目标
- 默认情况下,租户是使用tentid,实现表内隔离
- 租户可以选择独立数据库,独立文件系统。
ZLT多租户实现方案
概要
ZLT使用的实际是Mybatis-Plus的多租户方案。
注意其中关键的两个类,
TenantSqlParser TenantHandler
其中TenantSqlParser 需要一个 TenantHandler 接口成员,
根据TenantHandler 接口的
getTenantId()
getTenantIdColumn()
doTableFilter(String tableName)
三个方法分别配置租户ID的获取,租户ID的字段名,以及是否过滤该表

实现代码
实际上就是设置tentid,Mybatis-Plus会自动插入脚本,在crud层面自动处理了tentId
public class TenantContextHolder {/*** 支持父子线程之间的数据传递*/private static final ThreadLocal<String> CONTEXT = new TransmittableThreadLocal<>();public static void setTenant(String tenant) {CONTEXT.set(tenant);}public static String getTenant() { return CONTEXT.get(); }public static void clear() {CONTEXT.remove();}}
自动化配置,这个代码是丢在启动器里面的
@EnableConfigurationProperties(TenantProperties.class)public class TenantAutoConfigure {@Autowiredprivate TenantProperties tenantProperties;@Beanpublic TenantHandler tenantHandler() {return new TenantHandler() {/*** 获取租户id*/@Overridepublic Expression getTenantId(boolean where) {String tenant = TenantContextHolder.getTenant();if (tenant != null) {return new StringValue(TenantContextHolder.getTenant());}return new NullValue();}/*** 获取租户列名*/@Overridepublic String getTenantIdColumn() {return "tenant_id";}/*** 过滤不需要根据租户隔离的表* @param tableName 表名*/@Overridepublic boolean doTableFilter(String tableName) {return tenantProperties.getIgnoreTables().stream().anyMatch((e) -> e.equalsIgnoreCase(tableName));}};}/*** 过滤不需要根据租户隔离的MappedStatement*/@Beanpublic ISqlParserFilter sqlParserFilter() {return metaObject -> {MappedStatement ms = SqlParserHelper.getMappedStatement(metaObject);return tenantProperties.getIgnoreSqls().stream().anyMatch((e) -> e.equalsIgnoreCase(ms.getId()));};}}
代码增强:实现对多租户信息的获取
重写mybatis-plus里面的MultiTenantSqlParser的代码,这是对接口AbstractJsqlParser的实现。
protected Expression builderExpression(Expression currentExpression, Table table) {Expression tenantExpression = this.tenantHandler.getTenantId(false);Object appendExpression;// 多个tenant id的情况if (tenantExpression instanceof MultiOrExpression){appendExpression = tenantExpression;}else if (!(tenantExpression instanceof SupportsOldOracleJoinSyntax)) {.....}
