MyBatis的二級緩存
二級緩存是SqlSessionFactory級別,通過同一個SqlSessionFactory創建的SqlSession查詢的結果會被 緩存;此后若再次執行相同的查詢語句,結果就會從緩存中獲取
二級緩存開啟的條件:
a>在核心配置文件中,設置全局配置屬性cacheEnabled="true",默認為true,不需要設置
b>在映射文件中設置標簽
c>二級緩存必須在SqlSession關閉或提交之后有效
d>查詢的數據所轉換的實體類類型必須實現序列化的接口
使二級緩存失效的情況:
兩次查詢之間執行了任意的增刪改,會使一級和二級緩存同時失效
開啟二級緩存:
第一步核心配置文件設置全局配置屬性cacheEnabled="true",默認為true,不需要設置
第二步配置文件:
第三步查詢的數據所轉換的實體類類型必須實現序列化的接口:
舉例:
不同的sqlSession查詢方法相同,參數相同,兩次查詢期間執行一次sqlSession關閉
查看結果:
可以看到不同sqlSession只執行了一次sql語句,說明二級緩存成功
不同的sqlSession查詢方法相同,參數相同,兩次查詢期間執行任意一次增刪改操作
@Test public void selectEmpById(){ SqlSession session = MybatisUtils.getSqlSession(); EmpMapper mapper1 = session.getMapper(EmpMapper.class); Emp emp1 = mapper1.selectEmpById(1); System.out.println("emp"+emp1); int i = mapper1.insertEmp(new Emp(12, "張氏", 29, "男", "yby@qq.com")); System.out.println("添加了"+i+"條數據"); SqlSession sqlSession = MybatisUtils.getSqlSession(); EmpMapper mapper = sqlSession.getMapper(EmpMapper.class); Emp emp = mapper.selectEmpById(1); System.out.println(emp); }
查看結果:
可以看到不同sqlSession執行同一方法期間執行了任意一次增刪改操作,執行力兩次sql語句,說明此時二級緩存失效
二級緩存的相關配置
在mapper配置文件中添加的cache標簽可以設置一些屬性:
eviction屬性:緩存回收策略
LRU(Least Recently Used) – 最近最少使用的:移除最長時間不被使用的對象。
FIFO(First in First out) – 先進先出:按對象進入緩存的順序來移除它們。
SOFT – 軟引用:移除基於垃圾回收器狀態和軟引用規則的對象。
WEAK – 弱引用:更積極地移除基於垃圾收集器狀態和弱引用規則的對象。 默認的是 LRU。
flushInterval屬性:刷新間隔,單位毫秒
默認情況是不設置,也就是沒有刷新間隔,緩存僅僅調用語句時刷新
size屬性:引用數目,正整數
代表緩存最多可以存儲多少個對象,太大容易導致內存溢出
readOnly屬性:只讀,true/false
true:只讀緩存;會給所有調用者返回緩存對象的相同實例。因此這些對象不能被修改。這提供了 很重要的性能優勢。
false:讀寫緩存;會返回緩存對象的拷貝(通過序列化)。這會慢一些,但是安全,因此默認是 false。
MyBatis緩存查詢的順序
先查詢二級緩存,因為二級緩存中可能會有其他程序已經查出來的數據,可以拿來直接使用。
如果二級緩存沒有命中,再查詢一級緩存
如果一級緩存也沒有命中,則查詢數據庫
SqlSession關閉之后,一級緩存中的數據會寫入二級緩存