1. 程式人生 > 實用技巧 >MyBatis 快取機制

MyBatis 快取機制

MyBatis 快取機制

簡介

MyBatis 包含一個非常強大的查詢快取特性,它可以非常方便地配置和定製。快取可以極大的提升查詢效率.
MyBatis系統中預設定義了兩級快取:一級快取、二級快取

  1. 預設情況下,只有一級快取(SqlSession級別的快取,也稱為本地快取)開啟。
  2. 二級快取需要手動開啟和配置,他是基於namespace級別的快取。

一級快取

  1. 一級快取(local cache), 即本地快取, 作用域預設為sqlSession。同一次會話期間只要查詢過的資料都會儲存在當前SqlSession的一個Map中。

  2. 級快取失效的幾種情況
    不同的SqlSession對應不同的一級快取
    同一個SqlSession但是查詢條件不同
    同一個SqlSession兩次查詢期間執行了任何一次增刪改操作
    同一個SqlSession兩次查詢期間手動清空了快取

@Test

     public void testFirstCache() throws Exception {


          SqlSessionFactory sqlSessionFactory = 
getSqlSessionFactory();

          SqlSession sqlSession1 = 
sqlSessionFactory.openSession(true);

          EmpMapper mapper1 = 
sqlSession1.getMapper(EmpMapper.class);

          Emp emp1 = mapper1.getEmpByEid("13");

          System.out.println(emp1);

          

          System.out.println("********************");

          mapper1.deleteMoreEmp("1");

          sqlSession1.clearCache();

          

          SqlSession <u>sqlSession2</u> = 
sqlSessionFactory.openSession(true);

          EmpMapper mapper2 = 
sqlSession1.getMapper(EmpMapper.class);

          Emp emp2 = mapper2.getEmpByEid("13");

          System.out.println(emp2);

     }


二級快取

  • 二級快取(second level cache),全域性作用域快取

  • 二級快取預設不開啟,需要手動配置

  • MyBatis提供二級快取的介面以及實現,快取實現要求POJO實現Serializable介面

  • 二級快取在 SqlSession 關閉或提交之後才會生效

  • 二級快取使用的步驟:
    全域性配置檔案中開啟二級快取

<!-- 開啟二級快取 -->

          <setting name="cacheEnabled" value="true"/>


需要使用二級快取的對映檔案處使用cache配置快取

<!-- 開啟二級快取 -->

     <cache 
type="<u>org.mybatis.caches.ehcache.EhcacheCache</u>"/>


注意:POJO需要實現Serializable介面

public class Emp implements Serializable{

}

快取相關的屬性

  1. 全域性setting的cacheEnable:
    配置二級快取的開關,一級快取一直是開啟的
  2. select標籤的useCache屬性:
    配置這個select是否使用二級快取。一級快取一直是使用的
  3. sql標籤的flushCache屬性:
    增刪改預設flushCache=true。sql執行以後,會同時清空一級和二級快取。查詢預設 flushCache=false。
  4. sqlSession.clearCache():只是用來清除一級快取
  5. readOnly:只讀,true/false
    true:只讀快取;會給所有呼叫者返回快取物件的相同例項。因此這些物件不能被修改。這提供了很重要的效能優勢。
    false:讀寫快取;會返回快取物件的拷貝(通過序列化)。這會慢一些,但是安全,因此預設是 false。
@Test

     public void testSecondCache() throws Exception {

          SqlSessionFactory sqlSessionFactory = 
getSqlSessionFactory();

          SqlSession sqlSession = 
sqlSessionFactory.openSession(true);

          EmpMapper mapper1 = 
sqlSession.getMapper(EmpMapper.class);

          Emp emp1 = mapper1.getEmpByEid("13");

          System.out.println(emp1);

          sqlSession.commit();

          //刪除功能:清除快取

          /* mapper1.deleteMoreEmp("1"); */

          //只是影響一級快取

          sqlSession.clearCache();

          System.out.println("===================");

          

          EmpMapper mapper2 = 
sqlSession.getMapper(EmpMapper.class);

          Emp emp2 = mapper2.getEmpByEid("13");

          System.out.println(emp2);

          

     }