1. 程式人生 > >MyBatis 一級快取避坑

MyBatis 一級快取避坑

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 的配置檔案中,新增以下配置:

 驗證程式碼和上面的一樣不變。

輸出:

可以看到,即使是同樣的查詢,每次查詢都是直接讀取資料庫了。

避坑完畢。

快取是不可能不要快取的,這個時候,就需要使用快取中介軟體了,由快取中介軟體管理快取。