ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
## 多库多租户 ​ 如果每个库一个租户,则需要动态路由到指定的数据源,可以借助ConditionalConnectionSource类,类似ConditionalSQLManager,可以代理ConnectionSource,根据适当条件使用返回不同数据源的数据库连接 > 参考S6MoreDatabase.multipleDataBaseAndTables ```java public class ConditionalConnectionSource implements ConnectionSource { Policy policy; Map<String,ConnectionSource> all; ConnectionSource defaultCs; /** * * @param policy 选择数据源的策略 * @param all 所有备选的数据源表 */ public ConditionalConnectionSource( Policy policy,Map<String,ConnectionSource> all){ this.all = all; String defaultName = policy.getMasterName(); defaultCs = all.get(defaultName); if(defaultCs==null){ throw new IllegalArgumentException("根据 "+defaultName+" 找不到对应的ConnectionSource"); } this.policy = policy; } //忽略其他代码 } ``` 构造ConditionalConnectionSource 需要一个策略类以及多个ConnectionSource构成的Map。策略类决定了使用哪个ConnectionSource。定义如下 ```java @Override public Connection getConn(ExecuteContext ctx, boolean isUpdate) { String name = policy.getConnectionSourceName(ctx,isUpdate); ConnectionSource cs = all.get(name); if(cs==null){ throw new IllegalArgumentException("根据 "+name+" 找不到对应的ConnectionSource"); } return cs.getConn(ctx,isUpdate); } ``` 策略类可以根据ThreadLocal,或者ExecuteContext提供的参数来决定返回哪一个ConnectionSouce,这个跟ThreadLocalSQLManager,ConditionalSQLManager原来类似。Policy定义如下 ```java public static interface Policy{ String getConnectionSourceName(ExecuteContext ctx, boolean isUpdate); String getMasterName(); } ``` 如下根据VipLocal的值来决定使用哪个数据源操作。 项目可以在Controller的Filter或者Service的AOP里设定这个值 ```java ConditionalConnectionSource.Policy policy = new ConditionalConnectionSource.Policy() { @Override public String getConnectionSourceName(ExecuteContext ctx, boolean isUpdate) { String name = VipLocal.get() if(name!=null){ return name; }else{ // 如果没有设置,则返回一个默认库 return "cs1"; } } @Override public String getMasterName() { return "cs1"; } }; ```