让建站和SEO变得简单

让不懂建站的用户快速建站,让会建站的提高建站效率!

你的位置:13彩票 > 首页 > 实用:Spring的多佃户数据源解决 AbstractRoutingDataSource!

首页
实用:Spring的多佃户数据源解决 AbstractRoutingDataSource!
发布日期:2022-05-15 15:28    点击次数:172

本文转载自微信公众号「密斯姐滋味」,作家密斯姐养的狗02号  。转载本文请关系密斯姐滋味公众号。

很厚情况,咱们如实需要在一个干事中拜访多个数据源。诚然它让合座盘算变的不那么优雅,但信得过的全国如实需要它。比如,你的业务为两个比拟大的客户干事,但你但愿他们大约共用一套代码。

也即是说,你的代码刚运转莫得议论盘算多佃户这种功能,但后头又有这种蛋疼的需求。但还好不是爆炸式的佃户增长。

除了引入一些分库分表组件,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 InheritableThreadLocal<String> 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 Map<String, Map<String, String>> dbs = new HashMap<>();      public Map<String, Map<String, String>> getDbs() {         return dbs;     }      public void setDbs(Map<String, Map<String, 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 Map<Object,Object> targetDataSource  = getTargetDataSource();         dataSource.setTargetDataSources(targetDataSource);         //TODO 默许数据库需要建筑         dataSource.setDefaultTargetDataSource(targetDataSource.values().iterator().next());         return dataSource;     }      private Map<Object,Object> getTargetDataSource(){         Map<Object,Object> 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等风物,将不可用。不便捷测试和单位测试,在测试接口的工夫,也需要每次强制指定指向的库。 由于是修改数据源的风物,每次加多库,都需要再行启动上线才不错。若是要做到动态性,数据源殉国事个问题。 End

关于一个微干事来说,有许多默许的汗漫计谋,比如,不同域之间的干事是不成分享一个数据库的。这些基本原则,把微干事整的明昭着白,是一些基本的原则。

同理的,若是咱们在盘算运转,就给每一张表加上佃户的字段ID,那么写代码的工夫就顺畅的多。然而全国上莫得这样多若是。

原则为何而存在?天然是为了让人去碎裂的。

编程仅仅器具,归正代码在我方手里,若何玩,看需要,也看神志。条条正途通罗马,曲径通幽处,征象无穷好。

 

作家简介:密斯姐滋味 (xjjdog),一个不允许法子员走弯路的公众号。聚焦基础架构和Linux。十年架构,日百亿流量,与你探讨高并发全国,给你不通常的滋味。

 



Powered by 13彩票 @2013-2022 RSS地图 HTML地图

Copyright 站群系统 © 2013-2021 365建站器 版权所有