
Java面試經常問到Mybatis一級快取和二級快取,今天就給大家重點詳解Mybatis一級快取和二級快取原理與區別@mikechen
Mybatis快取
快取就是記憶體中的資料,常常來自對資料庫查詢結果的保存,使用快取可以避免頻繁與資料庫進行互動,從而提高查詢回應速度,
MyBatis 提供了對快取的支持,分為一級快取和二級快取,如下圖所示:

我們先大致了解下MyBatis一級快取與MyBatis 二級快取:
一級快取:SqlSession級別的快取,快取的資料只在SqlSession內有效,
二級快取:mapper級別的快取,同一個namespace公用這一個快取,所以對SqlSession是共享的,二級快取需要我們手動開啟,
下面我們再分別詳解兩者的原理與區別,
Mybatis一級快取
1.為什么需要Mybatis一級快取
當我們使用Mybatis進行資料庫的操作時候,會創建一個SqlSession來進行一次資料庫的會話,會話結束則關閉SqlSession物件,
如果我們很有可能多次查詢完全相同的sql陳述句,每一次查詢都查詢一次資料庫,那查詢資料庫代價是比較大的,這會導致系統的資源浪費,
為了解決這個問題,Mybatis對每一次會話都添加了快取操作,不用相同的SQL每次都需要查詢資料庫,這就是Mybatis一級快取的作用,
2.Mybatis一級快取的實作
我們知道對SqlSession的操作,mybatis內部都是通過Executor來執行的,Executor的生命周期和SqlSession是一致的,
Mybatis在Executor中創建了本地快取(一級快取),如下圖所示:

大致的流程如下:
第一次查詢用戶id資訊,先去快取中查詢是否有,如果沒有,從資料庫中查詢用戶資訊,得到用戶資訊后在將用戶資訊儲存到一級快取中,
如果sqlSession去執行commit操作(插入、更新、洗掉),清空sqlSession中的一級快取,保證快取中始終保存的是最新的資訊,避免臟讀,
第二次查詢用戶id資訊,先去快取中查詢,如快取中有,直接從快取中獲取,
注意:兩次查詢須在同一個sqlsession中完成,否則將不會走mybatis的一級快取,
在mybatis與spring進行整合開發時,事務控制在service中進行,重復呼叫兩次servcie將不會走一級快取,因為在第二次呼叫時session方法結束,SqlSession就關閉了,
3.Mybatis一級快取配置
mybatis一級快取的范圍有SESSION和STATEMENT兩種,默認是SESSION,
如果不想使用一級快取,可以把一級快取的范圍指定為STATEMENT,這樣每次執行完一個Mapper中的陳述句后都會將一級快取清除,
如果需要更改一級快取的范圍,可以在Mybatis的組態檔中,在下通過localCacheScope指定,
<setting name="localCacheScope" value="https://www.cnblogs.com/mikechenshare/p/STATEMENT"/>
Mybatis二級快取
1.為什么需要Mybatis二級快取?
MyBatis 一級快取最大的共享范圍就是一個SqlSession內部,那么如果多個 SqlSession 需要共享快取,則需要開啟二級快取,
2.Mybatis二級快取的實作
開啟二級快取后,會使用 CachingExecutor 裝飾 Executor,進入一級快取的查詢流程前,先在 CachingExecutor 進行二級快取的查詢,具體的作業流程如下所示,

二級快取開啟后,同一個 namespace 下的所有操作陳述句,都影響著同一個 Cache,即二級快取被多個 SqlSession 共享,是一個全域的變數,
當開啟快取后,資料的查詢執行的流程就是 二級快取 -> 一級快取 -> 資料庫,
MyBatis 是默認關閉二級快取的,因為對于增刪改操作頻繁的話,那么二級快取形同虛設,每次都會被清空快取,
Mybatis一級快取與二級快取的區別
1)一級快取 Mybatis的一級快取是指SQLSession,一級快取的作用域是SQlSession, Myabits默認開啟一級快取,
在同一個SqlSession中,執行相同的SQL查詢時;第一次會去查詢資料庫,并寫在快取中,第二次會直接從快取中取, 當執行SQL時候兩次查詢中間發生了增刪改的操作,則SQLSession的快取會被清空,
每次查詢會先去快取中找,如果找不到,再去資料庫查詢,然后把結果寫到快取中, Mybatis的內部快取使用一個HashMap,key為hashcode+statementId+sql陳述句,Value為查詢出來的結果集映射成的java物件, SqlSession執行insert、update、delete等操作commit后會清空該SQLSession快取,
2) Mybatis二級快取是默認不開啟的,作用于一個Application,是Mapper級別的,多個SqlSession使用同一個Mapper的sql能夠使用二級快取,
以上
作者簡介
陳睿|mikechen,10年+大廠架構經驗,《BAT架構技術500期》系列文章作者,分享十余年架構經驗以及面試心得!
閱讀mikechen的互聯網架構更多技術文章合集
Java并發|JVM|MySQL|Spring|Redis|分布式|高并發|架構師
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/509242.html
標籤:Java
上一篇:樹的基本概念介紹
