1.BILL_SEQUENCE.nextval(序列)
String sql = "insert into bmis_bill (id,type,patientId,printUser,printTime,createTime,content)
values(BILL_SEQUENCE.nextval,?,?,?,?,?,?)";
int result = 0 ;
try {
result = jdbcTemplate.update(sql,bill.getType(),bill.getPatientId(),bill.getPrintUser(),bill.getPrintTime(),bill.getCreateTime(),bill.getContent());
}catch (Exception e) {
e.printStackTrace();
}
return result;
Connection conn=null;
PreparedStatement pstmt=null;
String sql="insert into mystu(id,name,age,gender) values(myseq.nextval,?,?,?)";
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
conn=DriverManager
.getConnection("jdbc:oracle:thin:@localhost:1521:orcl","scott","tiger");
pstmt=conn.prepareStatement(sql);
pstmt.setString(1,"tom");
pstmt.setInt(2,25);
pstmt.setString(3,"M");
pstmt.execute();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally{
//關閉資源
}
2. 連接數據庫操作
//公共代碼:得到數據庫連接
public Connection getConnection() throws Exception{
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:dbname", "username", "password");
return conn;
}
3.方法一,查兩次
//方法一
//先用select seq_t1.nextval as id from dual 取到新的sequence值。
//然後將最新的值通過變量傳遞給插入的語句:insert into t1(id) values(?)
//最後返回開始取到的sequence值。
//這種方法的優點代碼簡單直觀,使用的人也最多,缺點是需要兩次sql交互,性能不佳。
public int insertDataReturnKeyByGetNextVal() throws Exception {
Connection conn = getConnection();
String vsql = "select seq_t1.nextval as id from dual";
PreparedStatement pstmt =(PreparedStatement)conn.prepareStatement(vsql);
ResultSet rs=pstmt.executeQuery();
rs.next();
int id=rs.getInt(1);
rs.close();
pstmt.close();
vsql="insert into t1(id) values(?)";
pstmt =(PreparedStatement)conn.prepareStatement(vsql);
pstmt.setInt(1, id);
pstmt.executeUpdate();
System.out.print("id:"+id);
return id;
}
4.方法二,同一個Connection
//方法二
//先用insert into t1(id) values(seq_t1.nextval)插入數據。
//然後使用select seq_t1.currval as id from dual返回剛纔插入的記錄生成的sequence值。
//注:seq_t1.currval表示取出當前會話的最後生成的sequence值,由於是用會話隔離,只要保證兩個SQL使用同一個Connection即可,對於採用連接池應用需要將兩個SQL放在同一個事務內纔可保證併發安全。
//另外如果會話沒有生成過sequence值,使用seq_t1.currval語法會報錯。
//這種方法的優點可以在插入記錄後返回sequence,適合於數據插入業務邏輯不好改造的業務代碼,缺點是需要兩次sql交互,性能不佳,並且容易產生併發安全問題。
public int insertDataReturnKeyByGetCurrVal() throws Exception {
Connection conn = getConnection();
String vsql = "insert into t1(id) values(seq_t1.nextval)";
PreparedStatement pstmt =(PreparedStatement)conn.prepareStatement(vsql);
pstmt.executeUpdate();
pstmt.close();
vsql="select seq_t1.currval as id from dual";
pstmt =(PreparedStatement)conn.prepareStatement(vsql);
ResultSet rs=pstmt.executeQuery();
rs.next();
int id=rs.getInt(1);
rs.close();
pstmt.close();
System.out.print("id:"+id);
return id;
}
5.方法三,pl/sql語法,不直觀
//方法三
//採用pl/sql的returning into語法,可以用CallableStatement對象設置registerOutParameter取得輸出變量的值。
//這種方法的優點是隻要一次sql交互,性能較好,缺點是需要採用pl/sql語法,代碼不直觀,使用較少。
public int insertDataReturnKeyByPlsql() throws Exception {
Connection conn = getConnection();
String vsql = "begin insert into t1(id) values(seq_t1.nextval) returning id into :1;end;";
CallableStatement cstmt =(CallableStatement)conn.prepareCall ( vsql);
cstmt.registerOutParameter(1, Types.BIGINT);
cstmt.execute();
int id=cstmt.getInt(1);
System.out.print("id:"+id);
cstmt.close();
return id;
}
6.方法4,利用getGeneratedKeys
//方法四
//採用PreparedStatement的getGeneratedKeys方法
//conn.prepareStatement的第二個參數可以設置GeneratedKeys的字段名列表,變量類型是一個字符串數組
//注:對Oracle數據庫這裏不能像其它數據庫那樣用prepareStatement(vsql,Statement.RETURN_GENERATED_KEYS)方法,這種語法是用來取自增類型的數據。
//Oracle沒有自增類型,全部採用的是sequence實現,如果傳Statement.RETURN_GENERATED_KEYS則返回的是新插入記錄的ROWID,並不是我們相要的sequence值。
//這種方法的優點是性能良好,只要一次sql交互,實際上內部也是將sql轉換成oracle的returning into的語法,缺點是隻有Oracle10g才支持,使用較少。
public int insertDataReturnKeyByGeneratedKeys() throws Exception {
Connection conn = getConnection();
String vsql = "insert into t1(id) values(seq_t1.nextval)";
PreparedStatement pstmt =(PreparedStatement)conn.prepareStatement(vsql,new String[]{"ID"});
pstmt.executeUpdate();
ResultSet rs=pstmt.getGeneratedKeys();
rs.next();
int id=rs.getInt(1);
rs.close();
pstmt.close();
System.out.print("id:"+id);
return id;
}
7.方法5
//方法五
//和方法三類似,採用oracle特有的returning into語法,設置輸出參數,但是不同的地方是採用OraclePreparedStatement對象,因爲jdbc規範裏標準的PreparedStatement對象是不能設置輸出類型參數。
//最後用getReturnResultSet取到新插入的sequence值,
//這種方法的優點是性能最好,因爲只要一次sql交互,oracle9i也支持,缺點是隻能使用Oracle jdbc特有的OraclePreparedStatement對象。
public int insertDataReturnKeyByReturnInto() throws Exception {
Connection conn = getConnection();
String vsql = "insert into t1(id) values(seq_t1.nextval) returning id into :1";
OraclePreparedStatement pstmt =(OraclePreparedStatement)conn.prepareStatement(vsql);
pstmt.registerReturnParameter(1, Types.BIGINT);
pstmt.executeUpdate();
ResultSet rs=pstmt.getReturnResultSet();
rs.next();
int id=rs.getInt(1);
rs.close();
pstmt.close();
System.out.print("id:"+id);
return id;
}