Mybatis 的一級緩存與二級緩存

String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//創建 SqlSessionFactory 
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
inputStream.close();
//創建 SqlSession 
SqlSession session1 = sqlSessionFactory.openSession();
TUserMapper userMapper1 = session1.getMapper(TUserMapper.class);
List<TUser> list1 = userMapper1.selectByEmailAndSex(email, sex);

一級緩存

一級緩存默認會啓用,想要關閉一級緩存可以在 select 標籤上配置 flushCache="true"

一級緩存存在於 SqlSession 的生命週期中,在一個 SqlSession 中查詢時, MyBatis 會把以下信息通過算法生成鍵值

  • namespace.id
  • 指定查詢結果集的範圍(分頁信息)
  • 查詢所使用的 SQL 語句
  • 用戶傳遞給 SQL 語句的實際參數值

將鍵值和查詢結果存入一個 Map 對象中。如果在同一個 SqlSession 中執以上四點完全一致,那麼通過算法會生成相同的鍵值,當 Map 中已經存在該鍵值時,則會返中緩存中的對象。

任何的 INSERT、 UPDATE、DELETE 操作都會清空一級緩存。

SqlSession :代表一次數據庫連接,一般通過調用 Mapper 訪問數據庫,也可以直接發送 SQL 執行。線程不安全,要保證線程獨享(方法級)。

二級緩存

二級緩存存在於 SqlSessionFactory 的生命週期中,可以理解爲跨 SqlSession;緩存是以 namespace(在 Mapper.xml 文件中配置)爲單位的,不同 namespace下的操作互不影響。

setting 參數 cacheEnabled,這個參數是二級緩存的全局開關,默認值是 true,如果把這個參數設置爲 false,即使有後面的二級緩存配置,也不會生效。

開啓二級緩存,在 Mapper.xml 文件中配置:

<cache eviction=“LRU" flushInterval="60000" size="512" readOnly="true"/> 

這段配置有如下意義:
Mapper.xml 中的所有 select 語句將會被緩存。
Mapper.xml 中的所有 insert,update 和 delete 語句會刷新緩存。
緩存會使用 Least Recently Used(LRU,最近最少使用的) 算法來回收。
緩存刷新間隔 60000 ms。
緩存會存儲列表集合或對象(無論查詢方法返回什麼)的 512個引用。
緩存會被視爲是隻讀的緩存。

使用二級緩存容易岀現髒讀,建議避免使用二級緩存,在業務層使用可控制的緩存代替更好。

爲什麼出現髒讀?
因爲不同的 Mapper.xml 可以操作同一張表,而不同的 Mapper.xml 對應不同的緩存。如果用一個 Mapper.xml 對一張表進行了增刪改,只會刷新自己的二級緩存,不會刷新另一個 Mapper.xml 的二級緩存。

結構圖

在這裏插入圖片描述
圖中,namespaceB 和 namespaceC 共用了一個二級緩存,因爲是可以這樣配置的:
<cache-ref namespace=""/>

如果兩個 Mapper.xml 裏面所包含的表,不會在另外的 Mapper.xml 裏出現,那麼它們就可以通過上面的配置,共用一個二級緩存。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章