浅谈MyBatis二级缓存
一、二級緩存介紹
我們知道MyBatis 提供了一級緩存來減輕數據庫的壓力,但是一級緩存是一個SqlSession(會話)級別的緩存,這也就意味著一級緩存的適用范圍比較小。在一級緩存的基礎上,MyBatis 提供了二級緩存機制,二級緩存是一個namespace級別的緩存,相對于一級緩存而言,二級緩存允許跨SqlSession工作,因此二級緩存的作用范圍更大。
有關一級緩存可參考博文:
https://blog.csdn.net/codejas/article/details/79545367
二、二級緩存運行機制
每個SqlSession在執行查詢操作的時候,都會將查詢的結果放在當前會話的一級緩存中。如果當前會話關閉,一級緩存中的數據會被保存在二級緩存中。因此二級緩存是在一級緩存的基礎上進行擴展的,不同的namespace查出的數據都會將數據存在自己對應的緩存中,這些緩存信息使用Map存儲。
需要注意的地方是:MyBatis 在開啟二級緩存的情況下,如果發出了一條SQL 查詢語句,會先向二級緩存中查詢是否有對應的緩存數據,如果沒有再接著查詢一級緩存中的數據,如果一級緩存中也沒有對應的緩存數據,才會向數據庫發送SQL。下面附一張蹩腳的二級緩存運行機制圖。
三、實現二級緩存的步驟
1.在MyBatis 全局配置文件中開啟二級緩存的配置,默認也是開啟的,建議自己設置為開啟的。
2.在對應的SQL 映射文件中加入<cache/>標簽。
3.將返回的JavaBean 數據類型的類實現Serializable(序列化)接口。
知道了二級緩存的實現方式,下面就來體會一下二級緩存帶來的作用。
四、二級緩存初體驗
MyBatis 全局配置文件:
<!-- 配置二級緩存,默認也是開啟的,建議手動設置一下 --><setting name="cacheEnabled" value="true"/>POJO 實現序列化接口:
package com.jas.mybatis.bean;import java.io.Serializable;public class Department implements Serializable{private Integer id;private String departmentName;//省略get、set 與toString 方法 }mapper 接口:
Department getDeptById(Integer id);SQL 映射文件:
<!-- 在需要使用二級緩存的SQL 映射文件中添加 <cache/> 標簽相關的一些參數介紹:eviction:緩存回收策略flushInterval:緩存刷新時間,單位是毫秒,默認不刷新size:可存儲多少個緩存對象,只能是正整數,合理的設置可以防止內存泄漏readOnly:是否只讀--><cache/><select id="getDeptById" resultType="com.jas.mybatis.bean.Department">SELECT id, dept_name departmentName FROM t_dept WHERE id = #{id}</select>測試代碼:
// 用于返回SqlSessionFactory 對象private SqlSessionFactory getSqlSession() throws IOException {String resource = "mybatis-config.xml";InputStream is = Resources.getResourceAsStream(resource);return new SqlSessionFactoryBuilder().build(is); }@Testpublic void secondLevelTest() throws IOException {SqlSessionFactory sqlSessionFactory = getSqlSession();//創建兩個不同的會話SqlSession sqlSession1 = sqlSessionFactory.openSession();SqlSession sqlSession2 = sqlSessionFactory.openSession();DepatmentMapper depatmentMapper1 = sqlSession1.getMapper(DepatmentMapper.class);DepatmentMapper depatmentMapper2 = sqlSession2.getMapper(DepatmentMapper.class);Department department1 = depatmentMapper1.getDeptById(1);System.out.println(department1); // 關閉當前的會話1, 否則二級緩存不起作用sqlSession1.close();Department department2 = depatmentMapper2.getDeptById(1);System.out.println(department2);// 關閉會話2sqlSession2.close();}測試結果:
當會話1 查詢結束并關閉后,我們使用另一個會話執行與會話1 相同的SQL 查詢語句,發現并沒有發送SQL 語句,因為緩存中已經保存了要查詢的數據,這次直接從緩存中獲取數據,這就是MyBatis 提供的跨會話級別(SqlSession)的二級緩存機制。
五、與緩存相關的設置
1.可以在MyBatis 全局配置文件中的setting標簽中配置cacheEnabled屬性,表示是否啟用二級緩存機制,不過不影響一級緩存。
2.select查詢標簽中可以設置useCache屬性,配置是否使用二級緩存,默認一級緩存是一直生效的。
3.sqlSession.clearCache();方法默認只清除一級緩存中的數據。
4.可以在每個增刪改的標簽中設置flushCache屬性,設置為true后,如果執行了該增刪改操作,則一級緩存與二級緩存中的數據都會清空。
六、總結
這篇博客主要對MyBatis 中的二級緩存機制做了介紹,在實際開發的過程中,MyBatis 提供的二級緩存機制好像并沒有獲得開發人員的青睞。原因是二級緩存是一個namespace級別的緩存,如果在不同的namespace下操作同一SQL 語句,可能導致緩存中的數據不正確。在進行多表聯查的時候,也可能會導致二級緩存中的數據不正確。所以在實際的開發過程中要慎用二級緩存。
總結
以上是生活随笔為你收集整理的浅谈MyBatis二级缓存的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浅谈MyBatis一级缓存
- 下一篇: 怎么移动电脑桌面图标 移动电脑桌面图标的