千家信息网

​​​​​​​Spring多租户数据源管理AbstractRoutingDataSource怎么用

发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,本篇内容介绍了"Spring多租户数据源管理AbstractRoutingDataSource怎么用"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处
千家信息网最后更新 2025年11月07日​​​​​​​Spring多租户数据源管理AbstractRoutingDataSource怎么用

本篇内容介绍了"Spring多租户数据源管理AbstractRoutingDataSource怎么用"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

1.基本原理

多数据源能进行动态切换的核心就是spring底层提供了AbstractRoutingDataSource类进行数据源路由。AbstractRoutingDataSource实现了DataSource接口,所以我们可以将其直接注入到DataSource的属性上。

我们主要继承这个类,实现里面的方法determineCurrentLookupKey(),而此方法只需要返回一个数据库的名称即可。

比如,Controller通过拿到前端业务传递的数值,进行业务逻辑分发。它就可以手动设置当前请求的数据库标识,然后路由到正确的库表里面。

@Controllerpublic 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 InheritableThreadLocal 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.h3.Driver      url: jdbc:h3:mem:dba;MODE=MYSQL;DATABASE_TO_UPPER=false;    db-b:      driver-class-name: org.h3.Driver      url: jdbc:h3:mem:dbb;MODE=MYSQL;DATABASE_TO_UPPER=false;

然后,我们将它解析称properties。

@ConfigurationProperties(prefix = "multi")@Configurationpublic class DbsProperties {    private Map> dbs = new HashMap<>();    public Map> getDbs() {        return dbs;    }    public void setDbs(Map> dbs) {        this.dbs = dbs;    }}

接下来一步,需要配置整个应用所默认的数据源。如你所见,它的主要逻辑,就是在运行的时候,从ThreadLocal里取出提前设置的这个值。

public class DynamicDataSource extends AbstractRoutingDataSource {    @Override    protected Object determineCurrentLookupKey() {        return DataSourceContextHolder.getDbKey();    }}

最后一步,设置整个项目中默认的DataSource。注意,我们生成DynamicDataSource之后,还需要提供targetDataSource和defaultTargetDataSource两个属性的值,才能够正常运行。

@Configurationpublic class DynamicDataSourceConfiguration {    @Autowired    DbsProperties properties;    @Bean    public DataSource dataSource(){        DynamicDataSource dataSource = new DynamicDataSource();        final Map targetDataSource  = getTargetDataSource();        dataSource.setTargetDataSources(targetDataSource);        //TODO 默认数据库需要设置        dataSource.setDefaultTargetDataSource(targetDataSource.values().iterator().next());        return dataSource;    }    private Map getTargetDataSource(){        Map dataSources = new HashMap<>();        this.properties.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等模式,将不可用。不方便测试和单元测试,在测试接口的时候,也需要每次强制指定指向的库。

  • 由于是修改数据源的模式,每次增加库,都需要重新启动上线才可以。如果要做到动态性,数据源销毁是个问题。

"Spring多租户数据源管理AbstractRoutingDataSource怎么用"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

数据 数据源 属性 数据库 问题 配置 管理 业务 代码 方式 时候 模式 切换 测试 运行 租户 接下来 两个 内容 前端 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 小米手机网络安全 网络软件开发售后服务 软件开发转岗 网络安全意识形态领导组通知 非关系型数据库 关联关系 轻应用管理服务器 安装网站 超市商品数据库哪里下载 湖南项目软件开发排名 定向士官计算机网络技术好就业吗 贵州语音网络技术分类基础 泸溪软件开发有限公司 云服务器存储数据安全吗 巢湖品质网络技术服务哪家好 数据库软件 功能 辅料安全数据库 电大数据库应用技术题库 幼儿网络安全宣传手抄报 为什么要减少对数据库的访问 机械管理软件开发 手机下载中心显示服务器错误 服务器已经断开连接 数据库安装实例名称无效 河南什么是软件开发推广 常用的网络安全包括哪些方面 嘉定区国际网络技术服务收费标准 华农图书馆的数据库 图书馆数据库收费 初中学习网络技术有用吗 网络安全致小学家长一封信 直播服务器带宽要求
0