当前位置:   article > 正文

Mybatis与Jdbc批处理_sqlsessionfactory.opensession(executortype.batch,

sqlsessionfactory.opensession(executortype.batch, false);

Mysql数据库批量插入大量数据时经常会遇到插入速度过慢的场景;自己也知道批量插入比单条插入也会快很多,后面测试又发现代码也得也没有问题可是执行结果总是差强人意,我也在测试过程中遇到此问题,后面发现是由于URL中缺少了参数导致: rewriteBatchedStatements=true

此参数默认配置是false,需要手动在URL中配置成true进行开启;开启了配置之后,就可以正常使用批量插入了,下面直接上Mybaits和Jdbc批处理的代码

  1. try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false)) {
  2. // 获取Mapper,一定要重新获取,否则不会走批处理
  3. XxMapper mapper = sqlSession.getMapper(XxMapper.class);
  4. // 循环插入数据
  5. for (Info info: infos) {
  6. mapper.insert(info);
  7. }
  8. // 批量提交
  9. sqlSession.commit();
  10. }

Mybatis批处理一定要从会话中获取Mapper对象;创建会话的过程会创建执行器并将执行器封装到会话中;创建执行器过程可以参考下面代码

  1. public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
  2. executorType = executorType == null ? defaultExecutorType : executorType;
  3. executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
  4. Executor executor;
  5. // 根据执行类型创建执行器
  6. if (ExecutorType.BATCH == executorType) {
  7. executor = new BatchExecutor(this, transaction);
  8. } else if (ExecutorType.REUSE == executorType) {
  9. executor = new ReuseExecutor(this, transaction);
  10. } else {
  11. executor = new SimpleExecutor(this, transaction);
  12. }
  13. if (cacheEnabled) {
  14. executor = new CachingExecutor(executor);
  15. }
  16. executor = (Executor) interceptorChain.pluginAll(executor);
  17. return executor;
  18. }

会话创建完成后,从会话中获取到的Mapper对象,调用Mapper对象的方法,会由JDK最终代理到会话中的执行器进行执行,会话又会交由执行器执行;可以参考下面代码 

  1. @Override
  2. public int update(String statement, Object parameter) {
  3. try {
  4. dirty = true;
  5. MappedStatement ms = configuration.getMappedStatement(statement);
  6. // 执行器执行更新
  7. return executor.update(ms, wrapCollection(parameter));
  8. } catch (Exception e) {
  9. throw ExceptionFactory.wrapException("Error updating database. Cause: " + e, e);
  10. } finally {
  11. ErrorContext.instance().reset();
  12. }
  13. }

Jdbc批处理

  1. String sql = "INSERT INTO TABLE(ID, USER_ID, USER_NO) VALUES(?, ?, ?)";
  2. try (Connection connection = dataSource.getConnection();
  3. PreparedStatement stmt = connection.prepareStatement(sql)) {
  4. // 关闭事务的自动提交
  5. connection.setAutoCommit(false);
  6. for (Info info: infos) {
  7. stmt.setString(1, info.getId());
  8. stmt.setString(2, info.getUserId());
  9. stmt.setString(3, info.getUserNo());
  10. // 添加到批处理
  11. stmt.addBatch();
  12. }
  13. // 执行批处理
  14. stmt.executeBatch();
  15. // 事务提交
  16. connection.commit();
  17. } catch (Exception e) {
  18. e.printStackTrace();
  19. }

总结

如果批量插入的数据量在一万条以内的话,使用Mybatis的批处理与Jdbc的批处理在性能上区别不是很大;超过一万条的话还是建议使用Jdbc的批处理,性能上会好一些。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/158266
推荐阅读
相关标签
  

闽ICP备14008679号