做一些简单的大数据量插入工作, 采用JdbcTemplate
提供的batchUpdate方法犹如神助, 尤其在9000-10000条做一次分片插入, 效果更是好.
直接上代码
public static void executeBatchUpdate(JdbcTemplate jdbcTemplate, String updateSQL, List<Object[]> batchArgs) {
Connection con = null;
try {
con = jdbcTemplate.getDataSource().getConnection();
// 设置不自动提交
con.setAutoCommit(false);
// 如果要插入的参数超过9000条, 则开始进行分批次批量更新
int s = batchArgs.size() / 9000 + 1;
// 缓存待插入的参数列表
List<Object[]> batchArgsList;
for (int i = 1; i <= s; i++) {
if (i <= s - 1) {
batchArgsList = batchArgs.subList((i - 1) * 9000, i * 9000);
} else {
batchArgsList = batchArgs.subList((i - 1) * 9000, batchArgs.size());
}
// 执行批量更新
jdbcTemplate.batchUpdate(updateSQL, batchArgsList);
}
//手动提交
con.commit();
//还原自动提交
con.setAutoCommit(true);
} catch (Exception e) {
e.printStackTrace();
try {
//事务回滚
if (con != null) {
con.rollback();
con.setAutoCommit(true);
}
} catch (SQLException e1) {
e1.printStackTrace();
}
} finally {
try {
if (con != null) {
//关闭连接
con.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
使用方式
主要是搞SQL和对应的参数列表比较恶心一些, 但是估计这种场景使用的也不会很多, 大概就我这样写就好了:
@SneakyThrows
private void insertBillWuliao(List<BomWuliao> list) {
String sql = "insert into bom_month_bill_wuliao (inv_code,clz_name,num,unit_price,inv_name,unit,sub_clz_name) " +
"VALUES (?,?,?,?,?,?,?)";
List<Object[]> argsList = Lists.newArrayList();
if (CollectionUtils.isNotEmpty(list)) {
for (BomWuliao wuliao : list) {
argsList.add(new Object[]{wuliao.getInvCode(), wuliao.getClzName(), wuliao.getCount(),
wuliao.getUnitPrice(), wuliao.getInvName(), wuliao.getUnit(), wuliao.getSubClzName()});
}
BatchUpdateUtil.executeBatchUpdate(jdbcTemplate, sql, argsList);
}
}