Sharding Sphere JDBC使用Mybatis的saveBatch无法返回主键的问题

问题背景

项目中使用了MybatisPlus框架,数据库是PostgreSQL,配置了主键自增,新增数据后返回主键到实体类中。

项目中因为数据量问题,需要用到分库分表,因此引入了Sharding Sphere JDBC框架。但是Sharding Sphere JDBC会读取sql语句,根据分库分分表规则,重新组合sql语句,到这一步还没有问题。使用Mybatis的批量新增之后,无法获取到数据库自增产生的ID,实体类中id字段为空。

原因分析

原因应该是Sharding Sphere JDBC重写了statment,没有将数据库返回的结果保存下来

这个应该是Sharding Sphere与ORM框架整合的bug

Github中有人提出这个问题,官方回答他们没人时间去阅读第三方ORM的框架代码,只对JDBC做兼容,意思就是说他们不管这个bug😂

https://github.com/apache/shardingsphere/issues/9592

解决方案

1.配置多数据源,分表的地方使用ShardingSphere,其他表使用正常的ORM框架

2.Github大佬提供的解决办法:

通过重写ShardingSpherePreparedStatement类中的addBatch方法,将statment缓存下来

注意这个版本必须是5.2.1版本以上的才可以使用

java 复制代码
public void addBatch() {
    try {
        QueryContext queryContext = this.createQueryContext();
        this.trafficInstanceId = this.getInstanceIdAndSet(queryContext).orElse(null);
        this.executionContext = null != this.trafficInstanceId ? this.createExecutionContext(queryContext, this.trafficInstanceId) : this.createExecutionContext(queryContext);
        this.batchPreparedStatementExecutor.addBatchForExecutionUnits(this.executionContext.getExecutionUnits());

        // 这里加一下缓存statement,cacheBatchStatements是新方法
        ExecutionGroupContext<JDBCExecutionUnit> executionGroupContext = this.createExecutionGroupContext();
        this.cacheBatchStatements(executionGroupContext.getInputGroups());
    } catch (SQLException e) {
        throw new RuntimeException(e);
    } finally {
        this.currentResultSet = null;
        this.clearParameters();
    }
}

private void cacheBatchStatements(Collection<ExecutionGroup<JDBCExecutionUnit>> executionGroups) throws SQLException {
    Iterator var2 = executionGroups.iterator();

    while(var2.hasNext()) {
        ExecutionGroup<JDBCExecutionUnit> each = (ExecutionGroup<JDBCExecutionUnit>)var2.next();
        each.getInputs().forEach((eachInput) -> {
            if (!this.statements.contains((PreparedStatement)eachInput.getStorageResource())) {
                this.statements.add((PreparedStatement)eachInput.getStorageResource());
            }
        });
    }
}
xml 复制代码
<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
    <version>5.2.1</version>
</dependency>

github大佬地址:https://github.com/baomidou/mybatis-plus/issues/3207

相关推荐
没有bug.的程序员5 小时前
JAVA面试宝典 - 《MyBatis 进阶:插件开发与二级缓存》
java·面试·mybatis
码不停蹄的玄黓12 小时前
深入理解MyBatis延迟加载:原理、配置与实战优化
java·mybatis·延迟加载
hello早上好16 小时前
JPA、缓存、数据源与连接池、简介
java·mybatis
梁辰兴17 小时前
企业培训笔记:宠物信息管理--实现宠物信息分页查询
笔记·elementui·mybatis·vue3·springboot·宠物
鲁子狄19 小时前
[笔记] 动态 SQL 查询技术解析:构建灵活高效的企业级数据访问层
java·spring boot·笔记·sql·mysql·mybatis
拼搏@1 天前
第十六天,7月10日,八股
java·mybatis
军军君011 天前
基于Springboot+UniApp+Ai实现模拟面试小工具四:后端项目基础框架搭建下
spring boot·spring·面试·elementui·typescript·uni-app·mybatis
超级小忍2 天前
在 Spring Boot 中使用 MyBatis 的 XML 文件编写 SQL 语句详解
xml·spring boot·mybatis
程序猿小D2 天前
[附源码+数据库+毕业论文+答辩PPT+部署教程+配套软件]基于SpringBoot+MyBatis+MySQL+Maven+Vue实现的交流互动管理系统
spring boot·mysql·vue·mybatis·毕业论文·答辩ppt·交流互动
24kHT2 天前
xml映射文件的方式操作mybatis
xml·mybatis