一、MyBatis緩存介紹
正如大多數持久層框架一樣,MyBatis 同樣提供了一級緩存和二級緩存的支持
1.一級緩存:
基於PerpetualCache 的HashMap本地緩存,其存儲作用域為Session,當Session flush 或close 之後,該Session中的所有Cache 就將清空。
2. 二級緩存:
二級緩存與一級緩存其機制相同,默認也是採用PerpetualCache,HashMap存儲,不同在於其存儲作用域為Mapper(Namespace),並且可自定義存儲源,如Ehcache。
3. 對於緩存數據更新機制,當某一個作用域(一級緩存Session/二級緩存Namespaces)的進行了C/U/D 操作後,默認該作用域下所有select 中的緩存將被clear。
1.1、Mybatis一級緩存測試
package me.gacl.test;import me.gacl.domain.User;import me.gacl.util.MyBatisUtil;import org.apache.ibatis.session.SqlSession;import org.junit.Test;/*** @author gacl* 測試一級緩存*/public class TestOneLevelCache {/** 一級緩存: 也就Session級的緩存(默認開啟)*/@Testpublic void testCache() {SqlSession session = MyBatisUtil.getSqlSession();String statement = "me.gacl.mapping.userMapper.getUser";User user = session.selectOne(statement, );System.out.println(user);/** 一級緩存默認就會被使用*/user = session.selectOne(statement, );System.out.println(user);session.close();/*. 必須是同一個Session,如果session對像已經close()過了就不可能用了*/session = MyBatisUtil.getSqlSession();user = session.selectOne(statement, );System.out.println(user);/*. 查詢條件是一樣的*/user = session.selectOne(statement, );System.out.println(user);/*. 沒有執行過session.clearCache()清理緩存*///session.clearCache(); user = session.selectOne(statement, );System.out.println(user);/*. 沒有執行過增刪改的操作(這些操作都會清理緩存)*/session.update("me.gacl.mapping.userMapper.updateUser",new User(, "user", ));user = session.selectOne(statement, );System.out.println(user);}} 1.2、Mybatis二級緩存測試
1、開啟二級緩存,在userMapper.xml文件中添加如下配置
<mapper namespace="me.gacl.mapping.userMapper"><!-- 開啟二級緩存--><cache/>
2、測試二級緩存
package me.gacl.test;import me.gacl.domain.User;import me.gacl.util.MyBatisUtil;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.junit.Test;/*** @author gacl* 測試二級緩存*/public class TestTwoLevelCache {/** 測試二級緩存* 使用兩個不同的SqlSession對象去執行相同查詢條件的查詢,第二次查詢時不會再發送SQL語句,而是直接從緩存中取出數據*/@Testpublic void testCache() {String statement = "me.gacl.mapping.userMapper.getUser";SqlSessionFactory factory = MyBatisUtil.getSqlSessionFactory();//開啟兩個不同的SqlSessionSqlSession session = factory.openSession();SqlSession session = factory.openSession();//使用二級緩存時,User類必須實現一個Serializable接口===> User implements SerializableUser user = session.selectOne(statement, );session.commit();//不懂為啥,這個地方一定要提交事務之後二級緩存才會起作用System.out.println("user="+user);//由於使用的是兩個不同的SqlSession對象,所以即使查詢條件相同,一級緩存也不會開啟使用user = session.selectOne(statement, );//session.commit();System.out.println("user="+user);}} 1.3、二級緩存補充說明
1. 映射語句文件中的所有select語句將會被緩存。
2. 映射語句文件中的所有insert,update和delete語句會刷新緩存。
3. 緩存會使用Least Recently Used(LRU,最近最少使用的)算法來收回。
4. 緩存會根據指定的時間間隔來刷新。
5. 緩存會存儲1024個對象
cache標籤常用屬性:
<cache eviction="FIFO" <!--回收策略為先進先出-->flushInterval="60000" <!--自動刷新時間60s-->size="512" <!--最多緩存512個引用對象-->readOnly="true"/> <!--只讀-->
給大家補充點知識:
和hibernate一樣,mybatis也有緩存機制
一級緩存是基於PerpetualCache(mybatis自帶)的HashMap 本地緩存,作用範圍為session,所以當session commit或close後,緩存就會被清空
二級緩存默認也是基於PerpetualCache,但是可以為其製定存儲源,比如ehcache
一級緩存緩存的是SQL語句,而二級緩存緩存的是結果對象,看如下例子(mybatis的日誌級別設為debug)