MyBatis 一級快取避坑
阿新 • • 發佈:2019-02-01
MyBatis 一級快取(MyBaits 稱其為 Local Cache)無法關閉,但是有兩種級別可選:
package org.apache.ibatis.session; /** * @author Eduardo Macarron */ public enum LocalCacheScope { SESSION, //session 級別的快取
STATEMENT //statement 級別的快取 }
1)session 級別的快取
在同一個 sqlSession 內,對同樣的查詢將不再查詢資料庫,直接從快取中。
驗證程式碼:
public static void main(String[] args) throws IOException {
InputStream inputStream = new ClassPathResource("mybatis.xml").getInputStream();
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
System.out.println(mapper.get(1L));
System.out.println("-------------------");
System.out.println(mapper.get(1L));
}
輸出:
日誌輸出可以看到,第一次查詢通過資料庫查詢,第二次則沒有,直接通過快取讀取。
坑:這種快取策略有一個坑,在服務叢集時就會出現問題。
假設現在有一個服務叢集,有兩個節點。
首先,兩個節點都進行了同樣的查詢,兩個節點都有自己的一級快取,後續同樣的查詢,兩個節點將不再查詢資料庫。
如果此時節點 1 執行了 update 語句,那麼節點 1 的一級快取會被重新整理,而節點 2 的一級快取不會改變。
2)statement 級別的快取
避坑: 為了避免這個問題,可以將一級快取的級別設為 statement 級別的,這樣每次查詢結束都會清掉一級快取。MyBatis 原始碼如下:
在 MyBatis 的配置檔案中,新增以下配置:
驗證程式碼和上面的一樣不變。
輸出:
可以看到,即使是同樣的查詢,每次查詢都是直接讀取資料庫了。
避坑完畢。
快取是不可能不要快取的,這個時候,就需要使用快取中介軟體了,由快取中介軟體管理快取。