MyBatis-Plus批量保存的两种方法

  • 1.使用MybatisPlus自带的Iservice接口
    • 1.1入门使用
    • 1.2 原理方法
  • 2.使用MybatisPlus自定义新增
    • 2.1配置工作
    • 2.2 批量插入测试

springboot + mybatisPlus + mysql环境,批量保存的几种方法:

1.使用MybatisPlus自带的Iservice接口

BaseMapper中为提供批量插入接口,但是在com.baomidou.mybatisplus.extension.service.IService接口中提供了saveBatch批量插入方法。

1.1入门使用

  1. 新建一个接口,继承Iservice接口,泛型为被操作的实体类
package com.wsh.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.wsh.entity.Order;public interface BatchInsertService extends IService<Order> {}
  1. 创建一个方法,继承ServiceImpl,并且实现上述接口BatchInsertService
package com.wsh.service;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wsh.mapper.OrderMapper;
import com.wsh.entity.Order;
import org.springframework.stereotype.Service;@Service
public class BatchInsertServiceImpl extends ServiceImpl<OrderMapper,Order> implements BatchInsertService{}

其中,extends ServiceImpl<OrderMapper,Order>Order是被操作的实体类,Ordermapper是继承BaseMapper的自定义接口,如下:

package com.wsh.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wsh.entity.Order;// 使用mybatis-plus增强接口
public interface OrderMapper extends BaseMapper<Order> {}
  1. 批量保存测试
package com.wsh;import com.wsh.service.BatchInsertService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import com.wsh.entity.Order;
import javax.annotation.Resource;import java.util.ArrayList;
import java.util.Date;@SpringBootTest
public class TestBatchInsertService {@Resourceprivate BatchInsertService batchInsertService;@Testpublic void testBatchSave(){long start = System.currentTimeMillis();ArrayList<Order> orders = new ArrayList<>();for (int i = 0; i < 100000; i++) { //十万条数据Order order = new Order();order.setName("wsh"+i);order.setOrderDate(new Date());orders.add(order);}boolean b = batchInsertService.saveBatch(orders, 50);long end = System.currentTimeMillis();System.out.println("保存时间为:" + (end - start)); //73474System.out.println(b);}
}

测试结果为(部分展示):

==>  Preparing: INSERT INTO orders ( order_id, order_date, order_name ) VALUES ( ?, ?, ? )
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99951(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99952(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99953(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99954(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99955(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99956(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99957(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99958(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99959(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99960(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99961(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99962(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99963(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99964(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99965(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99966(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99967(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99968(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99969(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99970(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99971(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99972(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99973(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99974(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99975(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99976(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99977(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99978(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99979(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99980(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99981(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99982(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99983(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99984(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99985(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99986(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99987(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99988(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99989(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99990(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99991(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99992(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99993(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99994(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99995(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99996(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99997(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99998(String)
==> Parameters: 0(Integer), 2021-07-28 10:16:42.773(Timestamp), wsh99999(String)
保存时间为:73474
true

1.2 原理方法

Iservice接口中saveBatch方法:

  /*** 插入(批量)** @param entityList 实体对象集合* @param batchSize  插入批次数量*/boolean saveBatch(Collection<T> entityList, int batchSize);

ServiceImpl.java实现类中的saveBatch方法:

    /*** 批量插入** @param entityList ignore* @param batchSize ignore* @return ignore*/@Transactional(rollbackFor = Exception.class)@Overridepublic boolean saveBatch(Collection<T> entityList, int batchSize) {String sqlStatement = sqlStatement(SqlMethod.INSERT_ONE);try (SqlSession batchSqlSession = sqlSessionBatch()) {int i = 0;for (T anEntityList : entityList) {batchSqlSession.insert(sqlStatement, anEntityList);if (i >= 1 && i % batchSize == 0) {batchSqlSession.flushStatements();}i++;}batchSqlSession.flushStatements();}return true;}

sqlSessionBatch

    /*** 批量操作 SqlSession*/protected SqlSession sqlSessionBatch() {return SqlHelper.sqlSessionBatch(currentModelClass());}/*** 批量操作 SqlSession** @param clazz 实体类* @return SqlSession*/public static SqlSession sqlSessionBatch(Class<?> clazz) {// TODO 暂时让能用先,但日志会显示Closing non transactional SqlSession,因为这个并没有绑定.return GlobalConfigUtils.currentSessionFactory(clazz).openSession(ExecutorType.BATCH);}

注意:openSession(ExecutorType.BATCH),到这里就熟悉了。
插入十万条数据,时间为:73474

2.使用MybatisPlus自定义新增

2.1配置工作

注: 仅适用于MySQL

  1. 创建自定义数据方法注入类
package com.wsh.util;import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.extension.injector.methods.additional.InsertBatchSomeColumn;import java.util.List;public class EasySqlInjector extends DefaultSqlInjector {@Overridepublic List<AbstractMethod> getMethodList(Class<?> mapperClass) {// 防止父类方法不可用List<AbstractMethod> methodList = super.getMethodList(mapperClass);methodList.add(new InsertBatchSomeColumn());return methodList;}
}
  1. 在MybatisPlus配置文件MybatisPlusConfig加入自定义
package com.wsh.config;import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
import com.wsh.util.EasySqlInjector;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;@EnableTransactionManagement
@Configuration
@MapperScan("com.wsh.mapper")
public class MybatisPlusConfig {@Beanpublic EasySqlInjector easySqlInjector(){return new EasySqlInjector();}
}
  1. 扩展通用Mapper,支持数据批量插入,即:创建EasyBaseMapper接口继承BaseMapper
package com.wsh.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;import java.util.Collection;/*** @author suahng* @date 2021-07-21 20:47* @dec*/
public interface EasyBaseMapper<T> extends BaseMapper<T> {/*** 批量插入,仅使用批量插入* @param entityList 实体列表* @return 影响行数*/Integer insertBatchSomeColumn(Collection<T> entityList);
}
  1. 定义业务mapper接口,继承刚刚扩展的EasyBaseMapper
package com.wsh.mapper;
import com.wsh.entity.Order;
import org.springframework.stereotype.Repository;@Repository
public interface EasyMapper extends EasyBaseMapper<Order> {}
  1. 定义Service接口
package com.wsh.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.wsh.entity.Order;import java.util.Collection;public interface EasyService extends IService<Order> {/*** 批量插入,仅适用于 mysql* @param orderList* @return*/public Integer BatchSave(Collection<Order> orderList);
}
  1. 定义service接口的实现类
package com.wsh.service;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wsh.mapper.EasyBaseMapper;
import com.wsh.mapper.EasyMapper;
import com.wsh.entity.Order;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.util.Collection;@Service
public class EasyServiceImpl extends ServiceImpl<EasyMapper, Order> implements EasyService{@Overridepublic Integer BatchSave(Collection<Order> orderList) {return baseMapper.insertBatchSomeColumn(orderList);}
}

2.2 批量插入测试

package com.wsh;import com.wsh.entity.Order;
import com.wsh.service.EasyServiceImpl;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;@SpringBootTest
public class TestEasyService {@ResourceEasyServiceImpl easyService;@Testpublic void testBatchSave(){long start = System.currentTimeMillis();ArrayList<Order> orders = new ArrayList<>();for (int i = 0; i < 100000; i++) {Order order = new Order();order.setName("hcy"+i);order.setOrderDate(new Date());orders.add(order);}Integer b = easyService.BatchSave(orders);long end = System.currentTimeMillis();System.out.println("保存时间为:" + (end - start));//6348 6093 4320System.out.println(b);}
}

结果:

0(Integer), 2021-07-28 11:28:02.54(Timestamp), hcy16065(String), 0(Integer), 2021-07-28 11:28:02.54(Timestamp), hcy16066(String), 0(Integer), 2021-07-28 11:28:02.54(Timestamp), hcy16067(String), 0(Integer), 2021-07-28 11:28:02.54(Timestamp), hcy16068(String), 0(Integer), 2021-07-28 11:28:02.54(Timestamp), hcy16069(String), 0(Integer), 2021-07-28 11:28:02.54(Timestamp), hcy16070(String), 0(Inte<...>.556(Timestamp), hcy99998(String), 0(Integer), 2021-07-28 11:28:02.556(Timestamp), hcy99999(String)
<==    Updates: 100000
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1d50a7ca]
保存时间为:4223
100000

插入十万条数据,时间为:4223,比上一个方法减少了大约一半的时间。

MyBatis-Plus批量保存相关推荐

  1. mybatis plus 批量保存_mybatis源码分析

    原理图: Configuration解析: Configuration表示配置,该对象中维护了很多mybatis的配置参数: 大致可分为四部分:1.环境变量Environment 2.配置参数:3.缓 ...

  2. MyBatis批量保存数据

    一 .思路 1.首先创建一个实体类(TestEntity),对应批量保存的一条数据 2.Controller获取前台传递的数据(是Map列表,即代码中的paramMapList) 3.Service对 ...

  3. mybatis使用foreach进行批量保存

    mysql下批量保存 mysql支持语法 inset into table values(),(),().... 可以使用foreach进行遍历保存第一种方法<insert id="a ...

  4. Mybatis之批量更新操作

    2019独角兽企业重金招聘Python工程师标准>>> Mybatis之批量更新操作 更新单条记录 1 UPDATE course SET name = 'course1' WHER ...

  5. Jquery Easy UI Datagrid 上下移动批量保存数据

    DataGrid with 上下移动批量保存数据 通过前端变量保存修改数据集合,一次性提交后台执行 本想结合easyui 自带的$('#dg').datagrid('getChanges'); 方法来 ...

  6. word存为html图片有两个,如何批量保存Word图片?另存为Word多个图片的方法

    如何批量保存Word图片?很多用户在发送Word文档的时候都没有附上原图的习惯,导致接收方需要使用Word文档中的图片的时候还需要一个个另存为下载,当然,这是不明智的行为,如果你曾经历过这些,一定想知 ...

  7. 记录0.7.1版本的seata批量保存会报错的情况

    at io.seata.rm.datasource.AbstractPreparedStatementProxy.addBatch(AbstractPreparedStatementProxy.jav ...

  8. mysql基础----mybatis的批量插入(一)

    这里面记录一下使用mybatis处理mysql的批量插入的问题,测试有可能不准.只愿世间风景千般万般熙攘过后,字里行间,人我两忘,相对无言. mybatis的批量插入 我们的测试主体类是springb ...

  9. jpa批量保存,事务没提交_在事务外自动保存托管JPA实体

    jpa批量保存,事务没提交 Spring中的存储库和事务并存. Spring中的所有数据库访问都应在事务内运行,并且通常在某个地方使用@Transactional来强制执行此操作. 但是,这并不总是必 ...

  10. chrome浏览器开发者工具F12中某网站的sources下的源码如何批量保存?

    目录 chrome浏览器 开发者工具F12中某网站的sources下的源码如何批量保存 1. 常用保存Sources源码的两种方法 1.1单个文件 1.2 单个页面 2. 问题 3.解决方案 chro ...

最新文章

  1. MySQL 微秒慢查询补丁
  2. 【高并发】在高并发环境下该如何构建应用级缓存?
  3. 2017西安交大ACM小学期 刁钻的顾客[3进制+折半枚举]
  4. GDAL的一个BUG
  5. Apache mod_rewrite规则重写的标志一览
  6. X5内核视频之问答汇总
  7. 淘宝运营到底是做什么的?
  8. linux为360路由器刷机,[详细]360路由器刷openwrt、不死uboot、双系统 、wifi中继
  9. 求过指定点和指定方向的直线方程
  10. 什么是SKEY,怎样获取SKEY,SKEY的…
  11. 在技术招聘中,HR 如何识别候选人的“味道”?
  12. 天罡现世,Balong出海,华为这波5G动作666!
  13. 电脑C盘空间严重不足,教你5招!电脑内存瞬间多出10个G
  14. 2017年10月WEB前端开发实习生面试题总结
  15. 2018年 吉林大学 软件工程 967考研经验分享
  16. 别克英朗18T用车感受(一)
  17. EXCEL如何从地址中提取省、市、区
  18. 使用RANSAC的鲁棒TDOA Chan定位算法
  19. NVME协议-NVME概述
  20. python基础教程django 获取字段最大值,最新的记录操作

热门文章

  1. openstack安装文档
  2. opencv 4.5.5 imread 失败(报错)的处理方式
  3. python直方图解释_python直方图1 lin
  4. 使用mysql创建表格
  5. 互联网大佬生存法则 如何防守周鸿祎
  6. 适合计算机中职生见到打拼音的软件,中职计算机基础教案设计(18页)-原创力文档...
  7. 使用java 实现 word 转换成图片
  8. 测试转开发,我都经历了什么
  9. PHPStrom 快捷键
  10. Markdown:VS Code中预览markdown的快捷键和markdown的简单语法