当前使用版本(必填,否则不予处理)

     <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 后测试,还是未解决打开该问题反馈错误