天天看點

Spring進階:3步搞定MybatisPlus多資料源,詳細配置及原了解析

作者:程式員拾山

前言

MybatisPlus(MP)作為mybatis的增強工具,提供了配置多資料源的擴充,通過簡單的幾步配置,即可使用注解輕松切換資料源。

以下是dynamic-datasource提供的功能清單:

Spring進階:3步搞定MybatisPlus多資料源,詳細配置及原了解析

使用方法

1,引入dynamic-datasource-spring-boot-starter。

<dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
  <version>${version}</version>
</dependency>           

2,配置多資料源。

spring:
  datasource:
    dynamic:
      primary: master #預設主庫名為master
      strict: false #不使用嚴格模式
      datasource:
        master:
          url: jdbc:mysql://127.0.0.1:3306/master
          username: root
          password: 66668888
          driver-class-name: com.mysql.jdbc.Driver 
        slave_1:
          url: jdbc:mysql://127.0.0.1:3307/slave_1
          username: root
          password: 66668888
          driver-class-name: com.mysql.jdbc.Driver
        slave_2:
          url: ENC(xxxxx) # 内置加密
          username: ENC(xxxxx)
          password: ENC(xxxxx)
          driver-class-name: com.mysql.jdbc.Driver           

主庫預設為master,從庫命名的格式預設以_分割。

3,在方法或者類上使用@DS切換資料源

Spring進階:3步搞定MybatisPlus多資料源,詳細配置及原了解析

DS注解既可以寫在類上,也可以寫在方法上,方法上的優先級高于類。

如果沒有指定DS的屬性值或者沒有使用DS注解,就自動走master主庫。

通過以上3步,就可以輕松使用MP切換多資料源的能力了。當然,除了支援主從模式,還支援多主多從、多庫,混合模式。

原理探究

打開dynamic-datasource-spring-boot-starter.jar包,在spring.factories檔案中,可以看到配置了DynamicDataSourceAutoConfiguration啟動類。

Spring進階:3步搞定MybatisPlus多資料源,詳細配置及原了解析

打開DynamicDataSourceAutoConfiguration類,可以看到通過@AutoConfigureBefore注解,提前初始化了MP自己的DataSource資料源。

Spring進階:3步搞定MybatisPlus多資料源,詳細配置及原了解析

而DataSourceAutoConfiguration類的核心作用就是初始化DataSrouce,MP通過搶先配置的方式,使DataSource變成了自己指定的資料源。

除了初始化MP自己的資料源,DynamicDataSourceAutoConfiguration類還做了一些其他的初始化工作,比如DynamicDataSourceProperties配置,初始化DS注解的切面Advisor等。

初始化工作做完以後,接下來就是根據DS注解判斷走哪個資料源了。

DynamicDataSourceAnnotationInterceptor類是一個方法攔截器,它的invoke裡面有判斷DS key的操作。

Spring進階:3步搞定MybatisPlus多資料源,詳細配置及原了解析

在determineDatasourceKey方法中,會調用提前注入的DataSourceClassResolver類的findKey方法,判斷類或者方法上是否指定了DS注解。

Spring進階:3步搞定MybatisPlus多資料源,詳細配置及原了解析

在這個方法中,MP會将方法的判斷結果緩存下來,下次執行相同的類方法就可以直接緩存,進而大大提升查找效率。

擷取到dsKey以後,會将其設定在DynamicDataSourceContextHolder中的LOOKUP_KEY_HOLDER中,它是一個泛型為Deque<String>的ThreadLocal,為什麼設定成棧呢?官方給出的解釋是:

Spring進階:3步搞定MybatisPlus多資料源,詳細配置及原了解析

接下來就是擷取資料庫連結的AbstractRoutingDataSource類的getConnection方法,

Spring進階:3步搞定MybatisPlus多資料源,詳細配置及原了解析

而determineDataSource方法就會去擷取指定的資料源,

Spring進階:3步搞定MybatisPlus多資料源,詳細配置及原了解析

這裡的邏輯是:如果沒有指定DS,就走主庫,如果指定了DS,就根據DS的屬性值進行條件比對,看走哪個判斷分支。

擷取到connection連結之後,接下來就是執行真正的資料庫語句了。

以上就是一個常見的資料庫操作的流程,大體思路就是先找MP的啟動類,看看啟動類都做了哪些工作,之後再按照找資料源,找連結的思路,看MP是如何具體實作多資料源切換的操作的。

當然,MP多資料源還有其他的功能點,但整體來說,代碼邏輯并不是很複雜,大家可以通過debug對源碼進行梳理。

#頭條創作挑戰賽#

我是@程式員拾山,歡迎關注我,期待與大家一起學習成長,也感謝您的點贊和關注。

繼續閱讀