MyBatis缓存机制之一级缓存
MyBatis緩存機制之一級緩存
前言
????????MyBatis內部封裝了JDBC,簡化了加載驅動、創建連接、創建statement等繁雜的過程,是我們常見的持久性框架。緩存是在計算機內存中保存的臨時數據,讀取時無需再從磁盤中讀取,從而減少數據庫的查詢次數,提高執行效率。Mybatis提供了一級緩存和二級緩存的支持,默認情況下只開啟一級緩存。本次將帶著大家深入了解Mybatis的一級緩存機制。
介紹
????????當我們訪問數據庫時,Mybatis會創建出一個SqlSession對象開啟一次數據庫會話。在這次會話中,我們可能會執行多次相同的查詢語句,如果不采取措施,每一次查詢都會訪問數據庫,造成資源的浪費。為了優化這部分場景,Mybatis提供了一級緩存的方案,如果是相同的SQL語句,會優先命中一級緩存,避免直接對數據庫進行查詢。具體執行過程如下圖所示。
?????????每個SqlSession中都持有Executor執行器,每個Excutor中有一個LocalCache緩存。Mybatis根據當前執行的SQL生產MappedStatement,在緩存中進行查詢,如果緩存命中的話,直接返回結果給用戶,如果緩存沒有命中,查詢數據庫,結果寫入LocalCache,再返回結果給用戶。具體實現類的類關系圖如下所示:
?
源碼分析
我們將對MyBatis的源碼進行分析,深入理解底層原理。
????????SqlSession: SqlSession是應用程序與持久層執行交互操作的單線程對象,代表著一個資源的啟用,包含所有執行SQL操作的方法。默認實現類是DefaultSqlSession。
????????主要作用:1、獲取Mapper接口;2、發送SQL給數據庫;3、控制數據庫事務
?????????Executor執行器:Executor定義了查詢、更新、事務、緩存操作相關的接口方法,由SqlSession依賴,并受其調度與管理。核心功能是調度執行SQL。在Executor內部完成對LocalCache的查詢和寫入。
?
?Cache:Mybatis中的Cache接口,提供了緩存的基本操作。
?????????PerpetualCache是對Cache接口最基本的實現,其原理非常簡單,內部持有HashMap,對一級緩存的操作實則是對HashMap的操作。如下代碼所示:
????????客戶端與數據庫的交互,首先通過DefaultSqlSessionFactory開啟SqlSession:
?????????????????在初始化SqlSession時,會通過configuration類創建一個新的Executor:
?????????SqlSession創建完畢后,根據不同類型的Statement,SqlSession會執行對應的方法。比如Select語句,最終會執行到selectList方法
????????SqlSession把具體的查詢交給Executor去執行。如果只開啟了一級緩存的話,首先會進入BaseExecutor的query方法。代碼如下所示:
????????會根據傳入的參數生成CacheKey作為唯一標識,進入方法,查看具體的生成邏輯:
????????在上述的代碼中,將MappedStatement的Id、SQL的offset、SQL的limit、SQL本身以及SQL中的參數傳入了CacheKey這個類,最終構成CacheKey。在CacheKey的update方法中,會進行一個hashcode和checksum的計算,同時把傳入的參數添加進updatelist中。如下代碼所示:
?只要兩條SQL的下列五個值相同,即可以認為是相同的SQL。
Statement Id + Offset + Limmit + Sql + Params
如果在LocalCache查不到的話,就會查詢數據庫,并將結果寫入至緩存。
?????????如果是insert/update/delete方法,統一都會走SqlSession的update流程,同樣委托執行器執行SQL。
????????執行方法如下,我們可以發現每次執行update前都會清空LocalCache。所以當發生修改操作時,一級緩存會失效,防止了數據臟讀。
?總結
1、一級緩存LocalCache只是BaseExecutor的一個字段。所以,當SqlSession的生命周期結束時,一級緩存也會被回收。
2、一級緩存由PerpetualCache實現,其內部通過HashMap完成對緩存的讀寫操作,所以本質上講,一級緩存其實是通過HashMap實現的,Map中的key是由MappedStatement生成CacheKey,來確保查詢的唯一性。
3、MyBatis的一級緩存最大范圍是SqlSession內部,有多個SqlSession或者分布式的環境下,數據庫寫操作會引起臟數據,建議設定緩存級別為Statement。
總結
以上是生活随笔為你收集整理的MyBatis缓存机制之一级缓存的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SCI论文及期刊查询
- 下一篇: python游戏模块 - 26 小项目-