/**
* 批量插入
* @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模式