/**
* 批量插入
* @param list
*/
public void batchinsert(List<UserDTO> list){
//Mybatis内置的ExecutorType改为BATCH
SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH);
//获取mapper对象
UserMapper mapper = session.getMapper(UserMapper.class);
//一次插入的条数
int size = 1000;
//获取插入集合数据总条数
int listSize = list.size();
//循环次数
int nums = listSize/size;
try {//分批循环插入数据
if(listSize<=size){
list.stream().forEach(user->{
mapper.insertUser(user);
});
}else {
List<UserDTO> subList = null;
for (int i =0;i<nums;i++){
subList = list.subList(0,size);
subList.stream().forEach(user->{
mapper.insertUser(user);
});
list.subList(0,size).clear();
}
if (list.size()>0){
list.stream().forEach(user->{
mapper.insertUser(user);
});
}
}
} catch (Exception e) {
log.error("批量插入失败:" + e.getMessage());
throw new RuntimeException("批量插入失败!");
}finally {
//sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH,true);
//openSession默认自动提交为true,可以设置为false,写下面两句,手动提交和关闭session,防止连接池耗尽
session.commit();
session.close();
}
}
MyBatis中Batch模式有如下两种限制:
1.不能在同一个事务中使用不同的模式,对于配置ExecutorType要特别注意
2.比较batch模式与foreach动态sql方式,就发现batch无法细粒化到mapper的方法级别
对比 foreach模式批量插入
INSERT INTO table
(Id,XX,XX,XX)
VALUES
<foreach collection="list" item="item" separator=",">
(xx,
xx,
xx,
xx)
</foreach>
mybatis对批量插入的数据量主要是mysql自身对接收数据量的大小限制,通过参数max_allowed_packet控制
查询当前大小
select @@max_allowed_packet;
修改为256M
SET GLOBAL max_allowed_packet=268435456;
注意: foreach模式批量插入模式与MyBatis中Batch模式对比差异
1.二者速度差异不大,for模式使用简单,Batch模式使用复杂
2.如果mysql自身对接收数据量有大小限制,建议使用Batch模式
文章讨论了MyBatis中使用ExecutorType.BATCH进行批量插入的实现方式,以及与foreach动态SQL批量插入的差异。批处理模式受限于同事务中不能混用不同执行器类型,且无法细化到mapper方法级别。相比于简单易用的for循环,批处理模式在处理大数据量时能避免MySQL接收数据量的限制,但配置更复杂。建议根据数据量和系统限制选择合适的方式。
3602

被折叠的 条评论
为什么被折叠?



