由於數據的批量處理(比如往RDBMS插入幾萬條數據)非常耗資源,因此建議在所有場合能夠藉助於JDBC完成,而不要去採用Hibernate API。本文主要圍繞Spring內置的各類JDBC API抽象支持展開的。
1.1. JdbcTemplate內置的batchUpdate(final String[] sql)
這一方法適合於小批量數據的CUD(增、更新、刪除)操作,而且SQL類型不限。由於其內部使用了Statement語句,所以數據的操作效率一般。
1.2. JdbcTemplate內置的batchUpdate(String sql, final BatchPreparedStatementSetter pss)這一方法也僅僅適合於小批量數據的CUD(增、更新、刪除)操作,但始終是同一SQL(參數具有多樣性)。由於其內部使用了PreparedStatement語句,所以數據的操作效率還是不錯的。下面給出了操作示例:
final int[] no = new int[]{7369,7499,7521,7566,7654,7698};
jt.batchUpdate("update emp set sal = ? where empno = ?", //注:在oracle數據背景下,該方法的返回值失效(always -2)
new BatchPreparedStatementSetter(){
public void setValues(PreparedStatement ps, int i)throws SQLException {
ps.setInt(1, no[i]);
ps.setFloat(2, no[i]);
}
public int getBatchSize() {
return no.length;
}
});
1.3. BatchSqlUpdate
這一方法適合於各種批量數據的CUD(增、更新、刪除)操作,但始終是同一SQL(參數具有多樣性)。由於其內部使用了PreparedStatement語句,所以數據的操作效率還是不錯的。下面給出了操作示例:
DataSource ds = gbfa.getBean("dataSource");
final int[] no = new int[]{7369,7499,7521,7566,7654,7698};
BatchSqlUpdate bsu = new BatchSqlUpdate(ds, "update emp set sal=? where empno = ?");
bsu.setBatchSize(4);
bsu.setTypes(new int[]{Types.FLOAT, Types.INTEGER});
for(int i = 0; i < no.length; ++i){
log.info(bsu.update(new Object[]{no[i],no[i]})) ; ////注:在oracle數據背景下,該方法的返回值失效(always -1)
}
bsu.flush();
同JdbcTemplate內置的batchUpdate(String sql, final BatchPreparedStatementSetter pss)相比,BatchSqlUpdate會自動分批待批量處理的數據。比如,如果需要批量操作10萬條數據,則可以控制其batchSize,從而在時間(RDBMS可知性)和空間(內存)上達到平衡。
務必注意,在使用BatchSqlUpdate的最後,不要忘記手工調用其暴露的flush()方法。