问题背景
项目中使用了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版本以上的才可以使用
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());
}
});
}
}
<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