MyBatis笔记五:缓存
Mybatis 的缓存是分为两级缓存的,一个是本地缓存,也就是默认的缓存,这一个缓存是默认开启的。这个缓存是 sqlSession 级别的缓存也就是一个数据库会话的缓存,这个缓存其实说白了就是 sqlSession 级别的一个 Map 。
1.一级缓存
一级缓存底层是一个 map 。虽然缓存默认开启的但是我们也会遇到缓存失效的情况:
- sqlSession 不同
- 查询条件不同,导致返回的数据都不同
- 在两次查询之间进行了插删改操作
- 手动使用了
sqlSession.clearCache
方法清除了缓存。
2.二级缓存
二级缓存是在一级缓存的基础之上的,因为我们的一级缓存是在会话关闭之后这个缓存数据就失效了,那么我们的二级缓存的做的事情就是在会话关闭的时候我们的一级缓存的数据会被转移到一级缓存中,然后新的会话就可以参照二级缓存中的数据。
二级缓存是基于 namespace 的缓存,也就是每一个mapper就是一个二级缓存的空间,他们之间是互相不干扰的。不同的 namespace 查出的数据放到自己的缓存中,也就是 map 中。
1.开启二级缓存
默认的情况是开启的,我们也应该显示的配置,就是在settings标签中配置。
2.使用缓存
在 mapper 的 xml 中,使用cache标签,配置当前的 namespace 的缓存策略。
1 | <cache eviction="FIFO" flushInterval="60000" readOnly="true" size="12" type=""/> |
eviction:缓存的回收策略:
- LRU - 最近最少使用的:移除最长时间不被使用的对象。
- FIFO -先进先出:按对象进入缓存的顺序来移除它们。
- SOFT - 软引用:移除基于垃圾回收器状态和软引用规则的对象。
- WEAK - 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
- 默认的是LRU.
flushInterval:缓存刷新间隔。缓存多长时间清空一次,默认不清空,设置一个毫秒值
readonly:是否只读:
true:只读; mybatis认为所有从缓存中获取数据的操作都是只读操作,不会修改数据。
mybatis为了加快获取速度,直接就会将数据在缓存中的引用交给用户。不安全,速度快
false:非只读: mybatis觉得获取的数据可能会被修改。mybatis会利用序列化&反序列的技术克隆一份新的数据给你。 安全,速度慢
size:缓存存放多少元素;
type=”” 指定自定义缓存的全类名,但是这个类要实现Cache接口即可;
当然如果我们什么东西都不写的话,也就是只写了一个cache标签,他么上述的属性会自动的被应用。
然后就是我们的Cache的自定义,其实Cache的自定义比较简单也就是我们直接实现它的Cache 接口然后实现一些东西就好,但是更好的就是我们其实不用自己写这些东西,在Mybatis的Github上有很多已经写好的cache适配包不用我们自己写、然后再缓存标签中表明type为我们的适配包的类就好了。
3.POJO实现序列化接口
我们的每一个POJO都需要实现序列化接口,否则就会报错,因为我们如果没有开启 readonly 的话我们就必须采用序列化的方式来获取缓存下来的POJO对象。
4.注意
只有当我们的 sqlSession 关闭以后我们的一级缓存内容才会放到二级缓存中去,否则一直是一级缓存在起作用的。
- cacheEnabled=true: false:关闭缓存(二级缓存关闭) (一级缓存一直可用)
- 每个select标签都有useCache=”true”. 如果为false:不使用缓存(一级缓存依然使用,二级缓存不使用)
- 每个增删改标签的: flushCache=”true”: 增册改执行完成后就会清除缓存。他是清除一级二级缓存。
- sqlSession. clearCache( );只是清除当前session的一级缓存,因为我们都是用的 sqlSession 的方法,自然清除的一级缓存。
- localCacheScope:本地缓存作用域:(默认的一级缓存是SESSION) ;如果当前会话缓存为 STATEMENT:可以禁用一级缓存。】、