天天看點

帶你看懂RuoYi動态資料源切換資料源是什麼一、spring中是如何處理各種資料源的?二、有了如上的理論,那麼想想動态切換資料源吧總結

文章目錄

  • 資料源是什麼
  • 一、spring中是如何處理各種資料源的?
    • 1.開搞springboot
    • 2.建立一個測試類
  • 二、有了如上的理論,那麼想想動态切換資料源吧
    • 參考若依的動态資料源配置
  • 總結

資料源是什麼

資料源,對于java來說,就是可用的資料庫,那麼我平時開發的springboot springcloud項目,那麼也就是yml或者properties中的連結資訊, 例如 mysql redis influx mongodb sqlserver clickhouse nebula-graph …

一般在spring中,都已經對其做好了封裝

一、spring中是如何處理各種資料源的?

那就不得不說下JdbcTemplate 了,隻要是各種遵循了jdbc标準的資料源,也就是大部分的關系型資料庫,都是可以通過它來操作的;簡直就是神奇~~ 怎麼使用呢?

1.開搞springboot

搞一個springboot項目 由于我使用了mysql,是以還引入了mysql驅動包

<dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-jdbc</artifactId>
      </dependency>
      <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
         <scope>runtime</scope>
      </dependency>
           

然後在yml加入相應配置

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://xxxxx:3307/yuque
    username: root
    password: 123456
           

2.建立一個測試類

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
class WordApplicationTests1 {

    @Test
    void contextLoads() {
    }

    @Autowired
    JdbcTemplate jdbcTemplate;

    @SneakyThrows
    @Test
    public void query() {
        List<Bom> bomList = jdbcTemplate.query("select DISTINCT * from bom", new BeanPropertyRowMapper<>(Bom.class));

        System.out.println(JSONUtil.toJsonStr(bomList));
    }
}
           

相當于可以了,用的就是yml中的配置查詢的資料庫

帶你看懂RuoYi動态資料源切換資料源是什麼一、spring中是如何處理各種資料源的?二、有了如上的理論,那麼想想動态切換資料源吧總結
  • 我有一個想法,我想查詢一個其他的庫的資料,但是之前的yml中的我還想用

改造後,變成了

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
class WordApplicationTests1 {

    @Test
    void contextLoads() {
    }

    @Autowired
    JdbcTemplate jdbcTemplate;

    @SneakyThrows
    @Test
    public void query() {
        List<Bom> bomList = jdbcTemplate.query("select DISTINCT * from bom", new BeanPropertyRowMapper<>(Bom.class));

        System.out.println(JSONUtil.toJsonStr(bomList));

        Properties properties = new Properties();
        properties.put("url", "jdbc:mysql://localhost:3306/test?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&allowMultiQueries=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true");
        properties.put("username", "root");
        properties.put("driverClassName", "com.mysql.jdbc.Driver");
        properties.put("password", "root");

        DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
        JdbcTemplate template = new JdbcTemplate(dataSource);

        List<Bom> list = template.query("select * from bom", new BeanPropertyRowMapper<>(Bom.class));
        System.out.println(JSONUtil.toJsonStr(list));
    }
}

           

還是能用的,兩個都能查詢出資料

帶你看懂RuoYi動态資料源切換資料源是什麼一、spring中是如何處理各種資料源的?二、有了如上的理論,那麼想想動态切換資料源吧總結

那…請小夥伴思考下,如果是用jdbc弄一個動态資料源,是不是也不是很難,我需要用哪個庫的資訊,就讓他加載哪個庫的配置資訊就ok了呀.對吧?

甚至,我可以将配置資訊放入資料庫中,啟動後,一次性加載到記憶體,并執行個體化相應的datasource 執行個體,然後在執行個體化相應的jdbctemplete,放入到的全局中,那麼我就可以自如切換了!!!

二、有了如上的理論,那麼想想動态切換資料源吧

參考若依的動态資料源配置

若依

大體思路如下:

  • 首先利用本地線程搞一個緩存,目的是為了存放目前可用的資料源,這樣就可以設定/移除 某個資料源了;
DynamicDataSourceContextHolder 僅僅是個緩存
           
  • 由于為了使用友善,是以他自定義了注解,用來切換資料源,也就是更改上面的目前線程緩存,那麼自定義之後,就需要通過切面去實作這個自定義的注解,裡面的中心思想就是擷取傳入的可用資料源(可能有多個),替換之為目前資料源(隻能有一個);
DataSourceAspect 切面實作切換
           
  • 那麼多個資料源是從哪裡來的呢,是在項目啟動的時候,他就已經把可用資料源都執行個體化好了,然後存放起來了,就像我之前分析的那樣,關鍵點就是 實作這個方法 AbstractRoutingDataSource 其中 放入一個map 就是資料源本尊了
DruidConfig 把所有資料源都加載進去了
           
  • 之後就可以通過map.getkey 那樣,擷取到自己想要的資料源了;然後更改本地線程的資料源
  • 切換之後,查詢的時候,就會重新查詢到目前設定後的資料源,然後再去查詢

重點中的重點

DynamicDataSource extends AbstractRoutingDataSource
           
@Override
   protected Object determineCurrentLookupKey(){
       return DynamicDataSourceContextHolder.getDataSourceType();// 每次執行都會重新擷取新值
   }
           
帶你看懂RuoYi動态資料源切換資料源是什麼一、spring中是如何處理各種資料源的?二、有了如上的理論,那麼想想動态切換資料源吧總結

總結

通過此次JdbcTemplate 的資料源切換,想到了之前看過的若依項目中的多資料源切換問題,這次帶着我自己的想法去看,果然再次閱讀,收獲頗豐;算是徹底看懂了吧;

希望我的了解能為你帶來啟發