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

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

作者 | 蔡柱梁

审校 | 重楼

前言

在很多公司,经常听到“不要用 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+ 版本

作者介绍

蔡柱梁,51CTO社区编辑,从事Java后端开发8年,做过传统项目广电BOSS系统,后投身互联网电商,负责过订单,TMS,中间件等。

责任编辑:华轩 来源: 51CTO
相关推荐

2021-09-27 07:56:41

MyBatis Plu数据库批量插入

2022-09-29 10:06:56

SQLMySQL服务端

2023-06-07 08:08:37

MybatisSpringBoot

2023-07-29 22:02:06

MyBatis数据库配置

2023-06-14 08:34:18

Mybatis死锁框架

2023-10-31 08:01:48

Mybatis参数jdbcurl​

2024-02-28 09:35:52

2012-11-08 16:16:41

2023-01-12 09:13:49

Mybatis数据库

2021-10-18 07:58:33

MyBatis Plu数据库批量插入

2021-10-09 06:59:36

技术MyBatis数据

2023-01-17 09:13:08

Mybatis后端框架

2022-07-15 13:58:46

工具MyBatissql

2023-12-30 20:04:51

MyBatis框架数据

2022-05-20 12:24:45

分库分表Java依赖

2022-09-23 09:44:17

MyBatisforeach

2022-08-24 08:07:11

MyBatisSQLMySQL

2023-12-13 12:20:36

SpringMySQL数据源

2010-09-03 11:47:38

SQL删除

2023-02-15 09:34:20

公共字段mybatis变量
点赞
收藏

51CTO技术栈公众号