Mybatis批处理

本文介绍了Mybatis的批处理方法,包括单条SQL循环操作和XML中使用foreach批量操作,强调了XML批量操作在大数据量时的局限性。还详细讲解了Mybatis的BATCH模式,并提醒在使用时需要在MySQL连接URL中设置rewriteBatchedStatements=true以启用批处理,以提高INSERT/UPDATE/DELETE操作的性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Mybatis批处理

第一种 单条SQL循环操作

1.Mapper.xml
```
<insert id="insert" parameterType="com.example.mybatisbatch.entity.OrderDetail">
    insert into order_detail values
    (#{order.id},#{order.name},#{order.phone},#{order.expressNo},#{order.productName},#{order.createTime})
</insert>
```

2.单元测试
```
/**
 * 执行10000条
 * for循环单条数据
 * 耗时:共计:146秒
 * insert执行完成,共计:146秒
 * */
@Test
public void insertTest(){
    List<OrderDetail> grenate = this.grenate(10000);
    long start = System.currentTimeMillis();
    grenate.forEach(x->{
        orderDetailService.insert(x);
    });
    log.info("insert执行完成,共计:{}秒",(System.currentTimeMillis()-start)/1000);
}
```

第一种

第二种 XML中foreach批量操作

局限性:如果数据在200w XML是无法使用的,而且拼接容易出错,数据量小情况比第一种效率高。
1.Mapper
<insert id="insertBatch" parameterType="com.example.mybatisbatch.entity.OrderDetail">
        insert into order_detail values
        <foreach collection="list" separator="," item="order">
            (#{order.id},#{order.name},#{order.phone},#{order.expressNo},#{order.productName},#{order.createTime})
        </foreach>
    </insert>
2.单元测试
/**
     * XML foreach 执行10000
     * 耗时:共计:4秒
     * insertBatchTest执行完成,共计:4秒
     * */
    @Test
    public void insertBatchTest(){
        List<OrderDetail> grenate = this.grenate(10000);
        long start = System.currentTimeMillis();
        orderDetailService.insertBatch(grenate);
        log.info("insertBatchTest执行完成,共计:{}秒",(System.currentTimeMillis()-start)/1000);
    }

第二种

Mybatis BATCH 模式

⚠️:使用该模式必须rewriteBatchedStatements =true 在YML中Mysql链接URL中加入,原因是mysql jdbc默认无视executeBatch()语句,会把组成一组sql一句一条一条给Mysql执行,故性能下降。开启JDBC才会批量执行,对INSERT/UPDATE/DELETE有效。
1.复用第一种insert,使用满足1000条提交一次Commit 防止大数据内存溢出
```
@Override
public void mybatisBatch(List<OrderDetail> saveList) {
    //打开批处理
    SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
    OrderDetailMapper mapper = sqlSession.getMapper(OrderDetailMapper.class);

    //1000提交一次 大数据量情况下防止内存溢出
    for(int i=0;i<=saveList.size()-1;i++){
        mapper.insert(saveList.get(i));
        if(i%999 == 0){
            sqlSession.commit();
            sqlSession.clearCache();
        }
    }
    sqlSession.commit();
    sqlSession.clearCache();

}
```
2.单元测试性能
```
/**
 * 复用 mappr insert方法
 * 耗时:81秒 未开启rewriteBatchedStatements
 * 耗时:3秒   开启rewriteBatchedStatements*/
@Test
public void mybatisBatchTest(){
    List<OrderDetail> grenate = this.grenate(10000);
    long start = System.currentTimeMillis();
    orderDetailService.mybatisBatch(grenate);
    log.info("mybatisBatchTest执行完成,共计:{}秒",(System.currentTimeMillis()-start)/1000);
}
```

第三种

总结

单条insertXML中foreachMybatis BATCH操作条数
146S4S3S1W

补充

代码中功能生成数据 贴下
/**
     * 生成10000条数据
     * */
    public List<OrderDetail> grenate(int index){
        List<OrderDetail> result=new ArrayList<>();
        for(int i=1;i<=index;i++){
            result.add(OrderDetail.builder().createTime(LocalDateTime.now()).name("test"+i)
                    .phone(String.valueOf(i)).productName("商品"+i).expressNo(UUID.randomUUID().toString().replaceAll("-", "")).build());
        }
        return result;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值