介紹
隨着業務的發展,除了拆分業務模塊外,數據庫的讀寫分離也是常見的優化手段。
方案使用了AbstractRoutingDataSource
和mybatis plugin
來動態的選擇數據源
選擇這個方案的原因主要是不需要改動原有業務代碼,非常友好
環境
首先,我們需要兩個數據庫實例,一為master,一為slave。
所有的寫操作,我們在master節點上操作
所有的讀操作,我們在slave節點上操作
先跑起來兩個pg的實例,其中15432端口對應的master節點,15433端口對應的slave節點:
實現
整個實現主要有3個部分:
- 配置兩個數據源
- 實現
AbstractRoutingDataSource
來動態的使用數據源 - 實現
mybatis plugin
來動態的選擇數據源
配置數據源
將數據庫連接信息配置到application.yml文件中
write寫數據源,對應到master節點的15432端口
read讀數據源,對應到slave節點的15433端口
將兩個數據源信息注入為DataSourceProperties
:
實現AbstractRoutingDataSource
spring提供了AbstractRoutingDataSource
,提供了動態選擇數據源的功能,替換原有的單一數據源后,即可實現讀寫分離:
AbstractRoutingDataSource
內部維護了一個Map<Object, Object>
的Map
在初始化過程中,我們將write、read兩個數據源加入到這個map
調用數據源時:determineCurrentLookupKey()方法返回了需要使用的數據源對應的key
當前線程需要使用的數據源對應的key,是在DataSourceHolder
類中維護的:
實現mybatis plugin
上面提到了當前線程使用的數據源對應的key,這個key需要在mybatis plugin
根據sql類型來確定 MybatisDataSourceInterceptor
類:
僅當未在事務中,並且調用的sql是select類型時,在DataSourceHolder中將數據源設為read
其他情況下,AbstractRoutingDataSource
會使用默認的write數據源
至此,項目已經可以自動的在讀、寫數據源間切換,無需修改原有的業務代碼
最后,提供demo使用依賴版本