xiaoming728

xiaoming728

Mybatis-Plus 多租户插件-管理员忽略租户

2025-02-27
Mybatis-Plus 多租户插件-管理员忽略租户

原理

原理很简单:重写 Mybatis-Plus 构建 构建租户条件表达式 方法 buildTableExpression

首先继承TenantLineInnerInterceptor 重写 buildTableExpression 方法


/**
 * 管理员租户行内部侦听器
 *
 * @author xiaoming728
 * @date 2025-02-27
 */
@AllArgsConstructor
public class AdminTenantLineInnerInterceptor extends TenantLineInnerInterceptor {

    private TenantLineHandler tenantLineHandler;

    public TenantLineHandler getTenantLineHandler() {
        return this.tenantLineHandler;
    }

    public void setTenantLineHandler(final TenantLineHandler tenantLineHandler) {
        this.tenantLineHandler = tenantLineHandler;
    }

    @Override
    public Expression buildTableExpression(Table table, Expression where, String whereSegment) {
        if (tenantLineHandler.ignoreTable(table.getName())) {
            return null;
        }
        // 使用时需要注意,如果使用的是 Ruoyi-Vue-Plus 多租户版本框架,不要这样使用,可能会导致字典等信息复制多份,导致服务无法使用,建议将这里改为,通过配置文件配置哪些表可以让管理员忽略租户访问
        Expression tenantId = tenantLineHandler.getTenantId();
        if ("000000".equals(tenantId.toString())) {
            return null;
        }
        return new EqualsTo(getAliasColumn(table), tenantId);
    }
}

!!!使用时需要注意,如果使用的是 Ruoyi-Vue-Plus 多租户版本框架,不要这样使用,可能会导致字典等信息复制多份,导致服务无法使用,建议将这里改为,通过配置文件配置哪些表可以让管理员忽略租户访问

!!!使用时需要注意,如果使用的是 Ruoyi-Vue-Plus 多租户版本框架,不要这样使用,可能会导致字典等信息复制多份,导致服务无法使用,建议将这里改为,通过配置文件配置哪些表可以让管理员忽略租户访问

!!!使用时需要注意,如果使用的是 Ruoyi-Vue-Plus 多租户版本框架,不要这样使用,可能会导致字典等信息复制多份,导致服务无法使用,建议将这里改为,通过配置文件配置哪些表可以让管理员忽略租户访问

使用多租户插件


/**
 * 租户配置类
 *
 * @author Lion Li
 */
@EnableConfigurationProperties(TenantProperties.class)
@AutoConfiguration(after = {RedisConfig.class})
@ConditionalOnProperty(value = "tenant.enable", havingValue = "true")
public class TenantConfig {

    @ConditionalOnBean(MybatisPlusConfig.class)
    @AutoConfiguration(after = {MybatisPlusConfig.class})
    static class MybatisPlusConfiguration {

        /**
         * 多租户插件
         */
        @Bean
        public AdminTenantLineInnerInterceptor tenantLineInnerInterceptor(TenantProperties tenantProperties) {
            return new AdminTenantLineInnerInterceptor(new PlusTenantLineHandler(tenantProperties));
        }

    }

    @Bean
    public RedissonAutoConfigurationCustomizer tenantRedissonCustomizer(RedissonProperties redissonProperties) {
        return config -> {
            TenantKeyPrefixHandler nameMapper = new TenantKeyPrefixHandler(redissonProperties.getKeyPrefix());
            SingleServerConfig singleServerConfig = ReflectUtils.invokeGetter(config, "singleServerConfig");
            if (ObjectUtil.isNotNull(singleServerConfig)) {
                // 使用单机模式
                // 设置多租户 redis key前缀
                singleServerConfig.setNameMapper(nameMapper);
                ReflectUtils.invokeSetter(config, "singleServerConfig", singleServerConfig);
            }
            ClusterServersConfig clusterServersConfig = ReflectUtils.invokeGetter(config, "clusterServersConfig");
            // 集群配置方式 参考下方注释
            if (ObjectUtil.isNotNull(clusterServersConfig)) {
                // 设置多租户 redis key前缀
                clusterServersConfig.setNameMapper(nameMapper);
                ReflectUtils.invokeSetter(config, "clusterServersConfig", clusterServersConfig);
            }
        };
    }

    /**
     * 多租户缓存管理器
     */
    @Primary
    @Bean
    public CacheManager tenantCacheManager() {
        return new TenantSpringCacheManager();
    }

    /**
     * 多租户鉴权dao实现
     */
    @Primary
    @Bean
    public SaTokenDao tenantSaTokenDao() {
        return new TenantSaTokenDao();
    }

}