文章为学习总结,仅供参考
Mybatis缓存,总共分为三种:一级缓存、二级缓存和第三方缓存;
- 一级缓存:表示sqlsession级别的缓存,指的是每次查询的时候会开启一个会话,该会话相当于一次链接,关闭之后会自动生效;
例如:
//获取与数据库相关的会话
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取对应的映射接口对象
EmpDao mapper = sqlSession.getMapper(EmpDao.class);
Emp emp = mapper.selectEmpByStep(7369);
System.out.println(emp);
//关闭会话
sqlSession.close();
- 二级缓存:全局范围内的缓存,sqlsession关闭之后才会生效。
- 第三方缓存:继承第三方组件,来充当缓存。例如ehcache、redis等;
一级缓存:表示将数据存储在sqlsession中,关闭之后会自动失效,默认情况下是开启的。在同一个会话内如果执行了相同的sql语句,那么除了第一个外,其他的都是从缓存中进行查询的。
但是,在某些情况下,一级缓存可能会失效:
- 在同一个方法中,可能会开启多个会话,这时候就需要注意,会话跟方法没有关系,不要混为一谈,不是一个方法就只能有一个会话,所以严格记住,缓存时保存在SQL session中的
- 当查询需要传递对象的时候,如果对象中的属性值不同,也不会走缓存。
- 在同一次会话中,如果修改了数据(指的是在sqlsession会话中修改了数据,如果在数据库中修改了数据,mybatis不会知道,所以还会走缓存),那么缓存也会失效。
- 如果在一个会话中,手动清除了缓存,那么缓存也会失效。
二级缓存:二级缓存表示的是全局缓存,必须要等到sqlsession关闭之后才生效。就是当sqlsession关闭了,其中的一级缓存,就会到二级缓存中去。由于sqlsession关闭了,所以一级缓存没有了。
而且二级缓存默认是不开启的,如果需要开启的话需要进行配置👇
- 修改全局配置文件(一般名为mybatis-config.xml),在setting中添加配置
<setting name="cacheEnabled" value="true"/>
- 在指定的映射文件(xxxMapper.xml)中使用缓存配置
<cache></cache>
- 对应的Java实体类必须要实现序列化的接口
使用二级缓存的时候,可以包含多个属性值:
eviction:缓存淘汰机制:
- LRU 最近最少使用
- FIFO 先进先出,按照添加缓存的顺序执行
- SOFT - 软引用:基于垃圾回收器状态和软引用规则移除对象。
- WEAK - 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象
flushInterval:设置多长时间进行缓存刷新
size:引用的条数,是一个正整数,缓存中可以存储多少个缓存对象,一般不设置,如果设置大小的话尽量不要太大,容易导致内存溢出。默认是1024
readonly:只读属性:
- true:只读缓存,会给所有的调用的方法返回该对象的实例,不安全
- false: 读写缓存,只是返回缓存对象的拷贝,比较安全
###问题
一级缓存跟二级缓存有没有可能同时存在数据?
不会同时存在,因为二级缓存生效的时候,是在sqlsession关闭的时候
当查询数据的时候,我们是先查询一级缓存还是先查询二级缓存呢?
先查询二级缓存,然后在查询一级缓存。
当开启二级缓存后,控制台会打印出二级缓存的命中率。当查询的语句缓存在一级缓存的时候,二级缓存的命中率就会降低,所以说在查询一级缓存之前会先查询二级缓存。
第三方引用缓存,下次更新。。。。。摸鱼了。