自定義mybatis-plus插件解決分庫時sql增加庫名問題

????????項目中遇到了數(shù)據(jù)庫需要分庫的情況,已有功能都是按單庫實現(xiàn)的。因此升級過程中有個很重要的一項,sql查詢時要增加數(shù)據(jù)名參數(shù)。如果是sql值定義在mapper.xml中,那在接口增加一個數(shù)據(jù)庫名參數(shù)即可(工作量也不小),但是通過BaseMapper執(zhí)行的sql,沒有辦法手動增加庫名,所以必須找一個辦法既解決basemapper的問題最好也能一勞永逸。項目中用的是mybatis-plus(以下簡稱mp),我們需要在mp的生成sql動作到執(zhí)行sql動作中間將數(shù)據(jù)庫加到表名前面。mp有InnerInterceptor接口,增加庫名可以在beforePrepare方法可以實現(xiàn)。下面是具體實現(xiàn)方案。

? ? ? ? 首先自定義一個注解@SubDatabase,把所有需要分庫的表對應(yīng)的實體上都加上把需要分庫的實體都加上注解。項目啟動(實現(xiàn)CommandLineRunner)時,將注解掃出來,把實體名稱按駝峰轉(zhuǎn)下劃線改成表名,拼接一下,以備后面正則匹配用。

? ? ? ? 其次,定義一個ThreadLocal變量,再自定義個web過濾器HandlerInterceptorAdapter,在過濾器里面實現(xiàn)查詢用戶所歸屬的數(shù)據(jù)庫,并把庫名放到ThreadLocal變量中,便于后面增加庫名。這里代碼就不貼了,找地方放這個變量就行。

????????然后寫個方法,用正則表達(dá)式匹配把sql中的表名替換成帶庫名的表名,代碼如下圖所示。

? ? ? ? 可能有些同學(xué)會問為什么不直接匹配表名,要加上left join等操作匹配呢。這里主要是防止有些參數(shù)可能和表名一致,導(dǎo)致sql異常的問題。

? ? ? ? 最后自定義個InnerInterceptor,利用反射修改sql。

????????注意點,此方案適用于單數(shù)據(jù)源多數(shù)據(jù)庫場景,多數(shù)據(jù)源場景得根據(jù)具體情況調(diào)整。

????????如果各位有更好的方案,請多多指教,謝謝。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容