MyBatis 快取機制
阿新 • • 發佈:2020-07-18
MyBatis 快取機制
簡介
MyBatis 包含一個非常強大的查詢快取特性,它可以非常方便地配置和定製。快取可以極大的提升查詢效率.
MyBatis系統中預設定義了兩級快取:一級快取、二級快取
- 預設情況下,只有一級快取(SqlSession級別的快取,也稱為本地快取)開啟。
- 二級快取需要手動開啟和配置,他是基於namespace級別的快取。
一級快取
-
一級快取(local cache), 即本地快取, 作用域預設為sqlSession。同一次會話期間只要查詢過的資料都會儲存在當前SqlSession的一個Map中。
-
級快取失效的幾種情況
不同的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{
}
快取相關的屬性
- 全域性setting的cacheEnable:
配置二級快取的開關,一級快取一直是開啟的 - select標籤的useCache屬性:
配置這個select是否使用二級快取。一級快取一直是使用的 - sql標籤的flushCache屬性:
增刪改預設flushCache=true。sql執行以後,會同時清空一級和二級快取。查詢預設 flushCache=false。 - sqlSession.clearCache():只是用來清除一級快取
- 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);
}