Mybatis有个强大的特性,可以定制和配置缓存,缓存可以大大提升我们的查询效率。
默认情况下,只有一级缓存开启(SqlSession级别的缓存,也称为本地缓存)
二级缓存需要手动开启,他是基于namespace级别的缓存,也就是接口级别。
为了提高拓展性,MyBatis定义了缓存接口Cache,我们可以通过实现Cache接口来自定义二级缓存。
一级缓存
与数据库同义词会话期间查询到的数据会放在本地缓存中去,也关不掉一级缓存,相当于一个map。
以后如果需要获取相同的数据,直接从缓存中拿,没必要去查询数据库。
测试步骤:开启日志,在一个SqlSession中查询两次。
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> allById = mapper.findAllById(1);
for (User user : allById) {
System.out.println(user);
}
System.out.println("-----------------");
List<User> allById2 = mapper.findAllById(1);
for (User user : allById2) {
System.out.println(user);
}
sqlSession.close();
运行结果:
第一次查询有连接数据库,第二次查询直接从本地缓存中取。
缓存失效:
select 语句将会被缓存。
查询不同的东西,不同的mapper.xml。
insert,update,delete语句会刷新缓存,因为可能会改变原来的数据,所以必定刷新,一刷新缓存就失效了。
手动清除。
缓存会使用最近最少使用算法来清楚不需要的缓存
缓存不会定时刷新
缓存会保存列表或者对象的1024个引用。
二级缓存
二级缓存是事务性的,在一级缓存死了的时候才会出来
工作机制
一个会话查询一条数据,这个数据会被放在当前会话的一级缓存中去
当会话关闭,一级缓存也就消失了,所以我们需要用更高级的二级缓存,基于namespace保存到二级缓存中去。
新的会话查询信息,就可以从二级缓存中获取内容了
不同的mapper查询出的数据会放在自己对应的缓存(map)中
开启缓存
1:myabtis-config.xml 显示的开启全局缓存
2:启用的话就是在mapper.xml里面加一个<cache/>标签
还可以加一些属性来修饰:配置FIFO缓存,每隔50S刷新一次,最多可以存储512个对象或者列表,返回的对象是只读的。
清除策略,默认的LRU策略
LRU: 最近最少使用 ,移除长时间不被使用的对象
FIFO:先进先出 ,按对象进入缓存的顺序来移除他们
SOFT:软引用 属于垃圾回收器状态和软引用规则移除对象。
WEAK: 弱引用 更积极地基于垃圾回收器状态和弱引用规则移除对象。
测试一下
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> allById = mapper.findAllById(1);
for (User user : allById) {
System.out.println(user);
}
sqlSession.close();
System.out.println("-----------------");
SqlSession sqlSession2 = MyBatisUtils.getSqlSession();
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
List<User> allById2 = mapper2.findAllById(1);
for (User user : allById2) {
System.out.println(user);
}
运行结果:
小结
只要开启了二级缓存,在同一个mapper下有效
所有数据都会先放在一级缓存中去
只有当会话提交,或者关闭的时候,才会提交到二级缓存。
缓存原理
缓存顺序
先看二级缓存有没有,
再看一级缓存有没有,
都没有再查询数据库
自定义缓存
Ehcache 是一种广泛使用的开源的java分布式缓存,主要面向通用缓存。
导包
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.1.0</version>
</dependency>