多租户
2024年8月6日大约 2 分钟
多租户
1、Mybatis-plus
[!IMPORTANT] Mybatis-plus只支持自身的多租户方式
1.1、spring
@Component
public class MpTenantHandler implements TenantLineHandler {
ThreadLocal<String> threadLocal = new ThreadLocal<>();
@Override
public Expression getTenantId() {
// 返回租户ID的表达式,LongValue 是 JSQLParser 中表示 bigint 类型的 class
return new LongValue(2);
}
@Override
public String getTenantIdColumn() {
return threadLocal.get();
}
/**
* 指定租户字段
* @param tableName 表名
* @return
*/
@Override
public boolean ignoreTable(String tableName) {
TableInfo tableInfo = TableInfoHelper.getTableInfo(tableName);
List<TableFieldInfo> fieldList = tableInfo.getFieldList();
fieldList.forEach(field -> {
// 如果业务和工作流引擎中的租户字段不一致,可以通过这种方式动态切换
if (field.getColumn().equals("tenant_id") || field.getColumn().equals("tenant_code")) {
threadLocal.set(field.getColumn());
}
});
// 获取表字段
return false;
}
/**
* 如果业务系统不开启租户,使用下面方法,指定流程表才开启
* @param tableName 表名
* @return
*/
@Override
public boolean ignoreTable(String tableName) {
// 流程表
List<String> flowTableName = Arrays.asList("flow_definition", "flow_his_task", "flow_instance", "flow_node"
,"flow_skip", "flow_task", "flow_user");
TableInfo tableInfo = TableInfoHelper.getTableInfo(tableName);
AtomicBoolean flag = new AtomicBoolean(true);
if (flowTableName.contains(tableInfo.getTableName())) {
flag.set(false);
}
List<TableFieldInfo> fieldList = tableInfo.getFieldList();
fieldList.forEach(field -> {
// 如果业务和工作流引擎中的租户字段不一致,可以通过这种方式动态切换
if (field.getColumn().equals("tenant_id")) {
threadLocal.set(field.getColumn());
}
});
// 获取表字段
return flag.get();
}
}
@Configuration
public class MybatisPlusConfig {
@Resource
private MpTenantHandler mpTenantHandler;
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
TenantLineInnerInterceptor tenantInterceptor = new TenantLineInnerInterceptor();
tenantInterceptor.setTenantLineHandler(mpTenantHandler);
interceptor.addInnerInterceptor(tenantInterceptor);
return interceptor;
}
}
1.2、solon
public class MpTenantHandler implements TenantLineHandler {
ThreadLocal<String> threadLocal = new ThreadLocal<>();
@Override
public Expression getTenantId() {
// 返回租户ID的表达式,LongValue 是 JSQLParser 中表示 bigint 类型的 class
return new LongValue(2);
}
@Override
public String getTenantIdColumn() {
return threadLocal.get();
}
@Override
public boolean ignoreTable(String tableName) {
TableInfo tableInfo = TableInfoHelper.getTableInfo(tableName);
List<TableFieldInfo> fieldList = tableInfo.getFieldList();
fieldList.forEach(field -> {
// 如果业务和工作流引擎中的租户字段不一致,可以通过这种方式动态切换
if (field.getColumn().equals("tenant_id") || field.getColumn().equals("tenant_code")) {
threadLocal.set(field.getColumn());
}
});
// 获取表字段
return false;
}
}
@Configuration
public class WarmFlowConfig {
@Bean(value = "db1", typed = true)
public DataSource db1(@Inject("${demo.db1}") HikariDataSource ds) {
return ds;
}
/**
* MybatisPlus全局配置
*
* @param globalConfig 数据源
*/
@Bean
public void db1_cfg(@Db("db1") MybatisConfiguration cfg,
@Db("db1") GlobalConfig globalConfig) {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 多租户插件 必须放到第一位
interceptor.addInnerInterceptor(tenantLineInnerInterceptor());
cfg.addInterceptor(interceptor);
}
/**
* 多租户插件
*/
public TenantLineInnerInterceptor tenantLineInnerInterceptor() {
return new TenantLineInnerInterceptor(new MpTenantHandler());
}
}
2、通用多租户
2.1、yaml配置方式
# warm-flow工作流配置
warm-flow:
# 全局租户处理器(可通过配置文件注入,也可用@Bean/@Component方式
tenant_handler_path: com.warm.flow.core.test.handle.CustomTenantHandler
2.2、bean配置方式
@Configuration
public class WarmFlowConfig {
/**
* 全局租户处理器(可通过配置文件注入,也可用@Bean/@Component方式
*/
@Bean
public TenantHandler tenantHandler() {
return new CustomTenantHandler();
}
}
2.3、@Component配置方式
/**
* 全局租户处理器(可通过配置文件注入,也可用@Bean/@Component方式
*
* @author warm
*/
@Component
public class CustomTenantHandler implements TenantHandler {
@Override
public String getTenantId() {
// 这里返回系统中的当前办理人的租户ID,一般会有工具类获取
return "000000";
}
}