同時將數據插入主表和子表中時。
需求:增加一個新部門,同時增加一個該部門的新員工。
思路1:先讓sequence產生nextval並記錄下來,再分別添加主表和子表
這種思路可行,但是需要多訪問一次數據庫,影響性能。
思路2:先插入新部門,然後返回該部門編號,再接着插入員工。
對比思路1有了性能上的優化。
返回該部門編號,就要用到getGeneratedKeys()方法,使用此方法獲取自增數據,性能良好,只需要一次交互。
要想使用該方法,在新建PreparedStatement解析SQL語句時,就要傳入第二個參數:
一個String數組,數組中記錄的是要GeneratedKeys記錄的字段名。
代碼實現:
public void testGeneratedKeys(){
//假設傳入了ename等數據(此處省略)
Connection con = null;
try{
con = DBUtil.getConnection();
con.setAutoCommit(false);
String sql = "INSERT INTO depts VALUES(depts_seq.nextval,?,?)";
PreparedStatement ps = con.prepareStatement(sql,new String[]{"deptno"}); //第二個參數是要獲取的字段名數組
ps.setString(1,"市場部");
ps.setString(2,"濟南");
ps.executeUpdate();
ResultSet rs = ps.getGeneratedKeys(); //此方法會返回一個結果集
rs.next(); //調用結果集
int deptno = rs.getInt(1); //通過列數獲取部門編號。
sql = "INSERT INTO emps VALUES(emps_seq.nextval,?,?,?,?,?,?,?)"; //標準流程增加員工。
ps.setString(1,ename);
ps.setString(2,job);
ps.setInt(3, mgr);
ps.setDate(4, hiredate);
ps.setDouble(5, sal);
ps.setDouble(6, com);
ps.setInt(7, deptno);
ps.executeUpdate();
con.commit();
}catch(SQLException e){
try{
con.rollback();
}catch(SQLException e1){
e1.printStackTrace();
throw new RuntimeException("回滾失敗",e1);
}
e.printStackTrace();
throw new RuntimeException("增加部門和員工失敗",e);
}finally{
DBUtil.close(con);
}
System.out.println("增加成功");
}