02-MybatisPlus批量插入性能够吗?

1 前言

“不要用 mybatis-plus 的批量插入,它其实也是遍历插入,性能很差的”。真的吗?他们的立场如下:

  1. 遍历插入,反复创建。这是一个重量级操作,所以性能差。这里不用看源码也知道,因为这个和mybatis-plus没关系,而且我们现在使用SpringBoot,一般也用它的JDBC启动依赖。连接和连接池不是本文重点,总之这观点纯属无稽之谈,和不懂技术的领导说话一个德行
  2. 一条 insert 就一次网络IO,数量多了,这是个很可观且没必要的开销,所以性能差

2 show me源码!

对第2个观点,结合源码来看吧!

2.1 环境

① mybatis-plus 3.5.3.1

pom.xml:

② application.yml
Spring:# 使用默认的连接池库 datasource:url: "*****"username: "****"password: "****"

Service使用之处:

2.2 进入saveBatch

com.baomidou.mybatisplus.extension.service.IService#saveBatch(java.util.Collection)

会给我们这个批量操作开启事务(若是期望插入一条就成功一条,该批量方法就不适用);

且有限制提交数量,默认1000。

来到ServiceImpl实现类:

可见,MP批量插入是一条条插入的,但是这个一次次的遍历是真的发送给MySQL了吗?。只要记得这里有一个钩子,后面会回调回来执行。

/*** 获取mapperStatementId** @param sqlMethod 方法名* @return 命名id* @since 3.4.0*/
protected String getSqlStatement(SqlMethod sqlMethod) {return SqlHelper.getSqlStatement(mapperClass, sqlMethod);
}/*** 执行批量操作** @param list      数据集合* @param batchSize 批量大小* @param consumer  执行方法* @param <E>       泛型* @return 操作结果* @since 3.3.1*/
protected <E> boolean executeBatch(Collection<E> list, int batchSize, BiConsumer<SqlSession, E> consumer) {return SqlHelper.executeBatch(this.entityClass, this.log, list, batchSize, consumer);
}
3 SqlHelper#executeBatch(Class<?>, Log, Collection, int, BiConsumer<SqlSession,E>)
com.baomidou.mybatisplus.extension.toolkit.SqlHelper#executeBatch(java.lang.Class<?>, org.apache.ibatis.logging.Log, java.util.Collection, int, java.util.function.BiConsumer<org.apache.ibatis.session.SqlSession,E>)
/*** 执行批量操作** @param entityClass 实体类* @param log         日志对象* @param list        数据集合* @param batchSize   批次大小* @param consumer    consumer* @param <E>         T* @return 操作结果* @since 3.4.0*/
public static <E> boolean executeBatch(Class<?> entityClass, Log log, Collection<E> list, int batchSize, BiConsumer<SqlSession, E> consumer) {Assert.isFalse(batchSize < 1, "batchSize must not be less than one");return !CollectionUtils.isEmpty(list) && executeBatch(entityClass, log, sqlSession -> {int size = list.size();int idxLimit = Math.min(batchSize, size);int i = 1;for (E element : list) {consumer.accept(sqlSession, element);if (i == idxLimit) {sqlSession.flushStatements();idxLimit = Math.min(idxLimit + batchSize, size);}i++;}});
}

sqlSession从哪来的?看executeBatch。

4 SqlHelper#executeBatch(Class<?> entityClass, Log log, Consumer consumer)
com.baomidou.mybatisplus.extension.toolkit.SqlHelper#executeBatch(java.lang.Class<?>, org.apache.ibatis.logging.Log, java.util.function.Consumer<org.apache.ibatis.session.SqlSession>)
public static boolean executeBatch(Class<?> entityClass, Log log, Consumer<SqlSession> consumer) {SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);try {consumer.accept(sqlSession);//非事务情况下,强制commit。sqlSession.commit(!transaction);}
}

结合前面代码,这里是到了1000(默认1000,并且我批量保存的list超过1000),就会开启会话,将内存的SQL全部刷到MySQL,然后回去继续遍历。

总结

MP批量插入虽然是遍历插入,但不是一个insert就一次IO,而是打包了一次发送一批,所以性能没太大问题。但不是鼓励大家都用这批量插入,实际工作有更多要求,有时简单的批量插入没法满足。还是看实际情况决定。

扩展

如果使用mybatis-plus 3.4+ 版本,并且连接的是 MySQL 8.0 或更高版本的数据库,那么 mybatis-plus将会自动利用MySQL 8.0 的原生批量插入功能来执行批量插入操作。

具体实现的关键是在mybatis-plus的底层使用了mybatis-plus的批量新增方法时,mybatis-plus会将待插入的对象列表传递给底层的。

注意确保以下条件满足才能利用:

使用 MySQL 8.0 或更高版本的数据库

使用兼容 MySQL 8.0 的 JDBC 驱动程序(如 mysql-connector-java 版本 8.0 或更高)

使用 mybatis-plus 3.4+ 版本

参考:https://www.jianshu.com/p/a387879ccb97

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

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

相关文章

数据结构:手撕代码——顺序表

目录 1.线性表 2.顺序表 2.1顺序表的概念 2.2动态顺序表实现 2.2-1 动态顺序表实现思路 2.2-2 动态顺序表的初始化 2.2-3动态顺序表的插入 检查空间 尾插 头插 中间插入 2.2-4 动态顺序表的删除 尾删 头删 中间删除 2.2. 5 动态顺序表查找与打印、销毁 查找 …

mysql导入sql文件失败及解决措施

1.报错找不到表 1.1 原因 表格创建失败&#xff0c;编码问题mysql8相较于mysql5出现了新的编码集 1.2解决办法&#xff1a; 使用vscode打开sql文件ctrlh&#xff0c;批量替换&#xff0c;替换到你所安装mysql支持的编码集。 2.timestmp没有设置默认值 Error occured at:20…

一个公用的数据状态修改组件

灵感来自于一项重复的工作&#xff0c;下图中&#xff0c;这类禁用启用、审核通过不通过、设计成是什么状态否什么状态的场景很多。每一个都需要单独提供接口。重复工作还蛮大的。于是&#xff0c;基于该组件类捕获组件跳转写了这款通用接口。省时省力。 代码如下&#xff1a;…

Linux开机自启/etc/init.d和/etc/rc.d/rc.local

文章目录 /etc/init.d和/etc/rc.d/rc.local的区别/etc/init.dsystemd介绍 /etc/init.d和/etc/rc.d/rc.local的区别 目的不同&#xff1a; /etc/rc.d/rc.local&#xff1a;用于在系统启动后执行用户自定义命令&#xff0c;适合简单的启动任务。 /etc/init.d&#xff1a;用于管理…

实现一个vue js小算法 选择不同的时间段 不交叉

以上图片选择了时间段 现在需要判断 当前选择的时间段 不能够是 有交叉的所以现在需要循环判断 //判断时间段是否重叠交叉 export function areIntervalsNonOverlapping(intervals:any) {// 辅助函数&#xff1a;将时间字符串转换为从当天午夜开始计算的分钟数function conver…

信息系统架构风格-系统架构师(十

1、信息系统架构风格是描述特定应用领域中系统组织方式的惯用模式。架构风格定义了一个系统家族&#xff0c;即一个架构定义&#xff08;&#xff09;。 A一组设计原则 B一组模式 C一个词汇表和一组约束 D一组最佳实践 解析&#xff1a; 信息系统架构风格是描述某一特定 应…

汽车金属管检测新方法,分度盘高速视觉检测机检测效果如何?

汽车金属管是指在汽车制造和维修中广泛使用的金属管道&#xff0c;用于传输流体、气体或其他介质。汽车金属管在汽车中扮演着重要的角色&#xff0c;用于传输液体&#xff08;如燃油、冷却液、润滑油&#xff09;、气体&#xff08;如空气、排气&#xff09;、制动系统、液压系…

详解函数动态调用的作用——call

动态调用的作用 类似于其他语言的反射能够开发框架性代码 Call调用语法 (bool success, bytes data) <address>.call(bytes calldata)call是address的方法call返回值(bool success, bytes data)忽视返回值success&#xff0c;会造成严重问题 calldata的结构 call的…

183.二叉树:二叉搜索树中的众数(力扣)

代码解决 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* Tre…

Linux2(文件类型分类 基本命令2 重定向)

目录 一、文件类型分类 二、基本命令2 1. find 帮助查询 2. stat 查看文件的信息 3. wc 统计文本 4. 查看文本内容 4.1 cat 4.2 more 4.3 less 4.4 head 4.5 tail 5. cal 显示日历 6. date 显示时间 7. du 文件大小 8. ln 链接 软链接 硬链接 区别 9. histo…

碳中和研究院OLED透明屏2x2整机项目方案

一、项目背景 随着全球气候变化和环境问题的日益严重&#xff0c;碳中和成为各国政府和企业的重要议题。为了响应这一趋势&#xff0c;黑龙江碳中和研究院计划引入先进的OLED透明屏技术&#xff0c;以展示其研究成果和碳中和理念。本项目旨在为该研究院提供一套高质量的OLED透明…

关于Mysql 中 Row size too large (> 8126) 错误的解决和理解

提示&#xff1a;啰嗦一嘴 &#xff0c;数据库的任何操作和验证前&#xff0c;一定要记得先备份&#xff01;&#xff01;&#xff01;不会有错&#xff1b; 文章目录 问题发现一、问题导致的可能原因1、页大小2、行格式2.1 compact格式2.2 Redundant格式2.3 Dynamic格式2.4 Co…

vmmare虚拟机没有被分配ip地址问题;NAT模式下一直变化问题

打开任务管理器–>服务–>找到与VM和server相关的服务 发现NAT和DHCP服务被关闭了 尝试启动&#xff0c;报错 尝试一 虚拟网络编辑器点击还原默认设置 尝试二 可以了 ip变化 更改租用时长

性能测试常见的内存溢出问题: JVM 内存溢出如何调优?

针对java项目做性能测试的时候,很多同学都见过一个报错,就是OOM【Out Of MemoryError】;那出现这种报错就是项目发生了内存溢出的问题,这是比较严重的性能问题。所以,作为一个性能测试工程师,我们要能够分析JVM内存的问题以及理解其中的原理,才能更好的给JVM内存出现的性…

Wireless Network(百练,POJ)

题目链接: http://bailian.openjudge.cn/tm2019/F/ 2236 -- Wireless Network 题面描述: 思路: 这题开了10s&#xff0c;所以可以暴力点&#xff0c;每次修复一个点&#xff0c;就将该点相连的那些边建出来&#xff0c;总的时间复杂度为: O(nm)。关键在于如何判定两个点是否…

新能源汽车不安全?新能源汽车测试之方案篇——充电桩综合测试

背景 随着全球对气候变化和环境污染问题的日益加剧&#xff0c;新能源汽车作为一种环保、节能的交通工具备受关注。其发展背景主要源于对环境问题的关注以及对传统燃油汽车依赖的减少。新能源汽车的出现&#xff0c;带来了减少尾气排放、节能减排、保护环境等多方面的优点&…

【STM32】uc/OS-III多任务程序

目录 一、背景介绍二、UCOS-III简单介绍&#xff08;一&#xff09;源码&#xff08;二&#xff09;功能 三、实验&#xff08;一&#xff09;基于STM32CubeMX建立工程1、创建项目2、配置项目 &#xff08;二&#xff09;实现 四、总结五、参考 一、背景介绍 学习嵌入式实时操…

《精通ChatGPT:从入门到大师的Prompt指南》第7章:创意写作

第7章&#xff1a;创意写作 7.1 角色设定 角色设定是创意写作中最关键的环节之一。成功的角色设定能够让读者对故事产生共鸣&#xff0c;使故事更加生动有趣。角色不仅仅是情节发展的载体&#xff0c;更是读者情感的投射对象。因此&#xff0c;深入了解如何设定一个生动而有深…

【React】json-server

1.安装到开发环境 npm install json-server -D2.在根目录下下&#xff0c;新建db.json文件 {"list": [{"rpid": 3,"user": {"uid": "13258165","avatar": "http://toutiao.itheima.net/resources/images/9…

Go Module详解

文章目录 基本介绍相关环境变量Go Module的使用初始化项目&#xff08;go mod init&#xff09;管理依赖项&#xff08;go mod edit&#xff09;获取依赖项&#xff08;go mod download&#xff09;整理依赖项&#xff08;go mod tidy&#xff09;导入vendor目录&#xff08;go…