MyBatis(五)缓存

2019-07-07  本文已影响0人  guideEmotion

一 缓存机制

MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置定制。缓存可以极大的提升查询效率
MyBatis系统中默认定义了两级缓存。一级缓存和二级缓存
– 1、默认情况下,只有一级缓存(SqlSession级别的缓存,也称为本地缓存)开启。
– 2、二级缓存需要手动开启和配置,他是基于namespace级别的缓存。
– 3、为了提高扩展性。 MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存

架构图

image.png

二 一级缓存

一级缓存是sqlSession级别的缓存。在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构(HashMap),用于存储缓存数据。不同的sqlSession之间的缓存区域(HashMap)是互不影响的。

一级缓存(local cache), 即本地缓存, 作用域默认为sqlSession。当 Session flushclose 后, 该Session 中的所有 Cache 将被清空
• 本地缓存不能被关闭, 但可以调用clearCache()来清空本地缓存, 或者改变缓存的作用域.
• 在mybatis3.1之后, 可以配置本地缓存的作用域.
在 mybatis.xml 中配置

两种级别

Mybatis提供了一级缓存的方案来优化在数据库会话间重复查询的问题。实现的方式是每一个SqlSession中都持有了自己的缓存,一种是SESSION级别,即在一个Mybatis会话中执行的所有语句,都会共享这一个缓存。一种是STATEMENT级别,可以理解为缓存只对当前执行的这一个statement有效。Statement,即不使用一级缓存

工作流程

根据一级缓存的工作流程,我们绘制出一级缓存执行的时序图,如下图所示。



主要步骤如下:

  1. 对于某个Select Statement,根据该Statement生成key
  2. 判断在Local Cache中,该key是否用对应的数据存在。
  3. 如果命中,则跳过查询数据库,继续往下走。
  4. 如果没命中:
    4.1 去数据库中查询数据,得到查询结果;
    4.2 将key和查询到的结果作为key和value,放入Local Cache中。
    4.3. 将查询结果返回;
  5. 判断缓存级别是否为STATEMENT`级别,如果是的话,清空本地缓存。

工作场景

image.png
(1). 第一次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,如果没有,从数据库查询用户信息。得到用户信息,将用户信息存储到一级缓存中。
(2). 如果sqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。(3). 第二次发起查询用户id为1的用户信息,先去找缓存`中是否有id为1的用户信息,缓存中有,直接从缓存中获取用户信息。mybatis默认支持一级缓存的。测试很简单,这里就不贴代码了。

三 二级缓存

• 二级缓存(second level cache),全局作用域缓存
• 二级缓存默认不开启,需要手动配置
• MyBatis提供二级缓存的接口以及实现,缓存实现要求;POJO实现Serializable接口
二级缓存在 SqlSession 关闭或提交之后才会生效

使用步骤

– 1、全局配置文件中开启二级缓存
<setting name="cacheEnabled" value="true"/>
– 2、需要使用二级缓存的映射文件处使用cache配置缓存cache-ref:cache-ref代表引用别的命名空间的Cache配置,两个命名空间的操作使用的是同一个Cache
• <cache />
– 3、注意:POJO需要实现Serializable接口

映射文件的缓存配置

<cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>

<cache eviction="FIFO" flushInterval="60000" readOnly="false" size="1024"></cache> -->

<cache-ref namespace="mapper.StudentMapper"/>

属性

流程

当开启二级缓存后,会使用CachingExecutor装饰Executor,在进入后续执行前,先在CachingExecutor进行二级缓存的查询,具体的工作流程如下所示。

image.png
在二级缓存的使用中,一个namespace下的所有操作语句,都影响着同一个Cache,即二级缓存是被多个SqlSession共享着的,是一个全局的变量
当开启缓存后,数据的查询执行的流程就是 二级缓存 -> 一级缓存 -> 数据库

不同namespace查出的数据会放在自己对应的缓存中(map)
效果:数据会从二级缓存中获取

和缓存有关的设置/属性

参考

  1. Mybatis学习总结(九)——查询缓存
  2. https://www.jianshu.com/p/c553169c5921
上一篇 下一篇

猜你喜欢

热点阅读