Mybatis-plus的批量插入真的不能用吗?

news/2025/3/12 12:40:27/

目录

🧨一、前言

🧨二、走进源码

1.进入 saveBatch 看下

2.往里ServiceImpl#saveBatch走

3.SqlHelper#executeBatch(Class, Log, Collection, int, BiConsumer),e>

4.SqlHelper#executeBatch(Class entityClass, Log log, Consumer consumer)

🧨三、总结

🧨四、扩展

一、前言

在很多公司,经常听到“不要用 mybatis-plus 的批量插入,它其实也是遍历插入,性能很差的”。真的是这样吗?我们不应该人云亦云,应该自己去探究下。

我们先针对这个观点分析下,总结出来他们的看法大概率是下面的其中一种:

  1. 遍历插入,反复创建。这是一个比较重的操作,所以性能很差。
    这里不用看源码也能知道,因为这个和mybatis-plus没关系,而且我们现在使用了SpringBoot,一般也用它的JDBC启动依赖。连接和连接池不是本章节的重点,就不展开讲了,总的来说这观点是不正确的。
  2. 一条 insert 就一次网络IO,数量多了,这是个很可观且没必要的开销,所以性能差。

二、走进源码

对这第二个观点,笔者结合源码给出自己的观点。给出笔者的一些相关配置(使用mybatis-plus的版本是3.5.3.1)。

pom.xml如下:

...
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version>
</dependency>
...

application.yml如下:

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

笔者的Service如下图:

1.进入 saveBatch 看下

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

发现里面会给我们这个批量操作开启了事务(如果是期望插入一条就成功一条的,这批量方法就不适用了)并且是有限制提交数量的,默认1000。

2.往里ServiceImpl#saveBatch走

com.baomidou.mybatisplus.extension.service.impl.ServiceImpl#saveBatch

看到了mybatis-plus 的批量插入是一条条插入的,但是这个一次次的遍历是真的发送给MySQL了吗?这里留一个疑问。我们只要记得这里有一个钩子,后面会回调回来执行

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>)

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>)

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

三、总结

到这里大家应该都清楚的知道了 mybatis-plus 的批量插入虽然是遍历插入,但是不是一个insert就一次IO,而是打包了一次发送一批的,所以性能不会有什么太大问题。不过,笔者这里不是鼓吹大家都用这个批量插入就好了,实际工作中会有更多要求,有时这个简单的批量插入是没法满足的。因此,笔者只是提倡可以根据自己工作实际情况决定,但是性能方面就不用太过担心,mybatis-plus 也有考虑的。

四、扩展

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

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

需要注意的是,要确保以下条件满足才能利用

  1. 使用
  2. 使用兼容
  3. 使用mybatis-plus 3.4+ 版本

用工具

成功的前端工程师很会善用工具,这些年低代码概念开始流行,像国外的 Mendix,国内的 JNPF,这种新型的开发方式,图形化的拖拉拽配置界面,并兼容了自定义的组件、代码扩展,确实在 B 端后台管理类网站建设中很大程度上的提升了效率。

开源地址:JNPF体验中心

代码量少,系统的稳定性和易调整性都会得到一定的保障。基于代码生成器,可一站式开发多端使用 Web、Android、IOS、微信小程序。代码自动生成后可以下载本地,进行二次开发,有效提高整体开发效率。同时,支持多种云环境部署、本地部署给予最大的安全保障,可以快速搭建适合自身应用场景的产品。


http://www.ppmy.cn/news/994138.html

相关文章

C++第三大特性:多态(1)

目录 一.多态的含义 1.普通调用&#xff1a; 2.多态调用 重写函数&#xff1a; 实现多态调用的三个条件&#xff1a;&#xff08;缺一不可&#xff09; 情况1&#xff1a;当只有父类中存在虚函数&#xff0c;两个子类都没有virtual形成的虚函数时&#xff0c;也能形成多态&…

数据库优化(数据库自身的优化,数据库表优化,程序操作优化)

数据库优化(数据库自身的优化,数据库表优化,程序操作优化) 一、增加次数据文件,设置文件自动增长(粗略数据分区) 1. 增加次数据文件 从SQL SERVER 2005开始,数据库不默认生成NDF数据文件,一般情况下有一个主数据文件(MDF)就够了,但是有些大型的数据库,由于信息很…

4-Linux组管理和权限管理

Linux组管理和权限管理 Linux组的基本介绍文件/目录的所有者组的创建文件/目录所在的组其它组改变用户所在的组权限的基本介绍第0-9位说明rwx权限详解rwx 修饰文件时rwx修饰目录时 修改权限第一种方式&#xff1a;、-、 变更权限第二种方式&#xff1a;通过数字变更权限 修改文…

配置IPv6 over IPv4手动隧道示例

组网需求 如图1所示&#xff0c;两台IPv6主机分别通过SwitchA和SwitchC与IPv4骨干网络连接&#xff0c;客户希望两台IPv6主机能通过IPv4骨干网互通。 图1 配置IPv6 over IPv4手动隧道组网图 配置思路 配置IPv6 over IPv4手动隧道的思路如下&#xff1a; 配置IPv4网络。配置接…

JavaSE类和对象(2)(重点:封装、包、static静态变量和方法)

目录 一、封装 1.封装&#xff1a;从语法来看&#xff0c;就是被private修饰的成员变量或者成员方法。只能在当前类当中使用。 2.快捷键&#xff0c;自动生成set或者get方法 3.限定访问修饰符&#xff08;private、 protected、public&#xff09; public&#xff1a;可以理…

Spring框架中的Bean的各种加载方式

大家好&#xff0c;这里向大家主要介绍Spring框架以及SpringBoot框架中的Bean的各种加载方式&#xff0c;有时候我们的学习&#xff0c;就是单纯为了工作效率而作为工具使用&#xff0c;于是乎&#xff0c;往往忽略了其最重要的一点&#xff0c;那就是底层原理&#xff01;所以…

Java:Java程序通过执行系统命令调用Python脚本

本文实现功能&#xff1a;Java程序调用Python脚本 Python脚本 import sysdef add(x, y):return x yif __name__ "__main__":print(add(int(sys.argv[1]), int(sys.argv[2])))直接执行 $ python math.py 1 2 3Java程序调用Python脚本 package io.github.mouday.…

133. 克隆图

给你无向 连通 图中一个节点的引用&#xff0c;请你返回该图的 深拷贝&#xff08;克隆&#xff09;。 图中的每个节点都包含它的值 val&#xff08;int&#xff09; 和其邻居的列表&#xff08;list[Node]&#xff09;。 class Node { public int val; public List&…