mybatis批量保存工具类实用

一、代码

import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.support.TransactionSynchronizationManager;import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.function.Consumer;/*** 批处理工具* @author hulei*/
public class BatchInsertUtil {private static final Logger logger = LoggerFactory.getLogger(BatchInsertUtil.class);private static final SqlSessionFactory sqlSessionFactory = SpringUtils.getBean(SqlSessionFactory.class);private static final int DEFAULT_BATCH_SIZE = 1000;private static int validateAndReturnBatchSize(Integer handleCount) {if (handleCount == null || handleCount <= 0) {throw new IllegalArgumentException("批处理条数必须大于0");}return handleCount;}public static <T, U> int batchUpdateOrInsert(List<T> data, Class<U> mapperClass, Consumer<Pair<T, U>> consumer) {int handleCount = validateAndReturnBatchSize(null);int processedCount = 0;SqlSession batchSqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);try {U mapper = batchSqlSession.getMapper(mapperClass);for (T element : data) {consumer.accept(new Pair<>(element, mapper));processedCount++;if (processedCount % handleCount == 0) {batchSqlSession.flushStatements();}}batchSqlSession.commit(!TransactionSynchronizationManager.isSynchronizationActive());} catch (Exception e) {logger.error("批处理发生异常:{}", e.getMessage(), e);batchSqlSession.rollback();throw new RuntimeException("批量处理失败", e);} finally {batchSqlSession.close();}return processedCount;}public static void jdbcTemplateBatchUpdateOrInsert(JdbcTemplate jdbcTemplate, String updateOrInsertSQL, List<Object[]> batchArgs) {int handleCount = validateAndReturnBatchSize(null);try (Connection con = jdbcTemplate.getDataSource().getConnection()) {con.setAutoCommit(false);int batchSize = batchArgs.size() / handleCount + 1;for (int i = 0; i < batchSize; i++) {int fromIndex = i * handleCount;int toIndex = Math.min(fromIndex + handleCount, batchArgs.size());List<Object[]> subList = batchArgs.subList(fromIndex, toIndex);jdbcTemplate.batchUpdate(updateOrInsertSQL, subList);}con.commit();} catch (Exception e) {logger.error("批量提交处理失败:{}", e.getMessage(), e);rollbackAndCloseConnection(con);throw new RuntimeException("批量提交处理失败", e);}}private static void rollbackAndCloseConnection(Connection con) {if (con != null) {try {con.rollback();con.setAutoCommit(true);} catch (SQLException e) {logger.error("无法回滚事务或重置自动提交状态", e);} finally {try {con.close();} catch (SQLException e) {logger.error("关闭数据库连接时发生错误", e);}}}}// 辅助类,用于传递实体和Mapper的组合private static class Pair<T, U> {private final T first;private final U second;public Pair(T first, U second) {this.first = first;this.second = second;}public T getFirst() {return first;}public U getSecond() {return second;}}
}

二、代码分析

这段代码是Java实现的一个批量处理工具类,主要包含了两个方法,分别用于MyBatis和JdbcTemplate的批量处理操作。这个类主要用于提高数据插入或更新的效率,通过批处理方式减少数据库交互次数,提高性能。

  1. 类定义和成员变量
    BATCH_SIZE: 定义了默认的批处理大小为1000。
    logger: 使用SLF4J的日志记录器,用于输出日志信息。
    sqlSessionFactory: 从Spring容器中获取的SqlSessionFactory,用于创建SqlSession实例。
  2. 方法定义
    2.1 batchUpdateOrInsert
    这是一个泛型方法,接收一个数据列表、一个Mapper类以及一个BiFunction。BiFunction用于处理每个数据项,通常是调用Mapper的方法执行插入或更新操作。方法内部通过SqlSession的批处理功能执行操作,每次handleCount个数据项后提交一次事务。
    2.2 jdbcTemplateBatchUpdateOrInsert
    这个方法使用JdbcTemplate进行批量插入操作,接收一个JdbcTemplate实例、SQL语句和一个包含参数的列表。方法内部通过循环处理参数列表,每次处理handleCount个元素,然后调用batchUpdate方法执行批处理。在非事务环境中,手动提交事务;在事务环境中,提交操作无效。
  3. 其他辅助方法
    validateAndReturnBatchSize: 检查handleCount是否大于0,如果不是,则抛出异常,否则返回handleCount。此方法用于确保批处理大小的有效性。
    rollbackAndCloseConnection: 用于回滚事务、恢复自动提交状态并关闭数据库连接,主要用于处理异常情况下的资源清理。
  4. 总体评价
    代码结构清晰,职责明确,分别实现了MyBatis和JdbcTemplate的批量处理功能。
    使用了批处理和分批提交,提高了数据库操作的效率。
    异常处理和资源管理比较完整,能够确保在异常情况下资源能够被正确释放。
    通过BiFunction和Consumer提供了灵活的处理逻辑,可以适应不同的业务需求。
    需要注意的是,这段代码假设了SpringUtils.getBean()方法可以从Spring上下文中获取SqlSessionFactory。如果实际项目中没有这样的工具类,需要使用Spring的依赖注入来获取SqlSessionFactory。

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

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

相关文章

正版Office-Word使用时却提示无网络连接请检查你的网络设置 然后重试

这是购买电脑时自带的已经安装好的word。看纸箱外壳有office标记&#xff0c;但是好像没有印系列号。 某天要使用。提示&#xff1a;无网络连接请检查你的网络设置。 经过网上高手的提示&#xff1a; 说要勾选勾选ssl3.0、TLS1.0、1.1、1.2。 我的截图 我电脑进去就缺1.2. …

PCIe总线-MPS MRRS RCB参数介绍(四)

1.概述 PCIe总线的存储器写请求、存储器读完成等TLP中含有数据负载&#xff0c;即Data Payload。Data Payload的长度和MPS&#xff08;Max Payload Size&#xff09;、MRRS&#xff08;Max Read Request Size&#xff09;和RCB&#xff08;Read Completion Boundary&#xff0…

PostgreSQL的pg_archivecleanup工具

PostgreSQL的pg_archivecleanup工具 pg_archivecleanup 是 PostgreSQL 中用于管理 WAL&#xff08;Write-Ahead Logging&#xff09;归档目录的工具。在使用基于归档的日志复制或持久化存储时&#xff0c;pg_archivecleanup 用来清理那些不再需要的归档日志文件&#xff0c;帮…

vue中的数据共享场景和数据共享方法总结

1、数据共享场景有哪些 页面之间共享数据&#xff1a; 不同页面之间需要共享数据时&#xff0c;可以通过 Vuex 状态管理库或路由参数等方式进行数据传递。例如&#xff0c;在路由参数中传递数据或将数据存储在 Vuex 中&#xff0c;在不同页面间进行数据交换。页面和组件之间共…

C++ 抽象机制

抽象机制 1. 虚函数 使用关键字virtual 声明的函数&#xff0c;意思是可能随后在其派生类中重新定义。 纯虚函数 在声明的末尾使用0 的函数&#xff0c;说明是纯虚函数。 抽象类 含有纯虚函数多的类称为抽象类(abstract class). 多态类型 如果一个类负责为其他一些类提供接…

unity入门——按钮点击了却无法调用函数

查阅了一番都没有解决问题&#xff0c;最后发现问题是由button的Onclick()事件绑定了代码脚本而不是游戏对象导致的。 如果Onclick()事件绑定的是代码脚本&#xff0c;则下拉框里没有函数&#xff0c;但是点击MonoScript后能手动填入函数名&#xff08;本以为这样就能实现调用…

State.initState() must be a void method without an `async` keyword错误解析

文章目录 报错问题报错的代码 错误原因解决方法解析 另外的方法 报错问题 State.initState() must be a void method without an async keyword如下图&#xff1a; 报错的代码 报错的代码如下&#xff1a; overridevoid initState() async{super.initState();await getConf…

openssl3.2 - exp - 使用默认的函数宏,在release版中也会引入__FILE__

文章目录 openssl3.2 - exp - 使用默认的函数宏&#xff0c;在release版中也会引入__FILE__概述笔记验证是否__FILE__在release版下也能用&#xff1f;将openssl编译成release版的&#xff0c;看看CRYPTO_free()是否只需要一个参数就行&#xff1f;将工程中的openssl相关的库换…

重定义大语言模型的记忆能力:对抗性压缩如何挑战现有测量法

DeepVisionary 每日深度学习前沿科技推送&顶会论文分享&#xff0c;与你一起了解前沿深度学习信息&#xff01; Rethinking LLM Memorization through the Lens of Adversarial Compression 引言&#xff1a;探索大型语言模型的记忆能力 在当今信息时代&#xff0c;大型…

Window(Qt/Vs)软件添加版本信息

Window&#xff08;Qt/Vs&#xff09;软件添加版本信息 文章目录 Window&#xff08;Qt/Vs&#xff09;软件添加版本信息VS添加版本信息添加资源文件添加版本定义头自动更新版本添加批处理脚本设置生成事件 Qt添加版本信息添加资源文件文件信息修改自动更新版本 CMake添加版本信…

React 中使用 TS

目录 1&#xff0c;搭建项目2&#xff0c;tsconfig.json 相关配置项1&#xff0c; lib2&#xff0c;module3&#xff0c;jsx 3&#xff0c;在 React 中使用 TS3.1&#xff0c;TS 可以解决的问题3,2&#xff0c;函数式组件3.3&#xff0c;类组件3.4&#xff0c;Props 的默认值方…

#ESP32S3R8N8建立工程(VSCODE)点亮LED

1.参考文档 【立创ESP32S3R8N8】IDF入门手册 - 飞书云文档 (feishu.cn)https://lceda001.feishu.cn/wiki/GOIlwwfbIi1SC3k8594cDeFVn8g 2.建立工程 3.运行效果 4.更改配置 5.插播 之前配置的环境是有问题的&#xff0c;就算有自动检测也要仔细检查&#xff0c;必须严格按照以…

VMware安装ubuntun虚拟机使用桥接模式无法上网问题解决

问题&#xff1a;最近准备使用VMware虚拟机搭建k8s集群服务&#xff0c;因为需要在同一个网段下&#xff0c;我使用桥接的方式&#xff0c;我发现主机在使用有线连接时虚拟机网络连接正常&#xff0c;但是使用无线网就显示连接不上网络。 解决方法 一、查看网络连接&#xff…

aardio封装库) 微软开源的js引擎(ChakraCore)

前言 做爬虫肯定少不了JavaScript引擎的使用&#xff0c;比如在Python中现在一般用pyexecjs2来执行JavaScript代码&#xff0c;另外还有一些其他执行JavaScript的库&#xff1a; https://github.com/eight04/node_vm2: rpc调用nodejs&#xff0c;需要安装nodehttps://github.…

Spring Data JPA数据批量插入、批量更新真的用对了吗

Spring Data JPA系列 1、SpringBoot集成JPA及基本使用 2、Spring Data JPA Criteria查询、部分字段查询 3、Spring Data JPA数据批量插入、批量更新真的用对了吗 前言 在前两篇文章已经介绍过&#xff0c;在使用Spring Data JPA时&#xff0c;DAO层的Respository通过继承J…

BigKey的危害

1.2.1、BigKey的危害 网络阻塞 对BigKey执行读请求时&#xff0c;少量的QPS就可能导致带宽使用率被占满&#xff0c;导致Redis实例&#xff0c;乃至所在物理机变慢 数据倾斜 BigKey所在的Redis实例内存使用率远超其他实例&#xff0c;无法使数据分片的内存资源达到均衡 Redis阻…

Python中动画显示与gif生成

1. 动画生成 主要使用的是 matplotlib.animation &#xff0c;具体示例如下&#xff1a; import matplotlib.pyplot as plt import matplotlib.animation as animation import numpy as np fig, ax plt.subplots() t np.linspace(0, 3, 40) g -9.81 v0 12 z g * t**2 / …

等保测评多选模拟题

21、以下哪些是黑客攻击手段&#xff1f;_____&#xff08;ABCDEFG&#xff09; A、暴力猜测 B、利用已知漏洞攻击 C、特洛伊木马 D、拒绝服务攻击 E、缓冲区溢出攻击 F、嗅探sniffer G、社会工程 22、计算机病毒的特点有_____。&#xff08; CD …

NFT是什么?有什么用途?

NFT&#xff0c;即非同质化代币&#xff08;Non-Fungible Token&#xff09;&#xff0c;是Web3技术的另一个重要应用。与比特币这样的同质化加密货币不同&#xff0c;NFT是独一无二的&#xff0c;每个代币都代表了一个独特的资产或物品。NFT通常基于区块链技术&#xff0c;如以…

新建stm32工程模板步骤

1.先使用keil新建一个project的基本代码 2.stm32启动文件添加 将stm32的启动文件&#xff0c;在原工程当中新建一个Start文件夹把相关的启动文件放到文件夹当中 然后还需要找到下面三个文件 stm32f10x.h是stm32的外设寄存器的声明和定义&#xff0c;后面那两个文件用于配置系…