Spring JdbcTemplate的batch操作最后还是利用了JDBC提供的方法,Spring只是做了一下改造
JDBC的batch操作:
Spring做的工作就是把“变”与“不变”的部分抽离开来
sql语句就作为一个String类型的参数传递好了,而插入数据的写入提取为BatchPreparedStatementSetter接口:
JDBC的batch操作:
String sql = "INSERT INTO CUSTOMER " +
"(CUST_ID, NAME, AGE) VALUES (?, ?, ?)";
List<Customer> customers = getCustomersToInsert();
PreparedStatement pstmt = conn.prepareStatement(sql);
//默认情况下auto-commit=true,会认为一个statement就是一个transaction。批量操作中要执行多个statement,因此要设置为false
conn.setAutoCommit(false);
for (Customer customer : customers) {
pstmt.setLong(1, customer.getCustId());
pstmt.setString(2, customer.getName());
pstmt.setInt(3, customer.getAge() );
pstmt.addBatch();
}
int[] count = stmt.executeBatch();
conn.commit();
分析上述代码可知,实际应用中只有两部分是会变的:一是sql语句,二是要插入的数据
Spring做的工作就是把“变”与“不变”的部分抽离开来
sql语句就作为一个String类型的参数传递好了,而插入数据的写入提取为BatchPreparedStatementSetter接口:
class MyBatchPreparedStatementSetter implements BatchPreparedStatementSetter{
private List<Customer> customers;
public MyBatchPreparedStatementSetter(List<Customer> customers) {
this.customers = customers;
}
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
Customer customer = customers.get(i);
ps.setLong(1, customer.getCustId());
ps.setString(2, customer.getName());
ps.setInt(3, customer.getAge() );
}
@Override
public int getBatchSize() {
return customers.size();
}
}
BatchPreparedStatementSetter通常是以匿名内部类的形式出现:
String sql = ...;
List<Customer> customers = ...;
getJdbcTemplate().batchUpdate(sql, new BatchPreparedStatementSetter() {