Mybatis的缓存机制
缓存
将一些不太常变更的数据,保存在内存中,或者某些高速存储器上,从而提升我们查询数据的效率
Mybatis的两级缓存
1、一级缓存与SqlSessoin会话绑定,默认开启
2、二级缓存是应用程序全局缓存,所有SqlSession共享,需要手动开启
- 一级缓存是将数据保存在内存中(一个巨大的HashMap),一个SqlSession对应一个HashMap
-
一级缓存的生命周期:随着SqlSession创建而创建,当SqlSessioin Close关闭时跟着销毁,一级缓存的生命周期较短
-
二级缓存是应用程序全局的缓存,只要Mybatis在启动的过程中,二级缓存就会一直存在,二级缓存的载体可以是内存中的一个HashMap,也可以是一个单体的缓存框架,例如Ehcache、分布式NoSql数据库Redis。对于二级缓存来说,所有的SqlSesion都可以访问其中的数据。
-
二级缓存的生命周期:随着MybatisSessionFactory的创建而创建,在SessionFactory销毁时消失
-
二级缓存相较于一级缓存,二级缓存存活周期更长,需要的空间更大,但缓存的命中率更高
一级缓存默认开启
SqlSession session = sessionFactory.openSession();
Employee emp1 = session.selectOne(statement, 7566);
System.out.println(emp1);
Employee emp2 = session.selectOne(statement, 7566);
System.out.println(emp2);
session.close();
..entity.Employee@589838eb
..entity.Employee@589838eb
SqlSession session1 = sessionFactory.openSession();
Employee emp1 = session1.selectOne(statement, 7566);
System.out.println(emp1);
session1.close();
SqlSession session2 = sessionFactory.openSession();
Employee emp2 = session2.selectOne(statement, 7566);
System.out.println(emp2);
session2.close();
..entity.Employee@4dfa3a9d
..entity.Employee@464bee09
开启二级缓存
- 映射器 emp.xml
<mapper namespace="..mapper.EmpMapper">
<!-- cache size="512":在二级缓存中最多容纳512个对象 -->
<!-- eviction="FIFO":缓存清除策略FIFO、LRU -->
<!-- flushInterval="60000":定时(每60s)兑缓存进行清理 -->
<!-- readOnly="true":保存在缓存中的对象不允许被修改 -->
<cache size="512" eviction="FIFO" flushInterval="60000" readOnly="true"/>
<!-- useCache="false":不使用缓存 -->
<!-- 通常查询结果为多个对象时,不建议使用二级缓存。因为list列表中任何一个元素发生变化后,Mybatis为了保证缓存中的数据和数据库中数据的一致,会将整个list进行处理 -->
<select id="findAll"
resultType="..entity.Employee" useCache="false">
select * from emp
</select>
<select id="findById" parameterType="int"
resultType="..entity.Employee" useCache="true">
select * from emp where empno = #{value}
</select>
</mapper>
- 使用二级缓存存储的对象对应实体类需要实现
Serializable
接口
SqlSession session1 = sessionFactory.openSession();
Employee emp1 = session1.selectOne(statement, 7566);
System.out.println(emp1);
session1.close();
SqlSession session2 = sessionFactory.openSession();
Employee emp2 = session2.selectOne(statement, 7566);
System.out.println(emp2);
session2.close();
..entity.Employee@589838eb
..entity.Employee@589838eb
发表回复