Spring進(jìn)階:三步搞定MybatisPlus多數(shù)據(jù)源,詳細(xì)配置及原理解析
前言
MybatisPlus(MP)作為mybatis的增強工具,提供了配置多數(shù)據(jù)源的擴展,通過簡單的幾步配置,即可使用注解輕松切換數(shù)據(jù)源。
以下是dynamic-datasource提供的功能列表:
使用方法
1、引入
dynamic-datasource-spring-boot-starter。
2、配置多數(shù)據(jù)源。
主庫默認(rèn)為master,從庫命名的格式默認(rèn)以_分割。
3、在方法或者類上使用@DS切換數(shù)據(jù)源
?DS注解既可以寫在類上,也可以寫在方法上,方法上的優(yōu)先級高于類。
如果沒有指定DS的屬性值或者沒有使用DS注解,就自動走master主庫。
通過以上3步,就可以輕松使用MP切換多數(shù)據(jù)源的能力了。當(dāng)然,除了支持主從模式,還支持多主多從、多庫,混合模式。
原理探究
打開dynamic-datasource-spring-boot-starter.jar包,在spring.factories文件中,可以看到配置了DynamicDataSourceAutoConfiguration啟動類。
打開DynamicDataSourceAutoConfiguration類,可以看到通過@AutoConfigureBefore注解,提前初始化了MP自己的DataSource數(shù)據(jù)源。
而DataSourceAutoConfiguration類的核心作用就是初始化DataSrouce,MP通過搶先配置的方式,使DataSource變成了自己指定的數(shù)據(jù)源。
除了初始化MP自己的數(shù)據(jù)源,DynamicDataSourceAutoConfiguration類還做了一些其他的初始化工作,比如DynamicDataSourceProperties配置,初始化DS注解的切面Advisor等。
初始化工作做完以后,接下來就是根據(jù)DS注解判斷走哪個數(shù)據(jù)源了。
DynamicDataSourceAnnotationInterceptor類是一個方法攔截器,它的invoke里面有判斷DS key的操作。
在determineDatasourceKey方法中,會調(diào)用提前注入的DataSourceClassResolver類的findKey方法,判斷類或者方法上是否指定了DS注解。
在這個方法中,MP會將方法的判斷結(jié)果緩存下來,下次執(zhí)行相同的類方法就可以直接緩存,從而大大提升查找效率。
獲取到dsKey以后,會將其設(shè)置在DynamicDataSourceContextHolder中的LOOKUP_KEY_HOLDER中,它是一個泛型為Deque<String>的ThreadLocal,為什么設(shè)置成棧呢?官方給出的解釋是:
接下來就是獲取數(shù)據(jù)庫鏈接的AbstractRoutingDataSource類的getConnection方法,
而determineDataSource方法就會去獲取指定的數(shù)據(jù)源,
這里的邏輯是:如果沒有指定DS,就走主庫,如果指定了DS,就根據(jù)DS的屬性值進(jìn)行條件匹配,看走哪個判斷分支。
獲取到connection鏈接之后,接下來就是執(zhí)行真正的數(shù)據(jù)庫語句了。
以上就是一個常見的數(shù)據(jù)庫操作的流程,大體思路就是先找MP的啟動類,看看啟動類都做了哪些工作,之后再按照找數(shù)據(jù)源,找鏈接的思路,看MP是如何具體實現(xiàn)多數(shù)據(jù)源切換的操作的。
當(dāng)然,MP多數(shù)據(jù)源還有其他的功能點,但整體來說,代碼邏輯并不是很復(fù)雜,大家可以通過debug對源碼進(jìn)行梳理。