当前位置: 首页 > news >正文

SqlHelper自定义的Sql工具类

1. 简单使用

boolean batchRes = SqlHelper.exeBatch(sqlSessionFactory, updateList, OrderItemMapper.class, (orderItemMapper, orderItem) -> {orderItemMapper.updateByExampleSelective(orderItem);
});

实现类需要先引入 SqlSessionFactory,直接通过 @Autowired 即可,itemUpdateList 是传入的数据集合,OrderItemMapper 为指定的 Mapper 类型,后面的箭头函数会给一个指定 Mapper 的真实类,然后可以直接调用 Mapper 的方法。最后返回的 batchRes 为是否执行成功的结果,true 为成功,false 失败。

注意: 箭头函数中的 Mapper 使用的是 批处理SqlSession,其用于自定义数据批量提交,与 Autowired 自动引入的 Mapper 不同,所以不允许在箭头函数中使用引入的 Mapper 来执行数据 更新 操作。

2. 自定义批次

boolean batchRes = SqlHelper.exeBatch(sqlSessionFactory, updateList, 2000, OrderItemMapper.class, (orderItemMapper, orderItem) -> {orderItemMapper.updateByExampleSelective(orderItem);
});

在数据集合参数后面传入 int 数值,可以自定义批次大小,按需要修改,默认是 1000,此值需要根据 数据库的连接超时时间数据包大小限制服务器性能 等诸多因素进行调整。

3. SqlSession 回调

boolean batchRes = SqlHelper.exeBatch(sqlSessionFactory, updateList, (sqlSession, orderItem) -> {OrderItemMapper mapper = sqlSession.getMapper(OrderItemMapper.class);mapper.updateByExampleSelective(orderItem);// 下面的一般不执行,这里仅做演示,exeBatch 会自动执行 commit 操作sqlSession.commit();
});

通过 SqlSession 回调,可以在箭头函数中获取到批处理 SqlSession,用于自定义一些 commit、rollback 等操作。同样也支持自定义批次大小。

4. 自定义循环

可以使用内置的循环方法

boolean batchRes = SqlHelper.exeBatch(sqlSessionFactory, sqlSession -> {SqlHelper.batchForeach(sqlSession, updateList, OrderItemMapper.class, (orderItemMapper, orderItem) -> {orderItemMapper.updateByExampleSelective(orderItem);});
});

或者自定义循环

boolean batchRes = SqlHelper.exeBatch(sqlSessionFactory, sqlSession -> {int batchSize = 1000;int size = updateList.size();int batchLimit = Math.min(batchSize, size);int i = 1;for (Iterator<OrderItem> iterator = updateList.iterator(); iterator.hasNext(); ++i) {OrderItem next = iterator.next();OrderItemMapper sqlSessionMapper = sqlSession.getMapper(OrderItemMapper.class);sqlSessionMapper.updateByExampleSelective(next);if (i == batchLimit) {// 超过批次大小提交一次sqlSession.flushStatements();// 计算新的最大值batchLimit = Math.min(batchLimit + batchSize, size);}}
});

4. 源码

import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;import java.util.Collection;
import java.util.Iterator;
import java.util.function.BiConsumer;
import java.util.function.Consumer;/*** Sql工具类* <p>* 见 README_SQL_HELPER.md 文档说明** @author Jalon* @since 2025/9/22 11:54**/
public class SqlHelper {/*** 默认批次大小*/public static final Integer DEFAULT_BATCH_SIZE = 1000;/*** 执行批量操作** @param sqlSessionFactory SqlSessionFactory* @param list              数据集合* @param operation         批量操作* @param <T>               数据集合类* @return 是否执行成功*/public static <T> boolean exeBatch(SqlSessionFactory sqlSessionFactory, Collection<T> list, BiConsumer<SqlSession, T> operation) {return SqlHelper.exeBatch(sqlSessionFactory, list, DEFAULT_BATCH_SIZE, operation);}/*** 执行批量操作** @param sqlSessionFactory SqlSessionFactory* @param list              数据集合* @param mapperClass       Mapper类* @param operation         批量操作* @param <T>               数据集合类* @param <M>               Mapper类* @return 是否执行成功*/public static <T, M> boolean exeBatch(SqlSessionFactory sqlSessionFactory, Collection<T> list, Class<M> mapperClass, BiConsumer<M, T> operation) {return SqlHelper.exeBatch(sqlSessionFactory, list, DEFAULT_BATCH_SIZE, mapperClass, operation);}/*** 执行批量操作** @param sqlSessionFactory SqlSessionFactory* @param list              数据集合* @param batchSize         批次大小* @param operation         批量操作* @param <T>               数据集合类* @return 是否执行成功*/public static <T> boolean exeBatch(SqlSessionFactory sqlSessionFactory, Collection<T> list, int batchSize, BiConsumer<SqlSession, T> operation) {return SqlHelper.exeBatch(sqlSessionFactory, list, batchSize, SqlSession.class, operation);}/*** 执行批量操作** @param sqlSessionFactory SqlSessionFactory* @param list              数据集合* @param batchSize         批次大小* @param mapperClass       Mapper类* @param operation         批量操作* @param <T>               数据集合类* @param <M>               Mapper类* @return 是否执行成功*/public static <T, M> boolean exeBatch(SqlSessionFactory sqlSessionFactory, Collection<T> list, int batchSize, Class<M> mapperClass, BiConsumer<M, T> operation) {if (list == null || list.isEmpty()) {return false;}return SqlHelper.exeBatch(sqlSessionFactory, sqlSession -> {SqlHelper.batchForeach(sqlSession, list, batchSize, mapperClass, operation);});}/*** 执行批量操作** @param sqlSessionFactory SqlSessionFactory* @param operation         批量操作* @return 是否执行成功*/public static boolean exeBatch(SqlSessionFactory sqlSessionFactory, Consumer<SqlSession> operation) {// 参考MybatisPlusSqlSessionHolder sqlSessionHolder = (SqlSessionHolder) TransactionSynchronizationManager.getResource(sqlSessionFactory);boolean transaction = TransactionSynchronizationManager.isSynchronizationActive();if (sqlSessionHolder != null) {SqlSession sqlSession = sqlSessionHolder.getSqlSession();//原生无法支持执行器切换,当存在批量操作时,会嵌套两个session的,优先commit上一个session//按道理来说,这里的值应该一直为false。sqlSession.commit(!transaction);}// end 参考MybatisPlusSqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);if (!transaction) {
//            log.warn("SqlSession [" + sqlSession + "] Transaction not enabled");}try {operation.accept(sqlSession);// 非事务情况下,强制commit。sqlSession.commit(!transaction);return true;} catch (Throwable t) {sqlSession.rollback();throw t;} finally {sqlSession.close();}}/*** 批量循环操作** @param sqlSession SqlSession* @param list       数据集合* @param operation  批量操作* @param <T>        数据集合类型*/public static <T> void batchForeach(SqlSession sqlSession, Collection<T> list, BiConsumer<SqlSession, T> operation) {SqlHelper.batchForeach(sqlSession, list, SqlSession.class, operation);}/*** 批量循环操作** @param sqlSession SqlSession* @param list       数据集合* @param batchSize  批次大小* @param operation  批量操作* @param <T>        数据集合类型*/public static <T> void batchForeach(SqlSession sqlSession, Collection<T> list, int batchSize, BiConsumer<SqlSession, T> operation) {SqlHelper.batchForeach(sqlSession, list, batchSize, SqlSession.class, operation);}/*** 批量循环操作** @param sqlSession  SqlSession* @param list        数据集合* @param mapperClass Mapper类* @param operation   批量操作* @param <T>         数据集合类型*/public static <T, M> void batchForeach(SqlSession sqlSession, Collection<T> list, Class<M> mapperClass, BiConsumer<M, T> operation) {SqlHelper.batchForeach(sqlSession, list, DEFAULT_BATCH_SIZE, mapperClass, operation);}/*** 批量循环操作** @param sqlSession  SqlSession* @param list        数据集合* @param batchSize   批次大小* @param mapperClass Mapper类* @param operation   批量操作* @param <T>         数据集合类* @param <M>         Mapper类*/public static <T, M> void batchForeach(SqlSession sqlSession, Collection<T> list, int batchSize, Class<M> mapperClass, BiConsumer<M, T> operation) {if (batchSize < 1) {throw new IllegalArgumentException("batchSize must be greater than 0");}int size = list.size();int batchLimit = Math.min(batchSize, size);M mapper = null;if (SqlSession.class.equals(mapperClass)) {mapper = (M) sqlSession;} else {mapper = sqlSession.getMapper(mapperClass);}if (mapper == null) return;int i = 1;for (Iterator<T> iterator = list.iterator(); iterator.hasNext(); ++i) {T next = iterator.next();// 执行批量操作operation.accept(mapper, next);if (i == batchLimit) {// 超过批次大小提交一次sqlSession.flushStatements();// 计算新的最大值batchLimit = Math.min(batchLimit + batchSize, size);}}}
}
http://www.dtcms.com/a/395956.html

相关文章:

  • 每周读书与学习->初识JMeter 元件(二)
  • 西门子 S7-200 SMART PLC 实操案例:中断程序的灵活应用定时中断实现模拟量滤波(上)
  • 测试分类(1)
  • 广州创科——湖北房县汪家河水库除险加固信息化工程(续集)
  • QT(5)
  • 仓颉语言宏(Cangjie Macros)全面解析:从基础到实战
  • linux RAID存储技术
  • 【每日一问】交流电和直流电有什么区别?
  • Postman使用指南
  • 软件架构面试题及答案
  • 【STM32】基于串口的bootloader
  • 【STM32】中断
  • how many penguins in ur linux你有几只企鹅呢?
  • windows1122h2怎么升级24h2
  • ansible-playbook的使用
  • Zabbix7 监控USG6300E 并发IPv4会话数
  • Qt中使用多线程的范式
  • c语言10:指针加减指针的那些事儿
  • 数据库成为突破口:勒索软件攻击始于暴露的Oracle服务器
  • PT100铂电阻高精度原理图设计,已量产(温度传感器)
  • 推荐 6 个本周 yyds 的 GitHub 项目。
  • 内存释放机制以及栈和堆(c++)
  • PCL基础:点云体积计算,若需更精确的体积估算,可采用 Alpha Shape 或 Marching Cubes 等方法重建表面后再进行积分计算。
  • OSPF实验-20250922
  • Python控制流概述
  • 【LLM学习】【Ollama】四、MCP
  • 5G RedCap模组:轻量化5G技术的商业化实现
  • 深入探索卷积神经网络:从基础到高级架构(二)
  • 什么是DeepSeek-V3.1-Terminus版本?
  • 【C语言代码】堵车问题