Mybatis批处理

Mybatis批处理

第一种 单条SQL循环操作

1.Mapper.xml
```

    insert into order_detail values
    (#{order.id},#{order.name},#{order.phone},#{order.expressNo},#{order.productName},#{order.createTime})

```

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

Mybatis批处理_第1张图片

第二种 XML中foreach批量操作

局限性:如果数据在200w XML是无法使用的,而且拼接容易出错,数据量小情况比第一种效率高。
1.Mapper

        insert into order_detail values
        
            (#{order.id},#{order.name},#{order.phone},#{order.expressNo},#{order.productName},#{order.createTime})
        
    
2.单元测试
/**
     * XML foreach 执行10000
     * 耗时:共计:4秒
     * insertBatchTest执行完成,共计:4秒
     * */
    @Test
    public void insertBatchTest(){
        List grenate = this.grenate(10000);
        long start = System.currentTimeMillis();
        orderDetailService.insertBatch(grenate);
        log.info("insertBatchTest执行完成,共计:{}秒",(System.currentTimeMillis()-start)/1000);
    }

Mybatis批处理_第2张图片

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 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 grenate = this.grenate(10000);
    long start = System.currentTimeMillis();
    orderDetailService.mybatisBatch(grenate);
    log.info("mybatisBatchTest执行完成,共计:{}秒",(System.currentTimeMillis()-start)/1000);
}
```

Mybatis批处理_第3张图片

总结

单条insert XML中foreach Mybatis BATCH 操作条数
146S 4S 3S 1W

补充

代码中功能生成数据 贴下
/**
     * 生成10000条数据
     * */
    public List grenate(int index){
        List 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;
    }

你可能感兴趣的:(Mybatis,java,mysql,mybatis)