Spring+Mybatis批量提交(batchUpdate)
目录
提供两种批量提交方式,如有问题,欢迎网友随时指正
公共引入:SqlSessionFactory
@Autowired
private SqlSessionFactory sqlSessionFactory;
方式一:手动调动并提交
- 获取sqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
- 获取mapper并循环调用批量方法
LogMapper logMapper = sqlSession.getMapper(LogMapper.class);
for(Log log : logList){
logMapper.insert(log);
}
- 向数据库提交
sqlSession.commit();
- 提交失败,回滚事务
sqlSession.rollback();
以上为批量提交整体逻辑,以下为步骤说明:
(1)sqlSessionFactory为spring创建并管理,仅仅为了获取SqlSession
(2)此步骤调用的批量方法,例如logMapper.insert(log);,并未与数据库进行交互,只是将执行语句,执行参数等进行封装(详见org.apache.ibatis.executor.BatchExecutor#doUpdate方法),所以此处并不会出发数据库的校验,例如主键冲突,字段类型不对,字段长度不够等,也不会触发因网络等原因的连接异常。
执行核心代码:
Statement.addBatch();
(3)真正调用Statement.executeBatch()并关闭Statement(详见org.apache.ibatis.executor.BatchExecutor#doFlushStatements方法)。
执行核心代码:
Statement.executeBatch();
Statement.close();
(4)因为是批量操作,不确定是否需要调用回滚方法,还请网友大神解答。
其他:
1、因为是手动调用,所以可以不在外层方法设置@Transactional
2、此方式不依赖spring-batch包
方式二:自动调用并提交
- 构造MyBatisBatchItemWriter类
MyBatisBatchItemWriter<Log> writer = new MyBatisBatchItemWriterBuilder<Log>()
.statementId("com.XXX.log.mapper.LogMapper.insert")
.sqlSessionFactory(sqlSessionFactory)
.build();
- 获取参数集合并提交
// 从数据库或者其他地方获取批量操作结果集
List<log> logList = new ArrayList<Log>();
// 写入数据库
writer.write(logList);
以上为批量提交整体逻辑,以下为步骤说明:
(1)构造MyBatisBatchItemWriter对象
(2)此步骤调用约等于方式一的(2)+(3)步骤。
执行核心代码:
Statement.addBatch();
Statement.executeBatch();
Statement.close();
(3)因MyBatisBatchItemWriter对象未提供回滚操作,且内部并未执行回滚操作,所以应该不需要回滚。
其他:
1、外层方法必须设置@Transactional,否则会开启自动提交
2、依赖spring-batch包,MyBatisBatchItemWriter类实现ItemWriter接口,此接口在spring-batch包中
3、MyBatisBatchItemWriter类的statementId参数,只能硬编码到代码中,且只有在运行时才能知道是否正确,不太友好。