mybatis-plus用insertBatchSomeColumn方法批量新增指定字段
作者:暗武逢天 发布时间:2022-03-02 10:20:58
前言
MyBatis-Plus 是基于 MyBatis 进行封装的一套优秀的持久层框架,它提供了丰富的便捷操作方法和强大的代码生成器,大大简化了 MyBatis 的使用。在 MyBatis-Plus 中,我们可以使用 insertBatchSomeColumn
方法来实现批量新增指定字段的操作。
mybatis-plus
的 IService
接口 默认提供 saveBatch
批量插入,也是唯一一个默认批量插入,在数据量不是很大的情况下可以直接使用,但这种是一条一条执行的效率上会有一定的瓶颈,在这里先看下saveBatch的执行情况
可以看到sql语句是一条一条执行的,插入多少条数据就相当于执行了多少次的插入sql, 点进saveBatch
方法,看看内部是怎么实现的
注意看,方法有一个事务注解,说明插入整批数据会作为一个事务进行,
默认1000条一次,怪不得执行时每隔1000条会处于一个准备执行状态,等待几秒后才会往下执行(这里等待的时间就是1000个单条的insert
语句执行的时间)
再往下点是一个saveBatch
接口,参数分别是插入的对象集合、插入批次数量也就是默认的1000
这里也有一个事务的注解,这是因为saveBatch
是一个重载方法,插入的时候也可以指定插入批次数量调用
继续往下进入executeBatch
这里就是真正执行的方法了,idxLimit会对比DEFAULT_BATCH_SIZE和集合长度两个数中的最小数,作为批量大小,也就是说当集合长度不够1000,那么执行的时候批量大小就是集合的长度,就执行一次。
for循环中的consumer:对应的类型是一个函数式接口,代表一个接受两个输入参数且不返回任何内容的操作符。意思是给定两个参数sqlSession、循环中当前element对象,执行一次传递过来的consumer匿名函数。也就是上边源码里的插入匿名函数。
当i == indLimit时:执行一次预插入,并重新计算idxLimit的值
if中idxLimit计算规则:当前idxLimit加batchSize(默认1000) 和 集合长度 取最小值,计算出来的结果肯定不会超过集合的长度,最后的批次时idxLimit等于集合的长度,将这个值作为下一次执行预插入的时间点。
sqlSession.flushStatements():当有处于事务中的时候,起到一种预插入的作用,执行了这行代码之后,要插入的数据会锁定数据库的一行记录,并把数据库默认返回的主键赋值给插入的对象,这样就可以把该对象的主键赋值给其他需要的对象中去了,这里不是事务提交啊。
最后方法执行完后@Transactional注解会默认提交事务,如果调用的方法上还有@Transactional注解,默认的事务传播类型是Propagation.REQUIRED,不会新开启事务,如果没有@Transactional注解才会新开起事务
下面我们使用真正的批量新增方法insertBatchSomeColumn,看看两者的区别
1. 什么是批量新增指定字段
批量新增指定字段是指在一次 SQL 语句中执行多条 INSERT 语句,但是只插入指定的字段。批量新增指定字段可以提高数据操作效率,减少数据库与应用程序之间的网络传输次数,减轻数据库服务器的压力,提高系统的并发性能。
2. MyBatis-Plus 批量新增指定字段的方法的使用
mybatis-plus提供了InsertBatchSomeColumn批量insert方法。通过SQL 自动注入器接口 ISqlInjector注入通用方法 SQL 语句 然后继承 BaseMapper 添加自定义方法,全局配置 sqlInjector 注入 MP 会自动将类所有方法注入到 mybatis 容器中。我们需要通过这种方式注入下。
/**
* 自定义Sql注入
*
*/
public class EasySqlInjector extends DefaultSqlInjector {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
// 注意:此SQL注入器继承了DefaultSqlInjector(默认注入器),调用了DefaultSqlInjector的getMethodList方法,保留了mybatis-plus的自带方法
List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
methodList.add(new InsertBatchSomeColumn(i -> i.getFieldFill() != FieldFill.UPDATE));
return methodList;
}
}
自定义EasyBaseMapper
/**
* @author 武天
* @date 2023/3/22 18:19
*/
public interface EasyBaseMapper<T> extends BaseMapper<T> {
/**
* 批量插入 仅适用于mysql
*
* @param entityList 实体列表
* @return 影响行数
*/
Integer insertBatchSomeColumn(Collection<T> entityList);
}
mapper继承的这里改为继承刚书写的自定义mapper
/**
*
*
* @author wutian
* @email ${email}
* @date 2022-10-03 22:12:06
*/
@Mapper
public interface BreakDownCluesDao extends EasyBaseMapper<ExcelBreakdownClues> {
}
调用测试
可以看到明显的区别,sql只执行了一条,后面都是入参逗号相隔的形式,耗时也有所优化,这是插入数量不是很多的情况,如果是上万条或者上千万条数据,这种形式的优越性就体现出来了
3. 批量新增指定字段的注意事项
在使用 MyBatis-Plus 进行批量新增指定字段时,需要注意以下几点:
每次新增的数据量不要过大,建议每批次新增的数据量控制在 1000 条以内。
要新增的指定字段不能为 null,需要手动设置默认值。
如果要新增的指定字段在实体类中有对应的字段值,会被忽略。
来源:https://blog.csdn.net/m0_51406695/article/details/129724446
猜你喜欢
- 以前用序列化都是一些方法需要才实现的,后来业务需求要深拷贝才去研究。参阅了别人博客得出一些总结。序列化是为了把Java对象转化为字节序列(字
- 本文研究的主要是Java中finally和return的关系,具体介绍和实例如下所示。finally 和 return 关系的总结1.try
- 序言小编在项目中有遇到使用 flutter 实现扫码枪接入的需求。为方便使用,小编把能力封装成 package 并发布。好记性不如烂笔头,下
- IntelliJ IDEA简称IDEA,是常用的java开发工具,相对eclipse在使用上入门较难,但在编写java代码方面比较eclip
- 本文的目的是把json串转成map键值对存储,而且只存储叶节点的数据比如json数据如下:{responseHeader:{status:0
- mapper文件使用in("str1","str2")mybatis的xxxMapper.xml文件
- 本文实例为大家分享了java文件上传下载的具体代码,供大家参考,具体内容如下文件上传@RequestMapping(value="
- 方法重写(Override)和方法重载(Overload)都是面向对象编程中,多态特性的不同体现,但二者本身并无关联,它们的区别犹如马德华之
- 1.线程池Executors的简单使用1)创建一个线程的线程池。 Executors.newSingleThreadExecutor();
- 题目要求思路一:DFS+序列化设计一种规则将所有子树序列化,保证不同子树的序列化字符串不同,相同子树的序列化串相同。用哈希表存所有的字符串,
- 在学会了java中io流的使用后,我们对于数组的排序,又多了一种使用方法。大家知道流处理数据的效率是比较理想的,那么在具体操作数组排序上,很
- Java调用接口获取json数据保存到数据库今天给大家带来一个调用接口,来获取数据解析后再保存到数据库中的业务,业务中的Mapper和实体类
- spring-mybatis获取mapper方式汇总项目背景:pojo下面有一个user实体类Dao包下面写了usermapper.xml
- springmvc 使用map接收参数开发过程中有时候我们并不知道前端都会传递哪些参数给到后端. 为方便扩展接口功能, 在请求参数不改变的情
- 一.WebSocket简单介绍WebSocket protocol 是HTML5一种新的协议。它实现了浏览器与服务器全双工通信(full-d
- 数据库里面表的字段中带有“”_“下划线,我们知道插件默认的是将这些带有下划线的字段默认的变成“优美的驼峰式”的。表是肯定不能动的,实体类的字
- 简单工厂简单工厂模式是属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。定义了一个创建对象的类,由
- webp格式图片webp格式图片是google推出的,相比jpg png有着巨大的优势,同样质量的图片webp格式的图片占用空间更小,在像电
- 在windows环境下,我们通常在IDE如VS的工程中开发C++项目,对于生成和使用静态库(*.lib)与动态库(*.dll)可能都已经比较
- 前言总是觉得对HashMap很熟悉,但最近连续被问到几个关于它的问题,才发现它其实并不简单。这里对关于它的一些问题做个总结,也希望能够大家一