mybatis 之缓存机制
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mybatis 之缓存机制相关的知识,希望对你有一定的参考价值。
1、缓存机制的简单介绍:
a、MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。缓存可以极大的提升查询效率。
b、MyBatis 系统中默认定义了两级缓存:
一级缓存和二级缓存:
- 默认情况下,只有一级缓存(SqlSession 级别的缓存,也称为本地缓存)开启。
- 二级缓存需要手动开启和配置,它是基于 namespace 级别的缓存。
- 为了提高扩展性。MyBatis 定义了缓存接口 Cache。我们可以通过实现 Cache 接口来自定义二级缓存。
2、一级缓存:
a、一级缓存(local cache),即本地缓存,作用域默认是 sqlSession。一级缓存是一直开启的,无法关闭;是 sqlSession 级别的一个 Map 。
与数据库同一次会话期间查询到的数据会放到本地缓存中。
以后如果需要获取相同的数据,直接从缓存中拿,没有必要再去查询数据库。
注:可以看到上图的控制台输出结果,sql 语句只向数据库发送了一条,在相同的会话下(同一个 SqlSession,相同的查询条件),获取到的是同一个对象。
b、一级缓存失效的四种情况:
- 不同的 SqlSession 对应不同的一级缓存
注:可以看到,发送了两条 sql 语句,并且返回的 Employee 类的对象是两个不同的对象。
- 同一个 SqlSession 但是查询条件不同
- 同一个 SqlSession 两次查询期间执行了任何一次增删改操作
- 同一个 SqlSession 两次查询期间手动清空了缓存
3、二级缓存:(全局缓存)基于 namespace 级别的缓存,一个 namespase 对应一个二级缓存:
a、工作机制:
- 一个会话,查询一条数据,这个数据就会被放在当前会话的一级缓存中。
- 如果会话结束,一级缓存中的数据会被保存在二级缓存中;新的会话查询信息,就可以参照二级缓存。
- 不同的 namsespace 查询出的数据会放在自己对应的缓存中。(map)
b、实际出现的效果:
数据会从二级缓存中获取。查出的数据都会默认先放在一级缓存中,只有会话提交或者关闭以后,一级缓存中的数据才会转移到二级缓存中。
c、使用的方式:
- 开启全局配置文件(我的文件名叫做 mybatis-config.xml)配置:<setting name="cacheEnabled" value="true"/>(手动配置,即使默认配置的属性是 true,防止版本更新时带来的问题)
- 在 mapper.xml sql 映射文件中配置 <cache></cache>使用二级缓存。(所以说是基于
namespace 的缓存)
cache 标签中相关属性的配置:
- eviction:缓存的回收策略
* LRU - 最近最少使用的,移除最长时间不被使用的对象(默认)
* FIFO - 先进先出:按对象进入缓存的顺序来移除它们
* SOFT - 软引用:移除基于垃圾回收器状态和软引用规则的对象
* WEAK - 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象
- flushInterval:缓存刷新间隔
* 缓存多长时间清空一下,默认不清空,设置一个毫秒值
- readOnly:是否只读
* true 只读:mybatis 认为所有从缓存中获取数据的操作都是只读操作,不会修改数据。但是 mybatis 为了加快获取速度,直接就会将数据在缓存中的引用交给用户。(不安全,但速度快)
* false 非只读:mybatis 认为获取的数据可能被修改。mybatis 会利用序列化和反序列化的技术克隆一份新的数据给你。安全,但是速度慢。(默认设置,javabean 类需要实现 Serializable 接口)
- size:缓存中存放多少元素
- type="":指定自定义缓存的全类名。(实现 Cache 接口即可)
我们来看看示例的代码:
注:做了相关设置后,测试代码输出结果显示,只发送了一条 sql 语句,因为在 openSession 对象关闭后,mybatis 默认会先从二级缓存中取出数据。(因为底层是序列化和反序列化机制,所以返回的对象并不相同,但属性相同)
在新的会话进入后,查询数据会先到二级缓存中查找,后到一级缓存中查找,最后才是数据库中查找。
本文出自 “12392717” 博客,请务必保留此出处http://12402717.blog.51cto.com/12392717/1932302
以上是关于mybatis 之缓存机制的主要内容,如果未能解决你的问题,请参考以下文章
Java框架之MyBatis 07-动态SQL-缓存机制-逆向工程-分页插件