天天看點

Java——Mybatis二級緩存一、什麼是二級緩存二、二級緩存原理三、開啟二級緩存 四、如何解決一級緩存中Spring和Mybatis中sqlSession關閉的問題? 四、問題

一、什麼是二級緩存

二級緩存是mapper級别的緩存,Mybatis預設是沒有開啟二級緩存。多個SqlSession去操作同一個Mapper的sql語句,多個SqlSession可以共用二級緩存,也就是說,二級緩存是跨SqlSession的,是以二級緩存的作用範圍更大。

UserMapper有一個二級緩存區域(按namespace分),其它mapper也有自己的二級緩存區域(按namespace分)。每一個namespace的mapper都有一個二級緩存區域,兩個mapper的namespace如果相同,這兩個mapper執行sql查詢到資料将存在相同的二級緩存區域中。

二、二級緩存原理

Java——Mybatis二級緩存一、什麼是二級緩存二、二級緩存原理三、開啟二級緩存 四、如何解決一級緩存中Spring和Mybatis中sqlSession關閉的問題? 四、問題

不同的sqlsession都要調用mapper下的sql語句發起資料庫請求。 

第一次調用mapper下的SQL去查詢使用者資訊。查詢到的資訊會存到該mapper對應的二級緩存區域内。

第二次調用相同namespace下的mapper映射檔案中相同的SQL去查詢使用者資訊。會去對應的二級緩存内取結果。

如果調用相同namespace下的mapper映射檔案中的增删改SQL,并執行了commit操作。此時會清空該namespace下的二級緩存。

sqlsession對象銷毀mapper中的二級緩存資料仍然存在。

三、開啟二級緩存

1、  在核心配置檔案SqlMapConfig.xml中加入以下内容(開啟二級緩存總開關):

cacheEnabled設定為 true

Java——Mybatis二級緩存一、什麼是二級緩存二、二級緩存原理三、開啟二級緩存 四、如何解決一級緩存中Spring和Mybatis中sqlSession關閉的問題? 四、問題

2、在映射檔案中,加入以下内容,開啟二級緩存:

Java——Mybatis二級緩存一、什麼是二級緩存二、二級緩存原理三、開啟二級緩存 四、如何解決一級緩存中Spring和Mybatis中sqlSession關閉的問題? 四、問題

3、實作序列化

由于二級緩存的資料不一定都是存儲到記憶體中,它的存儲媒體多種多樣,是以需要給緩存的對象執行序列化。

如果該類存在父類,那麼父類也要實作序列化。

Java——Mybatis二級緩存一、什麼是二級緩存二、二級緩存原理三、開啟二級緩存 四、如何解決一級緩存中Spring和Mybatis中sqlSession關閉的問題? 四、問題

禁用二級緩存

該statement中設定userCache=false可以禁用目前select語句的二級緩存,即每次查詢都是去資料庫中查詢,預設情況下是true,即該statement使用二級緩存。

Java——Mybatis二級緩存一、什麼是二級緩存二、二級緩存原理三、開啟二級緩存 四、如何解決一級緩存中Spring和Mybatis中sqlSession關閉的問題? 四、問題

重新整理二級緩存

Java——Mybatis二級緩存一、什麼是二級緩存二、二級緩存原理三、開啟二級緩存 四、如何解決一級緩存中Spring和Mybatis中sqlSession關閉的問題? 四、問題

四、如何解決一級緩存中Spring和Mybatis中sqlSession關閉的問題?

Spring和MyBatis整合時, 每次查詢之後都要進行關閉sqlSession,關閉之後資料被清空。是以spring整合之後,如果沒有事務,一級緩存是沒有意義的。而如果開啟二級緩存的話,關閉sqlsession後,會把該sqlsession一級緩存中的資料添加到namespace的二級緩存中。這樣,緩存在sqlsession關閉之後依然存在。

四、問題

二級緩存是建立在同一個namespace下的,如果對表的操作查詢可能有多個namespace,那麼得到的資料就是錯誤的。

舉個例子:

訂單和訂單詳情,orderMapper、orderDetailMapper。在查詢訂單詳情時我們需要把訂單資訊也查詢出來,那麼這個訂單詳情的資訊被二級緩存在orderDetailMapper的namespace中,這個時候有人要修改訂單的基本資訊,那就是在orderMapper的namespace下修改,他是不會影響到orderDetailMapper的緩存的,那麼你再次查找訂單詳情時,拿到的是緩存的資料,這個資料其實已經是過時的。

根據以上,想要使用二級緩存時需要想好兩個問題:

  • 對該表的操作與查詢都在同一個namespace下,其他的namespace如果有操作,就會發生資料的髒讀。
  • 對關聯表的查詢,關聯的所有表的操作都必須在同一個namespace。

參考部落格:

https://blog.csdn.net/Searchin_R/article/details/85220734

https://blog.csdn.net/hd243608836/article/details/78654984