目錄
前言
MyBatis的查詢緩存分爲一級緩存和二級緩存,一級緩存是SqlSession級別的緩存,二級緩存是mapper級別的緩存,二級緩存是多個SqlSession共享的;MyBatis通過緩存機制減輕數據壓力,提供數據庫性能。
1.一級緩存
1.1 同一個SqlSession ,多次調用同一個Mapper和同一個方法的同一個參數,只會進行一次數據庫查詢,然後把數據緩存到緩衝中,以後直接先從緩存中取出數據,不會直接去查數據庫。
1.2 MyBatis中一級緩存是默認開啓的,即在查詢中(一次SqlSession中)。只要當SqlSession不關閉,那麼你的操作會默認存儲使用一級緩存。
1.3 需要注意的是,如果SqlSession執行了DML(insert,update,delete),並提交到數據庫,MyBatis會清空SqlSession中的一級緩存,保證緩存的數據的實時性,避免出現髒讀現象。
String config = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(config);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
SysUser user = sqlSession.selectOne("SysUserMapper.getByUUID", 080001);
System.out.println(user);
/*
* 一級緩存默認就會被使用
*/
user = sqlSession.selectOne(SysUserMapper.getByUUID", 01);
System.out.println(user);
sqlSession.close();
/*
1. 必須是同一個SqlSession,如果sqlSession對象已經close()過了就不可能用了
*/
sqlSession= MyBatisUtil.getSqlSession();
user = sqlSession.selectOne(SysUserMapper.getByUUID", 01);
System.out.println(user);
/*
2. 查詢條件必須是一樣的
*/
user = sqlSession.selectOne(SysUserMapper.getByUUID", 02);
System.out.println(user);
/*
3. 沒有執行過sqlSession.clearCache()清理緩存
*/
//sqlSession.clearCache();
user = sqlSession.selectOne(SysUserMapper.getByUUID", 02);
System.out.println(user);
/*
4. 沒有執行過增刪改的操作(這些操作都會清理緩存)
*/
session.update("SysUserMapper.updateUser",
new SysUser(02, "user", 23));
user = session.selectOne(SysUserMapper.getByUUID", 02);
System.out.println(user);
2.二級緩存
2.1 二級緩存是mapper級別的緩存,使用二級緩存,多個SqlSession使用同一個Mapper的sql去操作數據庫,得到的數據會存到二級緩存區域,以HashMap形式進行存儲。
2.2 MyBatis 默認不會開啓二級緩存,需要在setting全局參數中配置開啓二級緩存。
2.2.1 mybatis-config.xml配置
<settings>
<setting name="cacheEnable" value="true" />
</settings>
2.2.2 開啓當前mapper的namespace下的二級緩存:xxxxMapper.xml
<!-- 創建一個LRU緩存,每隔60秒刷新,最大緩存對象512個,而且返回的對象被認爲是隻讀的 -->
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true" />
1)flushInterval:刷新間隔,默認是不設置,也就是沒有刷新間隔,緩存僅僅調用語句時刷新;
2)size:緩存數目,默認值是1024;
3)readOnly:只讀,默認是false;
4)eviction:回收策略,默認LRU;
LRU | 最近最少回收策略,移除長時間不被使用對象 |
FIFO | 先進先出策略 |
SOFT | 軟引用策略,移除基於垃圾回收狀態和軟引用規則的對象 |
WEAK | 弱引用策略,更積極移除基於垃圾回收狀態和弱引用規則的對象 |
2.3 需要注意的是,使用二級緩存時,與查詢結果映射的Java對象必須實現java.io.Seriailizable接口的序列化和反序列化操作。因爲二級緩存數據存儲介質多樣,不一定在內存,也可能是在硬盤或者遠程服務器。