当前使用版本(必填,否则不予处理)
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
该问题是如何引起的?(确定最新版也有问题再提!!!)
前面的工程使用3.4.3.1 多租户使用正常,现在升级到3.5.1出现多租户,ignoreTable不会进来,我回退到3.5.0版本可正常使用
/**
* 新多租户插件配置,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存万一出现问题
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//多租户
interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantLineHandler() {
@Override
public Expression getTenantId() {
// 从当前系统上下文中取出当前请求的服务商ID。
Long currentTenantId = context.getCurrentTenantId();
if (currentTenantId == null) {
//获取缓存的tenant_id
currentTenantId =
Convert.toLong(redisUtil.get(ConstantRedisKey.USER_DATA_CACHE + Constant.CURRENT_TENANT_ID));
}
if (null == currentTenantId) {
throw new RuntimeException("获取当前服务商失败");
}
return new LongValue(currentTenantId);
}
// 这是 default 方法,默认返回 false 表示所有表都需要拼多租户条件
//在3.5.1之前,这个ignoreTable会进来,多租户使用正常,在使用3.5.1时不进来,会一直进来上面那个getTenantId函数。导致多租户不可用
@Override
public boolean ignoreTable(String tableName) {
return CONST_EXCLUDE_TABLE.contains(tableName);
}
}));
// 开启 count 的 join 优化,只针对部分 left join
PaginationInnerInterceptor innerInterceptor = new PaginationInnerInterceptor();
innerInterceptor.setOptimizeJoin(true);
// 如果用了分页插件注意先 add TenantLineInnerInterceptor 再 add PaginationInnerInterceptor
// 用了分页插件必须设置 MybatisConfiguration#useDeprecatedExecutor = false
interceptor.addInnerInterceptor(innerInterceptor);
return interceptor;
}
重现步骤(如果有就写完整)
前面的工程使用3.4.3.1 多租户使用正常,现在升级到3.5.1出现多租户,ignoreTable不会进来,我回退到3.5.0版本可正常使用
报错信息
配置ignoreTable常量表无效,会一直进去getTenantId函数,使多租户配置不可用
Comment From: nancheung
刚测了一下是可以进入ignoreTable方法的,如有问题,可以提供如何复现的具体使用场景吗
Comment From: LelandACM
@nancheung97 谢谢,我这个是我的配置文件,我也自己再测试下
@Configuration
@EnableTransactionManagement
@MapperScan("sunet.net.cn.sunetcloud.mapper")
public class MybatisPlusConfig {
private final TenantApiContext context;
private final RedisUtil redisUtil;
private final List<String> CONST_EXCLUDE_TABLE = new ArrayList<>();
public MybatisPlusConfig(TenantApiContext context, RedisUtil redisUtil) {
this.context = context;
this.redisUtil = redisUtil;
this.CONST_EXCLUDE_TABLE.add("sc_account");
this.CONST_EXCLUDE_TABLE.add("sc_tenant");
this.CONST_EXCLUDE_TABLE.add("sc_area");
this.CONST_EXCLUDE_TABLE.add("sc_log_type");
this.CONST_EXCLUDE_TABLE.add("sc_status");
this.CONST_EXCLUDE_TABLE.add("sc_permission");
this.CONST_EXCLUDE_TABLE.add("sc_permission_sub");
this.CONST_EXCLUDE_TABLE.add("sc_department");
this.CONST_EXCLUDE_TABLE.add("information_schema.tables");
}
/**
* 新多租户插件配置,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存万一出现问题
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//多租户
interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantLineHandler() {
@Override
public Expression getTenantId() {
// 从当前系统上下文中取出当前请求的服务商ID。
Long currentTenantId = context.getCurrentTenantId();
if (currentTenantId == null) {
//获取缓存的tenant_id
currentTenantId =
Convert.toLong(redisUtil.get(ConstantRedisKey.USER_DATA_CACHE + Constant.CURRENT_TENANT_ID));
}
if (null == currentTenantId) {
throw new RuntimeException("获取当前服务商失败");
}
return new LongValue(currentTenantId);
}
// 这是 default 方法,默认返回 false 表示所有表都需要拼多租户条件
@Override
public boolean ignoreTable(String tableName) {
return CONST_EXCLUDE_TABLE.contains(tableName);
}
}));
// 开启 count 的 join 优化,只针对部分 left join
PaginationInnerInterceptor innerInterceptor = new PaginationInnerInterceptor();
innerInterceptor.setOptimizeJoin(true);
// 如果用了分页插件注意先 add TenantLineInnerInterceptor 再 add PaginationInnerInterceptor
// 用了分页插件必须设置 MybatisConfiguration#useDeprecatedExecutor = false
interceptor.addInnerInterceptor(innerInterceptor);
return interceptor;
}
}
我在implService 里面调用 sc_account表的查询语句,理论上我设置sc_account表为忽略,他会进来 ignoreTable,但是他是直接进入getTenantId这个函数,导致为空报错。我的currentTenantId就是从sc_account表得到的。不知道我表述清楚没,我再自己试看下哪里出问题了
Comment From: LelandACM
@nancheung97 通过调试发现,3.5.0版本中,ignoreTable函数会先于getTenantId调用,而3.5.1正好相反。 不应该是先判断此表是否忽略,再来用getTenantId中的tenant_id来拼接吗?
Comment From: qmdx
升级 3.5.3.2 后测试,还是未解决打开该问题反馈错误