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

解决SqlServer自增主键使用MybatisPlus批量插入报错问题

报错

SqlServer 表中主键设置为自增,会报以下错误。

org.springframework.jdbc.UncategorizedSQLException: Error getting generated key or setting result to parameter object. Cause: com.microsoft.sqlserver.jdbc.SQLServerException: 必须执行该语句才能获得结果

报错原因

原因:mybatis-plus 批量执行时 SQL server 自增主键没有回填造成的。

从 MyBatis3.3.1 版本开始,MyBatis 开始支持批量新增回写主键值的功能,这个功能首先要求数据库主键值为自增类型,同时还要求该数据库提供的 JDBC 驱动可以支持返回批量插入的主键值(JDBC提供了接口,但并不是所有数据库都完美实现了该接口),因此到目前为止,可以完美支持该功能的仅有 MySQL 数据库。由于 SQL Server 数据库官方提供的 JDBC 只能返回最后一个插入数据的主键值,所以不能支持该功能。

分析

查看调用栈,来到 BatchExecutor 的 doFlushStatements 方法,执行了 jdbc3KeyGenerator.processBatch(ms, stmt, parameterObjects)

进入方法,在如图位置抛出异常

解决

实现工具类,给 MappedStatement 设置 NoKeyGenerator,问题就解决了

public class SqlUtil {/*** 500条数据 提交一次* 必须是  BATCH_CNT_SQL_SIZE 整数倍*/private final static int BATCH_SIZE = 500;
​/*** 批量保存,解决 mybatis-plus 在批量插入时由于主键自增报错问题* 如果主键不是自增,不要调用* @param list     数据集合* @param mClazz   mapper* @return 操作结果*/public static <E, M extends BaseMapper<E>> boolean saveBatch(Class<M> mClazz, List<E> list) {SqlSessionFactory factory = SpringUtil.getBean(SqlSessionFactory.class);SqlSession sqlSession = factory.openSession(ExecutorType.BATCH, false);MappedStatement ms = sqlSession.getConfiguration().getMappedStatement(mClazz.getName() + ".insert");MetaObject metaObject = SystemMetaObject.forObject(ms);Object keyGenerator = metaObject.getValue("keyGenerator");metaObject.setValue("keyGenerator", NoKeyGenerator.INSTANCE);M mapper = sqlSession.getMapper(mClazz);try {// 用于跟踪自上次刷新以来已处理的元素数int processedCount = 0;for (E e : list) {mapper.insert(e);processedCount++;if (processedCount >= BATCH_SIZE) {sqlSession.flushStatements();processedCount = 0;}}// 如果还有剩余的元素未刷新,则刷新if (processedCount > 0) {sqlSession.flushStatements();}sqlSession.commit();return true;} catch (Throwable t) {sqlSession.rollback();throw new RuntimeException(t.getMessage());} finally {metaObject.setValue("keyGenerator", keyGenerator);SqlSessionUtils.closeSqlSession(sqlSession, factory);}}
}

http://www.lryc.cn/news/457066.html

相关文章:

  • leetcode:反转字符串中的单词III
  • 深度学习常见问题
  • 神经网络的一些benchmark示例
  • 如何进行统级架构设计
  • 鼓组编写:SsdSample鼓映射 GM Map 自动保存 互换midi位置 风格模板 逻辑编辑器
  • 使用YOLOv11进行视频目标检测
  • DEEP和DeepBook V3将于10月14日推出
  • 学习之高阶编程列表推导式,字典推导式
  • QT实现QInputDialog中文按钮
  • Redis 常用指令技术解读
  • Web前端入门
  • 贝塞尔曲线详细讲解,如何用 Canvas 绘制三阶贝塞尔曲线?
  • Ubuntu20.04卸载ros2 foxy版本安装ros1 noetic版本
  • PicGo+Gitee搭建Typora图床
  • MySQL 脱敏函数使用详解:保护数据隐私的关键手段
  • nginx之virtual host
  • Windows 下纯手工打造 QT 开发环境
  • k8s的安装和部署
  • 第十八篇:一文说清楚ICMP的底层原理
  • 【优选算法】(第三十二篇)
  • 线程(四)线程的同步——条件变量
  • 二维数组的旋转与翻转(C++)(上(这只是简单讲解))
  • 【在Linux世界中追寻伟大的One Piece】System V共享内存
  • 【大数据】Spark弹性分布式数据集RDD详细说明
  • 人参玉桂膏简介
  • 消费者Rebalance机制
  • 消息队列介绍
  • 告别@Value,Spring Boot 3.3更优雅的配置注入方案
  • 甲虫身体图像分割系统源码&数据集分享
  • Qt - QMenu