Mybatis与Jdbc批处理

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

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

  • Mybatis批处理

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

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

  public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
    executorType = executorType == null ? defaultExecutorType : executorType;
    executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
    Executor executor;
    // 根据执行类型创建执行器
    if (ExecutorType.BATCH == executorType) {
      executor = new BatchExecutor(this, transaction);
    } else if (ExecutorType.REUSE == executorType) {
      executor = new ReuseExecutor(this, transaction);
    } else {
      executor = new SimpleExecutor(this, transaction);
    }
    if (cacheEnabled) {
      executor = new CachingExecutor(executor);
    }
    executor = (Executor) interceptorChain.pluginAll(executor);
    return executor;
  }

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

@Override
public int update(String statement, Object parameter) {
    try {
      dirty = true;
      MappedStatement ms = configuration.getMappedStatement(statement);
      // 执行器执行更新
      return executor.update(ms, wrapCollection(parameter));
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error updating database.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
}

Jdbc批处理

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

总结

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值