本章介绍缓存相关的内容,总共有6个小节
- 第一,第二小节介绍一级和二级缓存。
- 第三,第四小节介绍它与缓存框架Ecache,redis进行集成。
- 第五小节演示脏数据的产生以及它的处理方式。
- 第六小节介绍二级缓存的适用场景
结构如下图:
图7-1 第七章节
1、内置缓存
在了解自带缓存之前,首先需要对Mybatis的一些核心对象有所理解,尤其是sqlSessionFactory与SqlSession。如下图:
图7-2 sqlSessionFactory与sqlSession对象
1.1 一级缓存
它的一级缓存存在于sqlSession对象的生命周期中,伴随着SqlSession对象的产生,一级缓存自动生效。伴随着它的关闭(调用sqlSession的close方法),一级缓存被自动清除。
使用同一个sqlSession得到的Mapper接口对象,它执行更新,删除,插入都会刷新缓存。本质是确保同一个sqlSession对象,同一个namespace。
一级缓存只适用于查询语句,如果需要关闭一级缓存,在select标签上配置flushCache属性为true即可。
1.2 二级缓存
它的二级缓存存在于sqlSessionFactory对象的生命周期中,默认情况下是关闭的。下面通过几个问题来了解二级缓存
1. 如何开启二级缓存?
答:开启二级缓存需要进行配置,配置的步骤如下:
- 第一步:需要在config配置文件中的setting标签中设置cacheEnabled值为true,它对应Configuration对象的cacheEnabled属性值,它的默认值也是true。其实可以省略。
- 第二步:需要在Mapper配置文件或者是Mapper接口中添加缓存配置,如果是Mapper配置文件,需要添加<cache>标签,它的属性值如下:
表格2- 15 cache标签
描述 |
配置mybatis的二级缓存 |
|
属性 |
Eviction |
描述:回收策略。 1. LRU,移除最长时间不被使用的对象。 2. FIFO:按对象的进入缓存顺序来移除。 3. SOFT:基于垃圾回收机制。 4. WEAK:基于垃圾回收机制回收弱引用。 |
示例 eviction=LRU。 |
||
属性 |
flushInterval |
描述:缓存的刷新间隔,默认情况下不配置此项,因为更新,删除,添加语句都会刷新缓存。刷新间隔的单位为毫秒 |
示例 flushInterval=60*1000。 |
||
属性 |
Size |
描述:缓存引用的个数,当超出这个个数时,会回收其他对象,默认为1024。 |
示例 size=2048。 |
||
属性 |
readonly |
描述:缓存是否为只读,当为true时,缓存保存在Map对象中。当为false时,缓存的对象需要实现序列化接口,通过序列化反序列化机制实现。 |
示例 flushInterval=60*1000。 |
||
示例 |
<cache eviction="LRU" size="3" flushInterval="60*1000" readOnly="true"/> |
如果是mapper接口,需要配置@CacheNamespace注解,它的属性值与标签的属性值一一对应。它们不能同时存在,否则会报错。
2. 二级缓存的实现方式是什么?
答:当cache标签的readonly属性为false时,缓存是读/写的,此时它通过SerializeCache对象实现,此时缓存的结果集转换的JavaBean必须实现serializable接口。当cache标签的readonly属性为true时,缓存是只读的,此时它通过Map对象实现。
3. 如何处理二级缓存产生的脏数据?
答:当查询结果集为多个表的数据时,结果集需要映射为多个实体类型,例如用户对象中存在多个角色,需要返回List<Role>时。此时User对应UserMapper的命名空间,Role对应RoleMapper的命名空间,如果select语句存在与UserMapper命名空间下时,对RoleMapper命名空间下的增,删,改会导致UserMapper查询得到的Role不是最新的,此时User对应的List<Role>为脏数据。处理这种情况需要在UserMapper中配置<cache-ref namespace=”roleMapper的命名空间”>。
4. 二级缓存的适用场景?
答:因为每次新增,删除,修改都会清空一级和二级缓存,所以需要应用于以查询为主的项目中。由于查询结果集涉及到多个表时会产生脏数据,命名空间相互关联又会导致缓存频繁的被清空,所以尽量使用在关联较少的查询中。
5. 二级缓存的效果是什么?
答:效果如下:
- XXMapper文件中的所有Select语句都会被缓存。
- 所有的更新,修改,删除都会更新缓存。
- 缓存默认使用LRU算法回收。
- 缓存不会以任何时间来刷新。
- 缓存会存储集合或对象的1024个引用。
- 缓存会被视为可读写的。
2、集成
与缓存框架的集成都较为简单,都遵循以下三个步骤:
- 引入相关的jar包,名称为mybatis-XX,XX表示缓存框架的名称
- 搭建缓存框架的坏境,编写框架配置文件。
- 配置cache标签的type属性。它的值为缓存实现类,通常都在org.mybatis.caches.XX.className,其中XX表示缓存框架的名称。className为其对应的缓存实现类
2.1 Ehcache
官网地址:http://mybatis.org/ehcache-cache/index.html