当前位置: 首页 > news >正文

SpringBoot整合mybatisPlus实现批量插入并获取ID

背景:需要实现批量插入并且得到插入后的ID。

使用for循环进行insert这里就不说了,在海量数据下其性能是最慢的。数据量小的情况下,没什么区别。

【1】saveBatch(一万条数据总耗时:2478ms)

mybatisplus扩展包提供的:com.baomidou.mybatisplus.extension.service.IService#saveBatch(java.util.Collection<T>)

测试代码:

@Testpublic void testBatch1(){List<SysFile> list=new ArrayList<>();list.add(new SysFile().setFileName("fiel1"));list.add(new SysFile().setFileName("fiel2"));list.add(new SysFile().setFileName("fiel3"));list.add(new SysFile().setFileName("fiel4"));list.add(new SysFile().setFileName("fiel5"));list.add(new SysFile().setFileName("fiel6"));fileService.saveBatch(list);System.out.println(list);}

我们分析其实现原理如下:com.baomidou.mybatisplus.extension.service.impl.ServiceImpl#saveBatch

@Transactional(rollbackFor = Exception.class)
@Override
public boolean saveBatch(Collection<T> entityList, int batchSize) {String sqlStatement = sqlStatement(SqlMethod.INSERT_ONE);int size = entityList.size();executeBatch(sqlSession -> {int i = 1;for (T entity : entityList) {sqlSession.insert(sqlStatement, entity);if ((i % batchSize == 0) || i == size) {sqlSession.flushStatements();}i++;}});return true;
}

其实也就是一条条插入。

在这里插入图片描述

【2】集合方式foreach(一万条数据总耗时:474ms)

SysFileMapper 自定义方法batchSaveFiles

public interface SysFileMapper extends BaseMapper<SysFile> {int batchSaveFiles(List<SysFile> entityList);
}

xml实现

<insert id="batchSaveFiles">insert  into tb_sys_file (file_name) values<foreach collection="list" item="item" separator=",">(#{item.fileName})</foreach>
</insert>

测试代码:

@Test
public void testBatch2(){List<SysFile> list=new ArrayList<>();list.add(new SysFile().setFileName("fiel1"));list.add(new SysFile().setFileName("fiel2"));list.add(new SysFile().setFileName("fiel3"));list.add(new SysFile().setFileName("fiel4"));list.add(new SysFile().setFileName("fiel5"));list.add(new SysFile().setFileName("fiel6"));fileMapper.batchSaveFiles(list);System.out.println(list);
}

测试结果:
在这里插入图片描述
注意:这种方式得不到ID哦!

【3】MyBatis-Plus提供的InsertBatchSomeColumn方法(一万条数据总耗时:690ms)

这里mybatisplus版本是3.3.0。

编写MySqlInjector

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

注入到配置类

@EnableTransactionManagement
@MapperScan({"com.enodeb.mapper"})
@Configuration
public class MybatisPlusConfig {@Beanpublic MySqlInjector sqlInjector() {return new MySqlInjector();}
}    

SysFileMapper 自定义方法

public interface SysFileMapper extends BaseMapper<SysFile> {int insertBatchSomeColumn(List<SysFile> entityList);

测试代码:

@Test
public void testBatch3(){List<SysFile> list=new ArrayList<>();list.add(new SysFile().setFileName("fiel1"));list.add(new SysFile().setFileName("fiel2"));list.add(new SysFile().setFileName("fiel3"));list.add(new SysFile().setFileName("fiel4"));list.add(new SysFile().setFileName("fiel5"));list.add(new SysFile().setFileName("fiel6"));fileMapper.insertBatchSomeColumn(list);System.out.println(list);
}

测试结果

在这里插入图片描述
这里不仅实现了【2】的效果,还可以得到插入后的ID。

【4】假设一万条/十万条数据的情况下,执行时间是多少

策略一万条十万条
方式一2478ms20745ms
方式二474ms2904ms
方式三690ms8339ms

① 方式一

@Testpublic void testBatch1(){long start=System.currentTimeMillis();List<SysFile> list=new ArrayList<>();SysFile sysFile;for(int i=0;i<10000;i++){sysFile=new SysFile();sysFile.setFileName("file"+i);list.add(sysFile);}fileService.saveBatch(list);long end=System.currentTimeMillis();System.out.println("一万条数据总耗时:"+(end-start)+"ms");}

一万条数据总耗时:2478ms
十万条数据总耗时:20745ms

② 方式二

@Test
public void testBatch2(){long start=System.currentTimeMillis();List<SysFile> list=new ArrayList<>();SysFile sysFile;for(int i=0;i<10000;i++){sysFile=new SysFile();sysFile.setFileName("file"+i);list.add(sysFile);}fileMapper.batchSaveFiles(list);long end=System.currentTimeMillis();System.out.println("一万条数据总耗时:"+(end-start)+"ms");}

一万条数据总耗时:474ms
十万条数据总耗时:2904ms

③ 方式三

@Test
public void testBatch3(){long start=System.currentTimeMillis();List<SysFile> list=new ArrayList<>();SysFile sysFile;for(int i=0;i<10000;i++){sysFile=new SysFile();sysFile.setFileName("file"+i);list.add(sysFile);}fileMapper.insertBatchSomeColumn(list);long end=System.currentTimeMillis();System.out.println("一万条数据总耗时:"+(end-start)+"ms");
}

一万条数据总耗时:690ms
十万条数据总耗时:8339ms

【5】百万条数据的情况下进行优化

方式二、方式三都是拼接为一条SQL,也就说有多少直接全部一次性插入,这就可能会导致最后的 sql 拼接语句特别长,超出了mysql 的限制。

这是什么意思呢?以MySQL为例,我们是需要考虑 max_allowed_packet 这个属性配置大小。其决定了你最大可以单次发送包的大小,这里可以修改为64M也就是 67108864。

但是这个不是最优解,最优解应该是控制每次插入的数量,比如一万条插入一次。

    @Testpublic void testBatch4(){List<SysFile> list=new ArrayList<>();SysFile sysFile;for(int i=0;i<100000;i++){sysFile=new SysFile();sysFile.setFileName("file"+i);list.add(sysFile);}//设置每批次插入多少条数据int batchSize=10000;int count = (list.size() + batchSize - 1) / batchSize; // 计算总批次数量,确保最后一个批次也能处理//保存单批提交的数据集合List<SysFile> oneBatchList = new ArrayList<>(batchSize); // 预分配容量for (int i = 0; i < count; i++) {int startIndex = i * batchSize;int endIndex = Math.min(startIndex + batchSize, list.size());oneBatchList.addAll(list.subList(startIndex, endIndex));fileMapper.insertBatchSomeColumn(oneBatchList);oneBatchList.clear(); // 清空集合以备下次循环使用}}

【TIPS】

为了确保批量插入的高效性,还需要进行一些配置和优化。例如,在application.yml中配置数据库连接时,可以开启MySQL的批处理模式【rewriteBatchedStatements=true】:

spring:datasource:url: jdbc:mysql://127.0.0.1:3306/testBtach?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=trueusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver

此外还可以考虑使用jdbcTemplate.batchUpdate、Spring Batch来实现(这两种未测试)。

相关文章:

SpringBoot整合mybatisPlus实现批量插入并获取ID

背景&#xff1a;需要实现批量插入并且得到插入后的ID。 使用for循环进行insert这里就不说了&#xff0c;在海量数据下其性能是最慢的。数据量小的情况下&#xff0c;没什么区别。 【1】saveBatch(一万条数据总耗时&#xff1a;2478ms) mybatisplus扩展包提供的&#xff1a;…...

实战RAG第一天——llama_index向量索引,查询引擎,搜索知识库问答,全部代码,保姆级教学

一、llama_index简介 llama_index(以前称为 GPT Index)是一个用于构建、查询、索引大型文档和数据集的开源框架。它的核心功能是帮助开发者将大语言模型(LLM)与自己的数据集无缝集成,从而进行知识库的构建、查询等任务。llama_index 使用 Python 编写,并结合了多种大语言…...

大数据治理

大数据治理是指对大数据的管理和控制,以确保数据的质量、可用性、安全性和合规性。随着大数据技术的不断发展,企业和组织面临着越来越多的数据管理挑战,如数据质量问题、数据安全问题、数据合规问题等。大数据治理成为了企业和组织应对这些挑战的重要手段。 一、大数据治理…...

云计算作业

关闭防火墙 停用Linux 挂载 下载nginx程序 启动nginx程序 连接网卡配置文件并且修改 更改模式为静态手动&#xff0c;并且分别修改ip地址&#xff0c;网关地址&#xff0c;dns 激活 创建自定义文件 定义server模块 监听地址 设置目录 匹配 激活网址根目录 创建目录文…...

复制文件到U盘提示:对于目标文件系统,文件过大

查看U盘属性的文件系统是否为FAT32&#xff0c;需将其改为NTFS 方法一 Win R 输入cmd打开命令行&#xff0c;输入以下命令&#xff08;注&#xff1a;f为U盘盘符&#xff09; convert f: /fs:ntfs /x方法二 格式化U盘&#xff0c;右键点击U盘进行格式化&#xff0c;文件系…...

SpringBoot+Swagger2.7.0实现汉化(2.8.0不行)

场景 SpringBootSwagger2实现可视化API文档流程&#xff1a; SpringBootSwagger2实现可视化API文档流程_swagger 可视化端口-CSDN博客 上面SpringBoot中使用swagger的效果 上面使用的是swagger2.8.0,且在线API是英文的。现在要将其进行汉化。 汉化效果 实现 首先打开sprin…...

c++ 散列表

散列表&#xff08;Hash Table&#xff09;是一种高效的数据结构&#xff0c;广泛用于实现快速的键值对存储。 基本概念 散列表使用哈希函数将键映射到数组的索引。其主要优点在于平均情况下提供常数时间复杂度的查找、插入和删除操作。 哈希函数: 将键映射到一个固定大小的…...

Windows通过netsh控制安全中心防火墙和网络保护策略

Windows通过netsh控制安全中心防火墙和网络保护策略 1. 工具简介 【1】. Windows安全中心 【2】. netsh工具 netsh(Network Shell) 是一个Windows系统本身提供的功能强大的网络配置命令行工具。 2. 开启/关闭防火墙策略 在设置端口&#xff08;禁用/启用&#xff09;前&am…...

UML(Unified Modeling Language,统一建模语言)

UML&#xff08;Unified Modeling Language&#xff0c;统一建模语言&#xff09;是一种标准化的图形化语言&#xff0c;用于软件工程中的可视化建模。UML由Grady Booch、James Rumbaugh和Ivar Jacobson共同开发&#xff0c;他们各自的工作&#xff08;Booch方法、OMT方法和OOS…...

深⼊理解指针(2)

目录 1. 数组名的理解 2. 使⽤指针访问数组 3. ⼀维数组传参的本质 4. ⼆级指针 5. 指针数组 6. 指针数组模拟⼆维数组 1. 数组名的理解 我们在使⽤指针访问数组的内容时&#xff0c;有这样的代码&#xff1a; int arr[10] {1,2,3,4,5,6,7,8,9,10}; int *p &arr[…...

Ubuntu中MySQL远程登录设置

mysql单独放在一台Ubuntu服务器上&#xff0c;我远程连接不上。可能是安装的时候忘记设置远程登录了。事后补救措施如下&#xff1a; MySQL 绑定地址配置问题 MySQL 可能只绑定了 localhost&#xff0c;无法接受来自外部主机的连接。你需要检查 MySQL 的配置文件 /etc/mysql/…...

typescript 中封装一个 class 来解析接口响应数据

在TypeScript中&#xff0c;封装一个类来解析接口响应数据是一个常见的做法&#xff0c;它允许你将与接口响应相关的逻辑封装在一个可复用的单元中。下面是一个示例&#xff0c;展示了如何定义一个TypeScript类来解析一个假设的API接口响应数据。 首先&#xff0c;我们定义一个…...

[LeetCode] 21. 合并两个有序链表

题目描述&#xff1a; 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4]示例 2&#xff1a; 输入&#xff1a;l1 [], l2 […...

CTFHUB技能树之SQL——MySQL结构

开启靶场&#xff0c;打开链接&#xff1a; 先判断一下是哪种类型的SQL注入&#xff1a; 1 and 11# 正常回显 1 and 12# 回显错误&#xff0c;说明是整数型注入 判断一下字段数&#xff1a; 1 order by 2# 正常回显 1 order by 3# 回显错误&#xff0c;说明字段数是2列 知道…...

Git小知识:合理的分支命名约定

前言&#xff1a;创建新分支时&#xff0c;对 Git 分支进行合理的命名非常重要&#xff0c;应选择有描述性的名称&#xff0c;因为它可以帮助团队成员更好地理解分支的目的和内容&#xff0c;以便将来回顾时能立即明白分支的目的。以下是一些常见的分支命名约定&#xff1a; 功…...

Ubuntu如何显示pcl版本

终端输入&#xff1a; apt-cache show libpcl-dev可以看到&#xff0c;Ubuntu20.04&#xff0c;下载的pcl&#xff0c;应该都是1.10版本的...

wordcloud 字体报错

wordcloud 字体报错 词云库报错&#xff1a;Only supported for TrueType fonts字体文件问题pillow版本的问题wordcloud版本问题&#xff08;我的最终解决方案&#xff09; 词云库报错&#xff1a;Only supported for TrueType fonts 字体文件问题 解决方法 写绝对路径 &…...

使用Matplotlib绘制极轴散点图

散点图对于理解数据可视化中变量之间的相互作用至关重要。虽然散点图经常在笛卡尔坐标中创建&#xff0c;但我们也可以使用Matplotlib在极轴上创建散点图。有了这个功能&#xff0c;人们可以以创新的方式查看圆形或角形数据&#xff0c;例如周期性趋势或定向模式。在本文中&…...

Elasticsearch入门:增删改查详解与实用场景

引言 在我之前做社交架构设计的时候&#xff0c;我们有一项关键且必要的需求&#xff1a;需要存储并记录用户的所有聊天记录。这些记录不仅用于业务需求&#xff0c;也承担了风控审查的职责。因此&#xff0c;在架构设计中&#xff0c;我们需要考虑每天海量的聊天消息量&#…...

【AI论文精读6】SELF-RAG(23.10)附录

【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】 P1&#xff0c;P2&#xff0c;P3 附录 A SELF-RAG 细节 A.1 反思标记&#xff08;reflection tokens&#xff09; 反思标记的定义 下面我们提供了反思标记类型和输出标记的详细定义。前三个方面将在每个片段&#xf…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

三分算法与DeepSeek辅助证明是单峰函数

前置 单峰函数有唯一的最大值&#xff0c;最大值左侧的数值严格单调递增&#xff0c;最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值&#xff0c;最小值左侧的数值严格单调递减&#xff0c;最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事&#xff0c;必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后&#xff0c;我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集&#xff0c;就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...

02.运算符

目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&&#xff1a;逻辑与 ||&#xff1a;逻辑或 &#xff01;&#xff1a;逻辑非 短路求值 位运算符 按位与&&#xff1a; 按位或 | 按位取反~ …...