MyBatis 提供了一级缓存和二级缓存来提高数据库查询的性能。
一级缓存:
也叫本地缓存,是 SQLSession 级别的缓存。MyBatis 默认开启一级缓存,不需要任何额外配置。
其工作原理是:在同一个 SQLSession 中,第一次执行相同的查询 SQL 时,MyBatis 会将从数据库查询的数据写到缓存(内存)中;之后再执行相同的查询时,如果没有缓存失效或超时,就会直接从缓存中获取数据,而不再进行数据库查询,大大提高了查询效率。当一个 SQLSession 结束后,该 SQLSession 中的一级缓存也就不存在了。
一级缓存的生命周期:MyBatis 开启一个数据库会话时,会创建一个新的 SQLSession 对象,其中包含一个新的 Executor 对象,而 Executor 对象中持有一个新的 PerpetualCache 对象。当会话结束时,SQLSession 对象及其内部的 Executor 对象和 PerpetualCache 对象会一并释放掉。
缓存失效的情况:
- 当 SQLSession 调用
close()
方法时,SQLSession 对象关闭,直接会释放掉一级缓存 PerpetualCache 对象,一级缓存将不可用。
- 如果 SQLSession 调用了
clearCache()
,会清空 PerpetualCache 对象中的数据,但 SQLSession 对象还可以继续使用。
- SQLSession 中执行了任何一个
update
(修改)、delete
(删除)、insert
(新增)操作,都会清空 PerpetualCache 对象中的数据。
二级缓存:
二级缓存是多个 SQLSession 共享的,其作用域是 mapper 的同一个 namespace。不同的 SQLSession 两次执行相同 namespace 下的相同 SQL 语句且传递的参数也相同时,第一次执行完毕会将数据库中查询到的数据写到缓存(内存),第二次会直接从缓存中获取,从而提高了查询效率。MyBatis 默认不开启二级缓存,需要进行相应配置。
要开启二级缓存,需要进行以下步骤:
- 在 MyBatis 全局配置文件(如
mybatis-config.xml
)中的<settings>
标签中配置开启二级缓存,设置cacheEnabled
为true
(默认值就是true
,也可以省略这一步)。
- 在具体的 mapper.xml 文件中添加
<cache/>
标签。
- 被缓存的 POJO(实体类)必须实现序列化接口(
implements Serializable
)。
二级缓存的特点包括:
- mapper 映射文件中的所有 select 语句将会被缓存。
- mapper 映射文件中的所有 insert、update 和 delete 语句会刷新缓存。
- 二级缓存是以 namespace 为单位的,不同 namespace 下的操作互不影响。
- 如果在加入
<cache>
标签的前提下让个别 select 元素不使用缓存,可以使用useCache
属性,设置为false
。
- 缓存默认使用最近最少使用(LRU)算法来收回。
- 根据时间表,如
noFlushInterval
(没有刷新间隔),缓存不会以任何时间顺序来刷新。
- 缓存会存储列表集合或对象(无论查询方法返回什么)的 1024 个引用。
- 缓存会被视为是可读/可写(read/write)的缓存,意味着对象检索不是共享的,而且可以安全地被调用者修改,不干扰其他调用者或线程所做的潜在修改。
<cache>
标签还有一些可选属性,用于更精细地控制缓存行为,例如:
eviction
:缓存的回收策略,默认是lru
(最近最少使用,移除最长时间不被使用的对象),还可以选择fifo
(先进先出,按对象进入缓存的顺序来移除它们)、soft
(软引用,移除基于垃圾回收器状态和软引用规则的对象)、weak
(弱引用,更积极地移除基于垃圾收集器和弱引用规则的对象)。
flushInterval
:缓存刷新间隔,设置一个毫秒值表示多长时间清空一次缓存,默认不清空。
readonly
:是否只读,true
(只读)表示 MyBatis 认为所有从缓存中获取数据的操作都是只读操作,不会修改数据,这样可以加快获取数据的速度;false
(读写,默认)表示 MyBatis 觉得获取的数据可能会被修改,会利用序列化或反序列化的技术克隆一份新的数据,速度相对较慢。
size
:缓存存放元素的数量。
type
:指定自定义缓存的全类名(实现Cache
接口即可)。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
评论(0)