千家信息网

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

发表于:2025-01-16 作者:千家信息网编辑
千家信息网最后更新 2025年01月16日,本篇内容介绍了"Spring多租户数据源管理AbstractRoutingDataSource怎么用"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处
千家信息网最后更新 2025年01月16日​​​​​​​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安全错误 数据库的锁怎样保障安全 通过数据库查询数据步骤 数据库与java哪个火 北京企业软件开发市场报价 广州天象网络技术有限公司6 公司网络安全监控合法吗 于做好网络安全风险防范 网易版最好玩创造的服务器 软件开发相关的法条知识 基岩版服务器免费永久 夏维安服务器怎么样 对于网络安全该做什么 四川双嘉网络技术有限公司 服务器监控数据采集数据结构 软件开发课程程序员班 adams 公用数据库 宜阳软件开发怎么选 服务器主机名可以改吗 远程监控服务器是一种云端嘛 免费移植云数据库 认可的企业网络安全解决方案 重庆天衡互联网科技集团 ncbi数据库检索工具 数据库sql窗口输入的英文 公司网络安全监控合法吗 软件开发岗位的简历怎么写 银行软件开发岗具体工作 苹果连接不上服务器退出不了账号 逆水寒四周年服务器开启时间 总体国家安全观与网络安全 对日软件开发前景怎么样
0