mybatis-plus批量插入优化

news2024/9/22 3:49:17

mybatis-plus批量插入优化

    • 背景
    • 优化
    • 新的问题
    • 分批插入
    • springboot3整合mybaits-plus

背景

使用的mybatisplus的批量插入方法:saveBatch(),打印 sql 日志发现,底层还是一条条的 insert 语句,这显然是不行的

在这里插入图片描述

优化

之前就看到过网上都在说在jdbc的url路径上加上rewriteBatchedStatements=true 参数mysql底层才能开启真正的批量插入模式。但是我已经添加了

通过查阅相关文档后,发现mybatisPlus提供了sql注入器,我们可以自定义方法来满足业务的实际开发需求。

sql 注入器官网:https://baomidou.com/guides/sql-injector/

mybatis-plus -core 核心包提供了基本的增删查改注入器,在批量插入数据这里显然不够,所以可以看到在 mybaits-plus-extension 包下还额外提供了批量插入的可注入方法
在这里插入图片描述

  • AlwaysUpdateSomeColumnById: 根据Id更新每一个字段,全量更新不忽略null字段,解决mybatis-plus中updateById默认会自动忽略实体中null值字段不去更新的问题;
  • InsertBatchSomeColumn: 真实批量插入,通过单SQL的insert语句实现批量插入;
  • Upsert: 更新or插入,根据唯一约束判断是执行更新还是删除,相当于提供insert on duplicate key update支持。

我们只需要把这个方法添加进我们的sql注入器即可。
config包新增如下两个配置

public class MySqlInjector extends DefaultSqlInjector {
    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
        List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
        //更新时自动填充的字段,不用插入值
        methodList.add(new InsertBatchSomeColumn(i -> i.getFieldFill() != FieldFill.UPDATE));
        return methodList;
    }
}
@Configuration
public class MybatisPlusConfig {
    @Bean
    public MySqlInjector sqlInjector() {
        return new MySqlInjector();
    }
}

原先的 mapper 是这么写的

public interface UserMapper extends BaseMapper<User> {
}

我们新增了 InsertBatchSomeColumn 方法,需要重新定义一个 BaseMapper

public interface CommonMapper<T> extends BaseMapper<T> {
    /**
     * 真正的批量插入
     * @param entityList
     * @return
     */
    int insertBatchSomeColumn(List<T> entityList);
}
public interface UserMapper extends CommonMapper<User> {
}

优化后的接口就对了,sql 显示确实是 批量插入的语句
在这里插入图片描述

新的问题

上面虽然实现了真正意义上的sql层面的批量插入。

但是,到这里并没有结束,mybatisPlus官方提供的 insertBatchSomeColumn 方法不支持分批插入,**也就是有多少直接全部一次性插入,这就可能会导致最后的 sql 拼接语句特别长,超出了mysql 的限制,**于是我们还要实现一个类似于saveBatch 分批的批量插入方法。

分批插入

模仿原来的saveBatch方法:

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean saveBatch(Collection<User> entityList, int batchSize) {
        try {
            int size = entityList.size();
            int idxLimit = Math.min(batchSize, size);
            int i = 1;
            //保存单批提交的数据集合
            List<User> oneBatchList = new ArrayList<>();
            for (Iterator<User> it = entityList.iterator(); it.hasNext(); ++i) {
                User element = it.next();
                oneBatchList.add(element);
                if (i == idxLimit) {
                    baseMapper.insertBatchSomeColumn(oneBatchList);
                    //每次提交后需要清空集合数据
                    oneBatchList.clear();
                    idxLimit = Math.min(idxLimit + batchSize, size);
                }
            }
        } catch (Exception e) {
            log.error("saveBatch fail", e);
            return false;
        }
        return true;
    }
}

从下面结果可以看到,最终的 sql 分成了两个批次,这样的话 sql 语句就不会太长
在这里插入图片描述

springboot3整合mybaits-plus

这里就简单粘贴一下pom文件,注意 用mybatis-plus-spring-boot3-starter 这个依赖,不是用 mybatis-plus-spring-boot-starter ,不然报错

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.3.0</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example.springbootV3</groupId>
	<artifactId>springbootV3</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>springbootV3</name>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
			<version>3.1.3</version>
		</dependency>
		<dependency>
			<groupId>com.mysql</groupId>
			<artifactId>mysql-connector-j</artifactId>
		</dependency>
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
			<version>3.5.5</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>
spring.datasource.url=jdbc:mysql://192.168.133.128:3306/wxpay?useUnicode=true&characterEncoding=utf-8&rewriteBatchedStatements=true&useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
mybatis-plus.mapper-locations=classpath:/com/example/demo/**/*Mapper.xml

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1967163.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

怎么把C盘分成两个盘?让C盘分区更简单,赶快试试!

在日常使用电脑的过程中&#xff0c;有时我们可能希望将C盘分割成两个独立的分区&#xff0c;以便更好地管理文件和数据。这种操作需要谨慎进行&#xff0c;因为错误的分区操作可能导致数据丢失。那么&#xff0c;我们该怎么把C盘分成两个盘呢&#xff1f;下面&#xff0c;我将…

Telegraf 命令行指南:高效监控数据的秘诀

Telegraf 是一个轻量级的服务器监控代理&#xff0c;它支持从数百种数据源收集、处理和发送数据到各种存储库。它由 InfluxData 开发&#xff0c;常用于时间序列数据库 InfluxDB。Telegraf 的灵活性和强大的插件系统使其成为监控基础设施的理想选择。本文将为您提供一个 Telegr…

【解决方案】华普微基于收发芯片系列的LED智能灯控高效解决方案

一、方案概述 LED智能灯是一种集LED照明技术与智能控制技术于一体的现代照明产品。它采用高效节能的LED作为光源&#xff0c;相比传统灯具&#xff0c;具有更低的能耗、更长的使用寿命以及更环保的特性。 智能灯通过内置的智能芯片或连接外部智能设备&#xff08;如智能手机、…

vue2-级联选择器

级联选择器 一、市面上的级联选择器二、功能实现1、数据类型2、隐藏下拉框的方法3、html结构4、CSS代码5、各个方法代码 三、实现样式截图1、一级菜单1、鼠标放到一级菜单&#xff0c;就显示二级菜单2、鼠标点击一级菜单的时候 2、二级菜单1、鼠标放到二级菜单的时候&#xff0…

合规征程新里程碑:ATFX荣获香港SFC牌照,运营再上新台阶

全球知名金融科技品牌ATFX又传来好消息&#xff0c;继2023年6月获得阿联酋SCA第五类牌照后&#xff0c;ATFX全球合规运营策略再次取得重大成功。日前&#xff0c;ATFX宣布获得中国香港证券及期货事务监察委员会&#xff08;SFC&#xff09;颁发的第三类牌照&#xff08;号码&am…

GAMES104:06(下)游戏中地形大气和云的渲染2-学习笔记

文章目录 三、大气Atmosphere3.1 大气散射理论3.1.1 Analytic Atmosphere Appearance Modeling&#xff08;经验模型&#xff09;3.1.2 Participating Media参与介质3.1.3 辐射传递方程RTE(Radiative Transfer Equation)3.1.4 体积渲染公式VRE(Volume Rendering Equation) 3.2 …

比原生Transformer快的LMDeploy

创建conda环境 conda create lmdeploy conda activate lmdeploy 安装依赖包(注&#xff1a;下对应的版本要不然容易报错) pip install pytorch2.1.2 pip install lmdeploy[all]0.3.0 下载模型 通过Git协议下载模型。首先安装git-lfs组件 此处使用的root权限 curl -s ht…

YOLOv8改进 | 主干网络 | 简单而优雅且有效的VanillaNet 【华为诺亚方舟】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录 &#xff1a;《YOLOv8改进有效…

【C++核心篇】—— C++面向对象编程:封装相关语法使用和注意事项详解(全网最详细!!!)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、封装&#xff08;类&#xff09;1.封装的使用&#xff08;类和对象&#xff09;2. 对象的初始化和清理2.1 构造函数2.2 析构函数2.3 构造函数的分类及调用 …

海外仓代理模式,借鸡生蛋也能成为跨境新出路

国际物流是跨境电商生态圈同质化最严重跨境电商最开放的“地带”。唯独海外仓&#xff0c;算是国际物流行业唯一的一块“世外桃源”&#xff0c;但一个1000平米的小仓库&#xff0c;每年至少要花费100万的运转资金&#xff0c;无论是新企业还是成熟的企业&#xff0c;建立海外仓…

成都云飞浩容文化传媒有限公司怎么样?靠谱吗?

在数字经济的浪潮中&#xff0c;电商行业如同一艘巨轮&#xff0c;乘风破浪&#xff0c;不断前行。而在这片波澜壮阔的蓝海中&#xff0c;成都云飞浩容文化传媒有限公司犹如一颗璀璨的新星&#xff0c;以其专业的电商服务能力和前瞻性的市场洞察&#xff0c;为众多品牌搭建起通…

【Python机器学习】支持向量机——基于最大间隔分隔数据

有些人认为&#xff0c;SVM是最好的现成的分类器&#xff0c;这里说的“现成”指的是分类器不加修改即可直接使用。同时&#xff0c;这就意味着在数据上应用基本形式的SVM分类器就可以得到低错误率的结果。SVM能够对训练集之外的数据点做出很好的分类决策。 支持向量机&#x…

SAP ABAP SUBMIT 用法详解(看这一篇就够了)

文章目录 前言一、案例介绍/笔者需求二、B报表&#xff08;被SUBMIT的程序&#xff09;三、A报表&#xff08;用SUBMIT的程序&#xff09; a.SUBMIT B程序 b.AND RETURN 详解 c.CL_SALV_BS_RUNTIME_INFO 捕获ALV数据的方法 d.捕获…

使用STM32实现一个线性代数计算器

文章目录 背景挑战与困难如何整合编译&#xff1f;error: non-ASM statement in naked function is not supportederror: #pragma import is an ARM Compiler 5 extension, and is not supported by ARM Compiler 6error: redefinition of __FILE 改造demo中的cout改造delete运…

gdb调试 查找段错误

先设置 程序崩溃时的core文件产生 ulimit -c unlimited http://t.csdnimg.cn/BBGBQ 记得改完之后重启虚拟机。 core文件&#xff1a;当程序发生异常&#xff08;如段错误&#xff09;并退出时&#xff0c;操作系统可以选择生成一个 core 文件。这个文件包含了程序崩溃时刻…

【吊打面试官系列-Dubbo面试题】Dubbo 支持服务降级吗?

大家好&#xff0c;我是锋哥。今天分享关于 【Dubbo 支持服务降级吗&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; Dubbo 支持服务降级吗&#xff1f; 以通过 dubbo:reference 中设置 mock"return null"。mock 的值也可以修改为 true&#xff0c;然…

软测面试二十问(最新面试)

1.软件测试的流程是什么 参加需求评审会&#xff0c;解决需求疑问---写测试用例---对测试用例进行评审---评审后开始执行测试---提交bug---追踪bug---关闭bug---回归测试---交叉测试---编写测试报告---冒烟测试 2.什么是黑盒测试和白盒测试&#xff1f;它们有何区别 黑盒测试…

医院HIS搭建|HIS系统开发|HIS系统源码

在现代医疗管理中&#xff0c;医院信息系统&#xff08;HIS&#xff09;扮演着至关重要的角色。它是一个综合性的信息平台&#xff0c;旨在提高医院运营效率&#xff0c;优化患者护理&#xff0c;并确保医疗数据的准确性和安全性。以下是HIS系统包含的一些核心功能&#xff1a;…

抖音短视频矩阵管理系统:短视频运营的得力助手

1. 抖音短视频矩阵管理系统介绍 随着短视频行业的迅速发展&#xff0c;越来越多的企业和自媒体人开始关注短视频运营。抖音作为国内最受欢迎的短视频平台之一&#xff0c;拥有庞大的用户群体和丰富的内容资源。为了更好地管理和运营短视频&#xff0c;抖音短视频矩阵管理系统应…