天天看點

mybatis: 利用多資料源實作分庫存儲

spring中有一個AbstractRoutingDataSource的抽象類可以很好的支援多資料源,我們隻需要繼續它即可。

很簡單,就一個方法。其中DBContext的代碼如下:

這裡我模拟了一個分庫的場景:假設一個應用允許使用者注冊,但是使用者數量太多,全都放在一個資料庫裡,記錄過多,會導緻資料庫性能瓶頸,比較容易想到的辦法,把使用者的資料分散到多個資料庫中儲存(注:可能馬上有同學會說了,分開存了,要查詢所有使用者怎麼辦?這确實是分庫帶來的一個弊端,但也有相應的解決方案,本文先不讨論這個,以免跑題)。

假設我們有二個資料庫,裡面的表結構完全相同,有一張表T_USER用于儲存使用者資料,問題來了,如果有N個使用者要注冊,id分别是1、2、3...,服務端接到參數後,怎麼知道把這些資料分别插入到這二個庫中,必然要有一個規則 ,比較簡單的辦法就是取模,是以上面的getDBKeyByUserId就是幹這個的。

然後是jdbc的屬性配置檔案:

接下來是spring的配置檔案:

mybatis: 利用多資料源實作分庫存儲
mybatis: 利用多資料源實作分庫存儲

View Code

關鍵的是parentDataSource,dataSource1,dataSource2,dataSource這幾個bean的配置,一看就懂。

服務端的核心代碼:

注意:25,32行在調用mybatis操作資料庫前,先根據需要切換到不同的資料庫,然後再操作。 

運作完成後,可以看下db_1,db_2這二個資料庫,确認資料是否已經分散存儲到每個庫中:

mybatis: 利用多資料源實作分庫存儲

  

如果不喜歡在代碼裡手動切換db,也可以用注解的方式自動切換,比如:我們又增加了一個db_main

然後在spring配置檔案裡,要做些調整:

注意:67-81行,主要是增加了一個單獨的sqlSessionFactoryMain,然後将一個新的MapperScannerConfigurer關聯到它。

新庫裡對應表的Mapper類可以這麼寫:

注解裡name對應的值,必須與剛才spring檔案裡新增的MapperScannerConfigurer對應。

這樣,服務層就可以省去手動切換的代碼了,即:

上述二種方式可以共存在同一個項目中,個人建議:如果分庫的表結構相同,且表數量較多,第1種手動切換的方式比較适合,這樣mapper類不用重複建多個,如果分庫的表結構完全不同,第2種比較合适,因為表結構不同,mapper肯定也不同,是以mapper多個是無法避免的,這時候就甯可加點配置,代碼中就不用手動切換,可以省事點。