摘要:简述mybatis的二级缓存的基础配置
1、二级缓存,可以认为是SqlSessionFactory的生命周期,即在多个sqlSession中有效。
1.1.1 开启二级缓存,配置文件中有二级缓存的总开关,默认为true
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
1.1.2 如果是springboot项目则为
mybatis.configuration.cache-enabled=true
1.2.1 在mapper.xml的文件中通过<cache/>配置
<mapper namespace="com.honor.mapper.AreaDictMapper">
<!--开启二级缓存-->
<cache/>
1.2.2 如果在mapper接口中开启二级缓存通过(为使用注解(如:@Select)的方法开启缓存):@CacheNameSpace注解
如果mapper接口和对应的xml文件同时开启缓存,需要用参照缓存,在下一篇帖子会介绍。
1.3 注意需要缓存的实体类需要继承serializable接口
public class AreaDict implements Serializable {
1.4 <cache/>标签的属性(@CacheNameSpace)有相同的属性配置
eviction:缓存的回收策略 默认的是LRU
LRU - 最近最少使用,移除最长时间不被使用的对象
FIFO - 先进先出,按对象进入缓存的顺序来移除它们
SOFT - 软引用,移除基于垃圾回收器状态和软引用规则的对象
WEAK - 弱引用,更积极地移除基于垃圾收集器和弱引用规则的对象
flushInterval:缓存刷新间隔,缓存多长时间清空一次,默认不清空,设置一个毫秒值。
readOnly:是否只读
true:只读:mybatis认为所有从缓存中获取数据的操作都是只读操作,不会修改数据。
mybatis为了加快获取数据,直接就会将数据在缓存中的引用交给用户 。不安全,速度快
false:读写(默认):mybatis觉得获取的数据可能会被修改
mybatis会利用序列化&反序列化的技术克隆一份新的数据给你。安全,速度相对慢
size:缓存存放多少个元素
type:指定自定义缓存的全类名(实现Cache接口即可)
2、二级缓存示例
测试代码:开启二个sqlsession,两次执行一样的查询sql
System.out.println("二级缓存测试开始");
SqlSession sqlSession = sqlSessionFactory.openSession();
AreaDictMapper areaDictMapper = sqlSession.getMapper(AreaDictMapper.class);
AreaDict areaDict1 = areaDictMapper.selectById(1l);
sqlSession.commit();
sqlSession.close();
SqlSession sqlSession1 = sqlSessionFactory.openSession();
AreaDictMapper areaDictMapper1 = sqlSession1.getMapper(AreaDictMapper.class);
AreaDict areaDict2 = areaDictMapper1.selectById(1l);
sqlSession1.commit();
sqlSession1.close();
System.out.println("二级缓存测试结束");
结果:第一次发出sql语句,第二次不发,直接从sql中取。
上述红框中的cache hit ratio表示缓冲命中率,表示从缓存中取数据的次数占总次数的比例,这边一共需要发两次sql,从缓存中取了一次,所以占比0.5
3、缓存清空
3.1 执行dml语句会清空缓存
示例:
测试代码:在第二次查询之前更新一次数据库
System.out.println("二级缓存测试开始");
SqlSession sqlSession = sqlSessionFactory.openSession();
AreaDictMapper areaDictMapper = sqlSession.getMapper(AreaDictMapper.class);
AreaDict areaDict1 = areaDictMapper.selectById(1l);
sqlSession.commit();
sqlSession.close();
SqlSession sqlSession1 = sqlSessionFactory.openSession();
AreaDictMapper areaDictMapper1 = sqlSession1.getMapper(AreaDictMapper.class);
// 更新操作
areaDictMapper1.updateAreaNameById("改则县",3634);
AreaDict areaDict2 = areaDictMapper1.selectById(1l);
sqlSession1.commit();
sqlSession1.close();
System.out.println("二级缓存测试结束");
结果: 第二次查询发出sql,没有在缓存中获取,插入和删除操作类似。
3.2 flushCache="true"会清空缓存
示例:
测试代码 :在mapper中将selectById的flushCache设置为true
<select id="selectById" resultMap="BaseResultMap" flushCache="true">
select
<include refid="base_column_list"/>
from area_dict
where area_dict_id = #{id}
</select>
System.out.println("二级缓存测试开始");
SqlSession sqlSession = sqlSessionFactory.openSession();
AreaDictMapper areaDictMapper = sqlSession.getMapper(AreaDictMapper.class);
AreaDict areaDict1 = areaDictMapper.selectById(1l);
sqlSession.commit();
sqlSession.close();
SqlSession sqlSession1 = sqlSessionFactory.openSession();
AreaDictMapper areaDictMapper1 = sqlSession1.getMapper(AreaDictMapper.class);
// areaDictMapper1.updateAreaNameById("改则县",3634);
AreaDict areaDict2 = areaDictMapper1.selectById(1l);
sqlSession1.commit();
sqlSession1.close();
System.out.println("二级缓存测试结束");
结果:每次都会重新发sql