MyBatis 緩存結構

MyBatis 緩存結構

點擊右上角【關注】發哥微課堂頭條號,get更多相關技能~


0x00:什麼是緩存

在網站的各種業務中,幾乎離不開對數據庫的增刪改查操作,當一個功能點經常需要從數據庫讀取數據時,訪問量大的網站,對數據庫會造成很大的壓力,這時候,為了緩解數據庫的壓力,提高運行速度,則緩存就是其中的一個解決辦法。

緩存就是第一次用戶發來的請求時,將請求的結果放到緩存中,之後其他用戶發來同一個請求時,就會直接從緩存中讀取第一次保存的數據,減小數據庫壓力的同時也提高了查詢速度。

0x01:MyBatis 中的緩存

MyBatis 中的緩存有兩種,一種是一級緩存,另外一種是二級緩存。

一級緩存其實就是 SqlSession 級別的緩存,在操作數據庫的時候,每個 SqlSession 類的實例對象中都有一個數據結構 HashMap 可以用於存儲緩存數據。不同的 SqlSession 類的實例對象緩存的數據區域 HashMap 是互不影響的。

二級緩存就是 Mapper 級別的緩存,多個 SqlSession 類的實例對象操作同一個 Mapper 配置文件中的 sql 句,多個 SqlSession 類的實例對象可以共用二級緩存,二級緩存是跨 SqlSession 的。

0x02:MyBatis 緩存模式

MyBatis 緩存結構

從以上圖可以看出來,每個 SqlSession 類的實例對象自身有一個一級緩存,而查詢同一個 Mapper 映射文件的 SqlSession 類的實例對象之間又共享同一個二級緩存。

0x03:MyBatis 一級緩存

一級緩存是存在於每一個 SqlSession 的實例對象中的,當我們第一次去查詢某一個數據時,SqlSession 類的實例對象就會將這次查詢到的數據放到一級緩存中,在沒有對該數據進行增加或者修改或者刪除時,以後的查詢均會從緩存中讀取,而不會在重新連接數據庫做查詢。其原理圖如下:

MyBatis 緩存結構

上圖畫出了 MyBatis 一級緩存的原理,當第一查詢 id 為 1 的用戶時,因為緩存中沒有相應的數據,所以回去數據庫進行查詢,然後將查詢到的結果放到一級緩存中,隨後查詢時,均會到緩存中讀取,而不會再去數據庫中查詢。

當有修改、添加、和刪除的操作時,就會把緩存中的原有數據進行清空,目的是為了保持緩存中的數據是最新的,避免數據髒讀。當進行過修改、添加或刪除時,因為緩存數據已經被清空,所以下一次的操作會去數據庫查詢,然後再放到緩存中。

0x04:MyBatis 二級緩存

一級緩存是基於同一個 SqlSession 類的實例對象的,有時候查詢操作的方法會封裝到一個 service 方法中,當查詢操作完畢後,service 方法就會結束,這時候 SqlSession 類的實例化對象就關閉了,也就意味著一級緩存會被清空(因為一級緩存是基於 SqlSession 類的實例對象的)。如果再次調用 service 去查詢同一個信息時,就會重新打開一個 SqlSession 類的實例對象,由於一級緩存中這時候是空的,所以便無法再從緩存中獲取相關信息。

這時候就可以使用二級緩存,二級緩存是基於 Mapper 的,當有多個 SqlSession 類的實例對象去加載同一個 Mapper 文件,並執行其中的 sql 配置時,他們便會去共同使用一個 Mapper 緩存。二級緩存原理同一級緩存類似,如下圖:

MyBatis 緩存結構

二級緩存相對於一級緩存來說範圍會更大,其多個 SqlSession 類的實例對象回去共享一個 Mapper。一個 Mapper 都有自己的一個二級緩存區域,其中是按照 namespace 來劃分的,當兩個或多個 Mapper 的 namespace 相同時,那麼這些 Mapper 所執行的 sql 就會被緩存到同一個二級緩存中。

0x05:如何開啟二級緩存

一級緩存是默認開啟的,而二級緩存則需要手動開啟,首先需要在 MyBatis 的全局配置文件 SqlMapConfig.xml 中配置 setting 屬性,設置 cacheEnabled 為 true,代碼如下:

value="true"/>

因為二級緩存是基於 Mapper 文件的,所以第二步就需要在相應的 Mapper 文件中做配置,只需要添加一個 標籤即可,代碼如下:

0x06:總結

一級緩存是基於 SqlSession,二級緩存是基於 Mapper 的,在二級緩存中是以 namespace 為單位的,不同 namespace 下的操作互不干擾。使用二級緩存要注意的是,要保證該 Mapper 下的數據不會在其他的 Mapper 文件中有緩存,否則會得到不正確的結果,如果必須要使用,建議使用攔截器判斷執行 sql 涉及到哪些表,然後把相關表的緩存清空。


分享到:


相關文章: