此文已由做者趙計剛薪受權網易雲社區發佈。html
歡迎訪問網易雲社區,瞭解更多網易技術產品運營經驗java
在實際開發中,咱們一個項目可能會用到多個數據庫,一般一個數據庫對應一個數據源。spring
代碼結構:數據庫
簡要原理:安全
1)DatabaseType列出全部的數據源的key---keyspringboot
2)DatabaseContextHolder是一個線程安全的DatabaseType容器,並提供了向其中設置和獲取DatabaseType的方法服務器
3)DynamicDataSource繼承AbstractRoutingDataSource並重寫其中的方法determineCurrentLookupKey(),在該方法中使用DatabaseContextHolder獲取當前線程的DatabaseTypemybatis
4)MyBatisConfig中生成2個數據源DataSource的bean---valueapp
5)MyBatisConfig中將1)和4)組成的key-value對寫入到DynamicDataSource動態數據源的targetDataSources屬性(固然,同時也會設置2個數據源其中的一個爲DynamicDataSource的defaultTargetDataSource屬性中)框架
6)將DynamicDataSource做爲primary數據源注入到SqlSessionFactory的dataSource屬性中去,而且該dataSource做爲transactionManager的入參來構造DataSourceTransactionManager
7)使用的時候,在dao層或service層先使用DatabaseContextHolder設置將要使用的數據源key,而後再調用mapper層進行相應的操做,建議放在dao層去作(固然也可使用spring aop+自定註解去作)
注意:在mapper層進行操做的時候,會先調用determineCurrentLookupKey()方法獲取一個數據源(獲取數據源:先根據設置去targetDataSources中去找,若沒有,則選擇defaultTargetDataSource),以後在進行數據庫操做。
一、假設有兩個數據庫,配置以下
application.properties
View Code
說明:在以前的配置的基礎上,只增長了上述的第二個數據源。
二、DatabaseType
View Code
做用:列舉數據源的key。
三、DatabaseContextHolder
View Code
做用:構建一個DatabaseType容器,並提供了向其中設置和獲取DatabaseType的方法
四、DynamicDataSource
View Code
做用:使用DatabaseContextHolder獲取當前線程的DatabaseType
五、MyBatisConfig
View Code
做用:
經過讀取application.properties文件生成兩個數據源(myTestDbDataSource、myTestDb2DataSource)
使用以上生成的兩個數據源構造動態數據源dataSource
@Primary:指定在同一個接口有多個實現類能夠注入的時候,默認選擇哪個,而不是讓@Autowire註解報錯(通常用於多數據源的狀況下)
@Qualifier:指定名稱的注入,當一個接口有多個實現類的時候使用(在本例中,有兩個DataSource類型的實例,須要指定名稱注入)
@Bean:生成的bean實例的名稱是方法名(例如上邊的@Qualifier註解中使用的名稱是前邊兩個數據源的方法名,而這兩個數據源也是使用@Bean註解進行注入的)
經過動態數據源構造SqlSessionFactory和事務管理器(若是不須要事務,後者能夠去掉)
六、使用
ShopMapper:
View Code
ShopDao:
View Code
注意:首先設置了數據源的key,而後調用mapper(在mapper中會首先根據該key從動態數據源中查詢出相應的數據源,以後取出鏈接進行數據庫操做)
ShopService:
View Code
ShopController:
View Code
補:其實DatabaseContextHolder和DynamicDataSource徹底能夠合爲一個類
參考:
http://www.cnblogs.com/lzrabbit/p/3750803.html
遺留:在實際開發中,一個dao類只會用到一個數據源,若是dao類中的方法不少的話,每個方法前邊都要添加一個設置數據源的一句話,代碼有些冗餘,可使用AOP切面。
具體的實現方式見 第九章 springboot + mybatis + 多數據源 (AOP實現)
不少朋友反映遇到數據源循環依賴的問題,能夠試一下將MyBatisConfig中的相關代碼換成這樣試試
View Code
或者看看評論區已經解決了問題的朋友的方案。
免費領取驗證碼、內容安全、短信發送、直播點播體驗包及雲服務器等套餐
更多網易技術、產品、運營經驗分享請點擊。
相關文章:
【推薦】 手把手帶你打造一個 Android 熱修復框架(上篇)
【推薦】 【工程實踐】服務器數據解析