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

2024-06-15 05:28

本文主要是介绍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

这篇关于02-MybatisPlus批量插入性能够吗?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

Python实现批量提取BLF文件时间戳

《Python实现批量提取BLF文件时间戳》BLF(BinaryLoggingFormat)作为Vector公司推出的CAN总线数据记录格式,被广泛用于存储车辆通信数据,本文将使用Python轻松提取... 目录一、为什么需要批量处理 BLF 文件二、核心代码解析:从文件遍历到数据导出1. 环境准备与依赖库

linux批量替换文件内容的实现方式

《linux批量替换文件内容的实现方式》本文总结了Linux中批量替换文件内容的几种方法,包括使用sed替换文件夹内所有文件、单个文件内容及逐行字符串,强调使用反引号和绝对路径,并分享个人经验供参考... 目录一、linux批量替换文件内容 二、替换文件内所有匹配的字符串 三、替换每一行中全部str1为st

基于Python开发一个图像水印批量添加工具

《基于Python开发一个图像水印批量添加工具》在当今数字化内容爆炸式增长的时代,图像版权保护已成为创作者和企业的核心需求,本方案将详细介绍一个基于PythonPIL库的工业级图像水印解决方案,有需要... 目录一、系统架构设计1.1 整体处理流程1.2 类结构设计(扩展版本)二、核心算法深入解析2.1 自

Python自动化批量重命名与整理文件系统

《Python自动化批量重命名与整理文件系统》这篇文章主要为大家详细介绍了如何使用Python实现一个强大的文件批量重命名与整理工具,帮助开发者自动化这一繁琐过程,有需要的小伙伴可以了解下... 目录简介环境准备项目功能概述代码详细解析1. 导入必要的库2. 配置参数设置3. 创建日志系统4. 安全文件名处

SpringBoot中六种批量更新Mysql的方式效率对比分析

《SpringBoot中六种批量更新Mysql的方式效率对比分析》文章比较了MySQL大数据量批量更新的多种方法,指出REPLACEINTO和ONDUPLICATEKEY效率最高但存在数据风险,MyB... 目录效率比较测试结构数据库初始化测试数据批量修改方案第一种 for第二种 case when第三种

MyBatisPlus如何优化千万级数据的CRUD

《MyBatisPlus如何优化千万级数据的CRUD》最近负责的一个项目,数据库表量级破千万,每次执行CRUD都像走钢丝,稍有不慎就引起数据库报警,本文就结合这个项目的实战经验,聊聊MyBatisPl... 目录背景一、MyBATis Plus 简介二、千万级数据的挑战三、优化 CRUD 的关键策略1. 查

利用Python脚本实现批量将图片转换为WebP格式

《利用Python脚本实现批量将图片转换为WebP格式》Python语言的简洁语法和库支持使其成为图像处理的理想选择,本文将介绍如何利用Python实现批量将图片转换为WebP格式的脚本,WebP作为... 目录简介1. python在图像处理中的应用2. WebP格式的原理和优势2.1 WebP格式与传统

MybatisPlus service接口功能介绍

《MybatisPlusservice接口功能介绍》:本文主要介绍MybatisPlusservice接口功能介绍,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友... 目录Service接口基本用法进阶用法总结:Lambda方法Service接口基本用法MyBATisP

Python中bisect_left 函数实现高效插入与有序列表管理

《Python中bisect_left函数实现高效插入与有序列表管理》Python的bisect_left函数通过二分查找高效定位有序列表插入位置,与bisect_right的区别在于处理重复元素时... 目录一、bisect_left 基本介绍1.1 函数定义1.2 核心功能二、bisect_left 与

Java如何从Redis中批量读取数据

《Java如何从Redis中批量读取数据》:本文主要介绍Java如何从Redis中批量读取数据的情况,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一.背景概述二.分析与实现三.发现问题与屡次改进3.1.QPS过高而且波动很大3.2.程序中断,抛异常3.3.内存消