MyBatis總結之快取機制
目錄
前言
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介面的序列化和反序列化操作。因為二級快取資料儲存介質多樣,不一定在記憶體,也可能是在硬碟或者遠端伺服器。