91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在mybatis plus中動態切換數據源

發布時間:2020-12-28 14:44:56 來源:億速云 閱讀:1952 作者:Leah 欄目:開發技術

怎么在mybatis plus中動態切換數據源?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

mybatis plus多數據源切換

mybatis plus多數據源切換使用注解 @DS
DS注解作為多數據源切點,具體實現作用主要由兩個類完成
DynamicDataSourceAnnotationAdvisor
DynamicDataSourceAnnotationInterceptor

DS多數據源切換實現

1.DynamicDataSourceAnnotationAdvisor類實現切面配置,其中AnnotationMatchingPointcut用于尋找切點,進入可看到支持類和方法的切點,多個切點會執行多次,根據代碼順序,方法的切點執行晚于類切點,所以方法的切點會覆蓋類,但是都會被執行

怎么在mybatis plus中動態切換數據源

怎么在mybatis plus中動態切換數據源

2.DynamicDataSourceAnnotationInterceptor 實現切面功能,匹配到切點后,根據切點值(數據源id)設置當前線程有效數據源私有變量,用于執行查詢時動態數據源能獲取,執行完畢會清楚此變量,此存儲功能由DynamicDataSourceContextHolder提供

怎么在mybatis plus中動態切換數據源

3.執行時動態數據源確定,mybatisplus動態數據源實現類為DynamicRoutingDataSource,其維護一個map保存所有配置的數據源,以數據源ID作為key,執行查詢時,獲取連接,交由spring事務管理器SpringManagedTransaction進行連接獲取,若當前存在連接則直接返回,不存在是創建連接,只有創建連接時,才有機會切換數據源,此處需要注意的是,同一事務下,使用的同一個sqlSession,執行查詢時使用的是同一個執行器executor,最終使用的是同一個事務管理器,所以獲取連接時無法創建新連接,mybatisplus切換數據源功能失效,代碼無法被執行

怎么在mybatis plus中動態切換數據源

此處邏輯較多,一筆帶過有點草率,后續附帶mybatisplus查詢過程,感興趣的老鐵一會在看。

4.動態數據源敲定,接第3步,若當前事務管理器還未創建連接,那就打開一個連接,使用DataSourceUtils獲取一個連接,入參為mybatisplus的動態數據源DynamicRoutingDataSource,一步步往下巴拉,忽略不需要代碼,最終執行到了這一句:
Connection con = dataSource.getConnection();
使用DynamicRoutingDataSource獲取連接,瞧,兜兜轉轉,最終怎么找連接,敲定數據源又交給了mybatisplus,getConnection方法在其父級AbstractRoutingDataSource中,使用this.determineDataSource().getConnection()獲取連接,.getConnection()是數據源獲取連接方法,那確定數據源顧名思義就是determineDataSource方法了,這個方法的實現就在DynamicRoutingDataSource中,來瞧瞧!是不是瞬間舒服了,根據第二部切面設置的數據源,這個返回對應的數據源。

怎么在mybatis plus中動態切換數據源

5.主要邏輯已經清楚了,那么來延伸下,如何手動切換數據源mybatisplus切換數據源主要是使用DynamicDataSourceContextHolder的線程獨享變量,那么如果沒有DS切點,無法自動切換數據源,需要切換數據源時就可以使用DynamicDataSourceContextHolder.setDataSourceLookupKey 設置數據源,使用完后再清除掉(默認數據源生效),這個方法同第4步所提的事務問題,存在事務則無法切換(壓根就不執行 只設置無法執行切換代碼),如果將要執行的代碼已存在切點,則執行前手動設置也是無效的,因為切點會覆蓋你的設置。

注:如果需要在事務存在的情況下切換數據源,則估計要覆蓋掉或替換掉spring的事務管理器,此處待后續再議。如果事務內仍需要切換數據源,則需要單獨定義service并設置切點,設置此切點的事務傳播行為為PROPAGATION__REQUIRES_NEW,則執行切面方法時單獨創建一個事務,數據源會自動切換。

mybatisplus執行查詢過程

現分析mybatisplus執行查詢過程

1.執行selectById方法,執行return this.baseMapper.selectById(id);經過springaop切面進行一系列巴拉巴拉的處理,最終進入mybatisplus PageMapperMethod類中執行execute方法,根據sql類型進行不同處理,分新增,修改,刪除,查詢,我們本次只關注查詢,查詢里也有很多東西。

可以看到此處提供多種返回值的查詢,有空返回值,多個,map,游標,及啥也不是。空值查詢猜測是另有處理器直接處理返回值,此處不做延伸了,有需要再議,回到按照ID查詢及進入啥也不是分支,本次查詢不是分頁查詢,直接進入selectOne ,result = sqlSession.selectOne(this.command.getName(), param); 這里的sqlSession是SqlSessionTemplate,執行selectOne時首先獲取sqlSession(默認為DefaultSelSession)

怎么在mybatis plus中動態切換數據源

2.獲取真正的sqlSession并執行selectOne查詢,首先使用事務管理器獲取緩存的sqlSession的持有者(sqlSession包裝類),不存在則創建并緩存注冊。

怎么在mybatis plus中動態切換數據源

怎么在mybatis plus中動態切換數據源

得到真正的sqlSession后,執行selectOne,發現還是執行的selectList,然后就是大眾寫法,size=1返回get(0),否則為空或者報錯結果集太多。

3.來看看selectList在干嘛,先獲取查詢語句相關的MappedStatement,然后使用執行器executor執行查詢 this.executor.query
執行器是啥?怎么來的?

執行器是sqlSession內部的一個屬性,sqlSession其實也是個外包裝,提供了一堆規范化的操作,但是并不直接實現這些操作,而是交給執行器,執行器來執行增刪改查,默認使用的是SimpleExecutor,就以他入手,SimpleExecutor繼承抽象類BaseExecutor,BaseExecutor實現了Executor接口,這個query就在BaseExecutor中:這里主要是獲取執行的sql,以及根據執行語句和入參來生成一個緩存的key,會緩存查詢結果,如果下次再來個一毛一樣的查詢 就直接用緩存了,不查了,這個就是mybatis的一級緩存,緩存使用的是一個封裝的類PerpetualCache,最終對應的就是一個map :
private Map<Object, Object> cache = new HashMap();

怎么在mybatis plus中動態切換數據源

怎么在mybatis plus中動態切換數據源

4.執行數據庫查詢queryFromDatabase -> doQuery,這里和spring一個習慣,真正做事情的都是doXXX前面都是鋪墊前戲,看的人云里霧里的
這個doQuery的實現在SimpleExecutor中,進入查看,
先創建了一個Statement,這個我知道,是jdbc里的東西,jdbc大概就是加載驅動,獲取連接,打開一個執行語句塊,然后執行獲取結果。具體這個東西學名和作用還是百度下吧:
Statement 對象用于把 SQL 語句發送到 DBMS。你只須簡單地創建一個 Statement 對象并且然后執行它,使用適當的方法執行你發送的 SQL 語句。
這個也就是jdbc層面的sqlSession了吧。

創建完Statement后就會執行查詢,先看來看Statement如何創建

5.Statement創建,創建第一步獲取connection,這個就涉及到數據源了吧,進入查看,使用事務管理器Transaction獲取連接,默認的事務管理器是SpringManagedTransaction,然后獲取數據源,最終創建或使用一個已有的連接并返回,進而創建出一個Statement,其他細節已無心再細究,不影響本次分析目的。

6.執行查詢,直接略過看最終執行處,doFinish-> query ,執行jdbc的PreparedStatement.execute,之后的代碼就先不看了,看意思就是將原始ResultSet結果集轉化為list。

怎么在mybatis plus中動態切換數據源

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

江达县| 林芝县| 乌苏市| 闸北区| 涞水县| 无极县| 武城县| 福建省| 南开区| 雅江县| 永新县| 安塞县| 调兵山市| 平安县| 二连浩特市| 金沙县| 湘西| 陈巴尔虎旗| 松滋市| 宣威市| 体育| 临汾市| 莒南县| 南城县| 喀喇沁旗| 黄浦区| 正蓝旗| 顺平县| 韩城市| 吉木萨尔县| 邢台县| 耿马| 四会市| 鸡东县| 玉屏| 海阳市| 疏附县| 花垣县| 高尔夫| 夏津县| 富顺县|