同时将数据插入主表和子表中时。
需求:增加一个新部门,同时增加一个该部门的新员工。
思路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("增加成功");
}