MyBatis大批量插入的坑

文章讨论了在MyBatis中进行大量数据批量插入时遇到的性能问题,当表列数多且插入列表大时,操作耗时过长。原因是每次插入创建新的PreparedStatement对象,导致处理时间增加。MyBatis官方建议使用ExecutorType.BATCH执行器来优化,通过批处理减少网络IO并提高效率。此外,文中还提到了可采用MapReduce思想分批处理,但会增加数据库连接次数。
摘要由CSDN通过智能技术生成

MyBatis中的批量插入

  <insert id="batchInsert" >
    insert into table_name
    (aa, bb, cc, dd)
    values
    <foreach collection="list" item="item" separator=",">
xxxxxxxxx
    </foreach>
  </insert>

批量插入都会这样去写。他对应的SQL应该是

    insert into table_name
            (aa, bb, cc, dd) values(1,1,1,1),(2,2,2,2),(3,3,3,3)

原因就是:他可以将许多小操作变成一个大操作 最简单的就是减少网络IO.并且将检查索引更新和一致性检查放到最后。

问题

当表列数在20+ 插入的list 5000+的时候 整个过程很长 大概花了10分钟。这种情况应该是不被允许的。

原因

他的默认执行机器是Simple,也就是会为每一个语句创建一个新preparedStatement对象。对于这种foreach 没办法cache。然后由于value太长假设几千个 那他的PrepareStatement就会很长。然后存在占位符和参数的mapping这个也会很耗时。

查阅Mybatis官网和资料 发现大概是在20-50这个样子的values是性能比较高的

所以可以采用map reduce的思想。N个拆分成N/50次循环。但是也会带来个问题。就是会链接多次。

Mybatis官方建议

http://www.mybatis.org/mybatis-dynamic-sql/docs/insert.html

  try(SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
        SimpleTableMapper mapper = session.getMapper(SimpleTableMapper.class);
        List<SimpleTableRecord> records = getRecordsToInsert(); // not shown

        BatchInsert<SimpleTableRecord> batchInsert = insert(records)
                .into(simpleTable)
                .map(id).toProperty("id")
                .map(firstName).toProperty("firstName")
                .map(lastName).toProperty("lastName")
                .map(birthDate).toProperty("birthDate")
                .map(employed).toProperty("employed")
                .map(occupation).toProperty("occupation")
                .build()
                .render(RenderingStrategies.MYBATIS3);

        batchInsert.insertStatements().forEach(mapper::insert);

        session.commit();
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值