文章目录
前言
批量插入的使用背景现实中应该会用到很多很多,但哪种方式效率才是最高的呢?以下内容仅代表个人观点。不喜勿喷
mybatis的批量新增有两种方式,mybatis的foreach标签,基于Session的Executor Type方式。
一、For each标签
这里我们只讲代码,并不具体搭建工程,不明白的小伙伴可以去我博客查看关于springboot的文章。
1、Mapper.xml
<insert id="batchSaveUser" parameterType="java.util.List">
insert into user(username,password,address,sex,age,imgPath) values
<foreach collection="list" item="user" separator=",">
(#{user.username},#{user.password},#{user.address},#{user.sex},#{user.age},#{user.imgPath})
</foreach>
</insert>
2、Mapper.interface
Integer batchSaveUser(List<User> list);
3、controller.class
long startSave1 = System.currentTimeMillis();
ArrayList<User> users = new ArrayList<>();
for (Integer i = 0; i < 1000000; i++) {
User user1 = new User();
user1.setUsername("李白"+i);
user1.setAge(i);
user1.setSex(i%2==0?"男":"女");
user1.setAddress("北京市朝阳区");
user1.setImgPath("/static/202307-15784861870c53.jpg");
users.add(user1);
}
long endSave1 = System.currentTimeMillis();
System.out.println("装载数据消耗:"+(endSave1-startSave1)/1000+"秒");
long startSave = System.currentTimeMillis();
userService.batchSaveUser(users);
long endSave = System.currentTimeMillis();
System.out.println("用时:"+(endSave-startSave)/1000+"秒");
return "用时:"+(endSave-startSave)/1000+"秒";
4、运行结果
可以看到消耗62秒,我运行了多次,平均都在一分钟左右。
二、基于Session的Executor Type方式
1.Mappler.xml
创建一条insert语句即可。
<insert id="saveUser" parameterType="com.chenan.springboot_mybatis.pojo.User">
insert into user(username,password,address,sex,age,imgPath) values(#{username},#{password},#{address},#{sex},#{age},#{imgPath})
</insert>
2、在controller调用
这里考虑到性能问题,分批次提交:
ArrayList<User> users = new ArrayList<>();
for (Integer i = 0; i < 1000000; i++) {
User user1 = new User();
user1.setUsername("李白"+i);
user1.setAge(i);
user1.setSex(i%2==0?"男":"女");
user1.setAddress("河北邯郸");
user1.setImgPath("/static/202307-15784861870c53.jpg");
users.add(user1);
}
System.out.println("开始插入数据");
long startSave = System.currentTimeMillis();
SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH);
UserDao mapper = sqlSession.getMapper(UserDao.class);
int t = 2000;
int k = 0;
if(users.size()%t == 0){
k = users.size()/t;
}else{
k = users.size() / t + 1;
}
int num = 0;
for (int j = 0; j < k; j++) {
for (Integer i = 0; i < t; i++) {
num = j*t+i;
User user1 = users.get(num);
mapper.saveUser(user1);
if(i==(t-1)){
sqlSession.commit();
}
}
}
sqlSession.close();
long endSave = System.currentTimeMillis();
System.out.println("用时:"+(endSave-startSave)/1000+"秒");
return "";
3、运行结果
可以看到,用了18分钟左右,可以说相差了接近20倍
总结
我看过很多博客,毫无疑问,内容大概都是第二种方式更快一些,所以我才来做的测试,但结果我很诧异,也许是我的使用方法有问题,但就目前来说,我更愿意用第一种方式,同时如果有小伙伴们知道原因出在哪里,欢迎沟通。