MyBatis缓存
Posted _图南
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatis缓存相关的知识,希望对你有一定的参考价值。
MyBatis缓存学习笔记
1 缓存
<1> 什么是缓存
- 存在内存中的临时数据。
- 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库 数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。
<2> 什么样的数据用缓存
经常查询并且不经常改变的数据。
2 MyBatis缓存
- MyBatis中默认定义了两种缓存:一级缓存和二级缓存
- 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)
- 二级缓存需要手动开启和配置,他是基于namespace级别的缓存。 为了提高扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二 级缓存
3 一级缓存
介绍
- 在同一次会话期间,从数据库中查询的数据会放到本地缓存中。以后如果需要获得相同的数据,直接从缓存中那,可以跳过查询数据库这个步骤
- 减少和数据库的交互次数,减少系统开销,提高了系统效率和解决了 高并发系统的性能问题
- 一级缓存是sqlsession级别的,是一直开启的,我们是关闭不了它
- 一级缓存作用域很小,只能在查询相同的数据的两次操作才能有用
一级缓存失效的四种情况:
-
sqlsession不同,每个sqlSession中的缓存相互独立
//例如:在test中 SqlSession session1= MybatisUtils.getSession(); SqlSession session2= MybatisUtils.getSession();
-
sqlsession相同,查询条件不同
SqlSession session = MybatisUtils.getSession(); UserMapper mapper = session.getMapper(UserMapper.class); UserMapper mapper2 = session.getMapper(UserMapper.class);
mapper不同
-
sqlSession相同,在两次查询之间执行了增删改操作
-
sqlSession相同,手动清除了一个缓存
SqlSession session = MybatisUtils.getSession(); UserMapper mapper = session.getMapper(UserMapper.class); User user = mapper.queryUserById(1); System.out.println(user); session.clearCache();//手动清除缓存
4 二级缓存
介绍
- 二级缓存也叫全局缓存,基于namespace级别的缓存,一个命名空间,对应一个二级缓存
工作机制
- 一个会话查询一条数据,这个数据就会放在当前的回话的一级缓存中
- 关闭会话,一级缓存消失,一级缓存中的数据保存到二级缓存
- 在新的会话查询信息,可以在二级缓存中获取内容
二级缓存的使用
-
在全局配置文件中开启二级缓存【mybatis-config.xml】
1 <setting name="cacheEnabled" value="true"/>
-
在mapper.xml文件中配置二级缓存
<cache/> 官方示例=====>查看官方文档 <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/> 这个更高级的配置创建了一个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此对它们进行修改可能会在不同线程中的调用者 产生冲突
-
在pojo实体类中实现序列化接口
public class User implement Serializable{ ...... }
-
在test中测试代码
结论
- 开启二级缓存,在同一个Mapper中查询。可以在二级缓存中拿到数据
- 查到的数据默认会先放到一级换层中
- 只有会话关闭或提交以后,一级换层中的数据才会转到二级缓存中去
缓存查询顺序
新会话先到二级缓存中查询是否有对应的数据,再到一级缓存,最后到数据库
以上是关于MyBatis缓存的主要内容,如果未能解决你的问题,请参考以下文章