版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第Spring多租户数据源管理AbstractRoutingDataSource目录1.基本原理2.配置代码3.问题总结前言:
很多情况,我们确实需要在一个服务中访问多个数据源。虽然它让整体设计变的不那么优雅,但真实的世界确实需要它。比如,你的业务为两个比较大的客户服务,但你希望他们能够共用一套代码。
也就是说,你的代码刚开始没有考虑设计多租户这种功能,但后面又有这种蛋疼的需求。但还好不是爆炸式的租户增长。
除了引入一些分库分表组件,Spring自身提供了AbstractRoutingDataSource的方式,让多数数据源的管理成为可能。其实分库分表组件使用上限制很多,你不得不首先梳理这座屎山,接下来还要忍受中间件对你的SQL的苛刻要求;反而是一些野路子,能够让代码的改动量尽量的减少。
心动不如行动。接下来,就让我们来看一下它的具体实现吧。
1.基本原理
多数据源能进行动态切换的核心就是spring底层提供了AbstractRoutingDataSource类进行数据源路由。AbstractRoutingDataSource实现了DataSource接口,所以我们可以将其直接注入到DataSource的属性上。
我们主要继承这个类,实现里面的方法determineCurrentLookupKey(),而此方法只需要返回一个数据库的名称即可。
比如,Controller通过拿到前端业务传递的数值,进行业务逻辑分发。它就可以手动设置当前请求的数据库标识,然后路由到正确的库表里面。
@Controller
public
class
ARDTestController
{
@GetMapping("test")
public
void
chifeng(){
//db-a
应该是上层传递下来的属性,我们可以把它放在ThreadLocal里
DataSourceContextHolder.setDbKey("db-a");
}
}
那么当sql语句执行的时候,它如何知道自己需要切换到哪个数据源呢?是不是需要把db-a这个属性一直透传下去呢?
在Java中,可以使用ThreadLocal绑定这个透传的属性。像Spring的嵌套事务等实现的原理,也是基于ThreadLocal去运行的。所以,DataSourceContextHolder.本质上是一个操作ThreadLocal的类。
public
class
DataSourceContextHolder
{
private
static
InheritableThreadLocalString
dbKey
=
new
InheritableThreadLocal();
public
static
void
setDbKey(String
key){
dbKey.set(key);
}
public
static
String
getDbKey(){
return
dbKey.get();
}
}
2.配置代码
首先,我们自定义了配置文件的格式。如下面的代码,就配置了db-a和db-b两个数据库。
multi:
dbs:
db-a:
driver-class-name:
org.h2.Driver
url:
jdbc:h2:mem:dba;MODE=MYSQL;DATABASE_TO_UPPER=false;
db-b:
driver-class-name:
org.h2.Driver
url:
jdbc:h2:mem:dbb;MODE=MYSQL;DATABASE_TO_UPPER=false;
然后,我们将它解析称properties。
@ConfigurationProperties(prefix
=
"multi")
@Configuration
public
class
DbsProperties
{
private
MapString,
MapString,
String
dbs
=
new
HashMap();
public
MapString,
MapString,
String
getDbs()
{
return
dbs;
}
public
void
setDbs(MapString,
MapString,
String
dbs)
{
this.dbs
=
dbs;
}
}
接下来一步,需要配置整个应用所默认的数据源。如你所见,它的主要逻辑,就是在运行的时候,从ThreadLocal里取出提前设置的这个值。
public
class
DynamicDataSource
extends
AbstractRoutingDataSource
{
@Override
protected
Object
determineCurrentLookupKey()
{
return
DataSourceContextHolder.getDbKey();
}
}
最后一步,设置整个项目中默认的DataSource。注意,我们生成DynamicDataSource之后,还需要提供targetDataSource和defaultTargetDataSource两个属性的值,才能够正常运行。
@Configuration
public
class
DynamicDataSourceConfiguration
{
@Autowired
DbsProperties
properties;
@Bean
public
DataSource
dataSource(){
DynamicDataSource
dataSource
=
new
DynamicDataSource();
final
MapObject,Object
targetDataSource
=
getTargetDataSource();
dataSource.setTargetDataSources(targetDataSource);
//TODO
默认数据库需要设置
dataSource.setDefaultTargetDataSource(targetDataSource.values().iterator().next());
return
dataSource;
}
private
MapObject,Object
getTargetDataSource(){
MapObject,Object
dataSources
=
new
HashMap();
perties.getDbs().entrySet().stream()
.forEach(e-{
DriverManagerDataSource
dmd
=
new
DriverManagerDataSource();
dmd.setUrl(e.getValue().get("url"));
dmd.setDriverClassName(e.getValue().get("driver-class-name"));
dataSources.put(e.getKey(),dmd);
});
return
dataSources;
}
}
3.问题
通过以上简单的代码,就可以实现Spring简单的多数据源管理。但明显的,它还存在很多问题。
需要产品设计选择模式,进行业务切换。前端可以采用放在localStroage的方式,保存属性,可使用拦截器方式将变量每次都传递。后端每次请求,都需要带上目标db,可以采用放在ThreadLocal里的方式。但ThreadLocal有线程透传的问题,如果任务里开启了子线程,则变量不能共享。由于表是动态选择的,所以JPA自动创建和update等模式,将不可用。不方便测试和单元测试,在测试接口的时候,也需要每次强制指定指向的库。由于是修改数据源的模式,每次增加库,都需要重新启动上线才可以。如果要做到动态性,数据源销毁是个问题。
总结
对于一个微服务来说,有很多默认的
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年上半年福建三明高新区投资发展集团有限公司招聘1人笔试模拟试题及答案解析
- 2026福建宁德三都澳经济开发区管理委员会招聘2人考试参考试题及答案解析
- 2026湖北十堰茅箭区人民医院护理岗位招聘2人笔试参考试题及答案解析
- 人才发展培养计划实施承诺书(5篇)
- 2026北京市海淀区特殊教育研究与指导中心招聘3人笔试备考题库及答案解析
- 公司财务稳健发展承诺书(8篇)
- 2026年企业家健康管理方案设计与案例分析
- 2026广西崇左天等县人民武装部编外聘用人员招聘2人笔试模拟试题及答案解析
- 2026年外企本土化过程中的跨文化领导力挑战
- 2026江西新余市分宜县事业单位选调16人考试参考试题及答案解析
- 2026广西北海市从“五方面人员”中选拔乡镇领导班子成员25人笔试备考试题及答案解析
- 2026广西北海市产业投资有限责任公司招聘4人备考题库带答案详解(综合卷)
- 2026年滁州城市职业学院单招综合素质考试题库含答案详细解析
- 2026年四川省南充市辅警人员招聘考试试题解析及答案
- 博物馆意识形态责任制度
- (一模)南昌市2026届高三年级三月测试语文试卷(含答案解析)
- 2026四川泸州高新控股旗下泸州产城招引商业管理有限公司人员招聘4人考试参考题库及答案解析
- 错混料内部奖惩制度
- 全国计算机等级考试二级Python编程真题及答案解析(共10套真题)
- 110kV瓮北变110kV间隔扩建工程施工组织设计
- 2019年广播电视大学春季招生简章
评论
0/150
提交评论