loading...
Mybatis一级缓存和二级缓存
Published in:2022-04-21 | category: Mybatis
Words: 1k | Reading time: 3min | reading:

什么是缓存?

缓存是存在于内存钟的临时数据。

使用缓存减少和数据库的交互次数,减轻数据库压力,提高数据库性能

适用于缓存

  • 经常查询并且不经常改变的
  • 数据的正确与否对最终结果影响不大的

不适用于缓存

  • 经常改变的数据
  • 数据的正确与否对最终结果影响很大的

一级缓存

一级缓存简介

一级缓存为sqlSesson缓存,缓存的数据只在SqlSession内有效。在操作数据库的时候需要先创建一个SqlSession会话对象,在对象中有一个HashMap用于存储缓存数据,此HashMap是当前会话对象私有的,别的SqlSession会话对象无法访问。

第一次会去查询数据库并写到缓存中,第二次从一级缓存中取。

一级缓存是基于PerpetualCache的HashMap本地缓存 ,默认打开一级缓存。

何时清空一级缓存

如果中间sqlSession执行了commit操作(执行插入、更新、删除),则会清空SqlSession中的一级缓存,这样做的目的为了让缓存中的是最新的信息,避免脏读。

当对SqlSession执行更新操作后,并执行commit时,不仅清空其自身的一级缓存(执行更新操作的效果),也会清空二级缓存。

一级缓存的存储格式

mybatis的缓存是基于[namespace:sql语句:参数]来进行缓存的,意思是,SqlSession的HashMap存储缓存数据时,是使用[namespace:sql:参数]作为key,查询返回的语句作为value保存的。

一级缓存无过期时间,只有生命周期

Mybatis在开启一个数据库会话时,会创建一个新的SqlSession对象,SqlSession对象中会有一个Executor对象,Executor对象中持有一个PerpertualCache对象。当会话结束时,SqlSession对象及其内部的Executor对象还有PerpetualCache对象也一并释放掉。

注意:Mybatis一级缓存是默认打开的,不需要手动开启。

二级缓存

二级缓存简介

它指的是Mybatis中SqlSessionFactory对象的缓存。有同一个SqlSessionFactory对象创建的SqlSession共享其缓存。

二级缓存是mapper级别的缓存,也就是同一个namespace的mapper.xml,当多个SqlSession使用同一个Mapper操作数据库的时候,得到的数据会缓存在同一个二级缓存区域。

二级缓存何时存入

在关闭Sqlsession后,才会把该sqlSession一级缓存中的数据添加到namespace的二级缓存中。

开启二级缓存后,还需要将要缓存的实体类实现Serializable接口,为了将缓存数据取出执行反序列化效果,因为二级缓存数据存储介质多种多样,不一定只存在内存中,有可能存在硬盘中。

二级缓存有过期时间,但没有后台线程进行检测

需要注意的是,并不是key-value的过期时间,而是这个cache的过期时间,是flushInterval,意味着整个清空缓存cache,所以不需要后台线程去定时检测。

每当存取数据的时候,都有检测一下cache的生命时间,默认是一个小时,如果这个cache存活了一个小时,那么将整个清空一下。

查询顺序

当Mybatis调用Dao层查询数据库的时候,先查询二级缓存,二级缓存中无对应数据,再去查询一级缓存,一级缓存中也没有,最后去数据库查找。

开启二级缓存

  1. 在ssm框架下,找到SqlMapConfig.xml,然后加入以下代码

    1
    2
    3
    4
    <settings>
    <!-- 开启二级缓存(默认是开的,这里写出来是为了方便代码维护 -->
    <setting name="cacheEnabled" value="true"/>
    </settings>
  2. 在需要开启的mapper.xml中,添加以下代码(在下方)

    1
    2
    <!-- 开启本mapper所在的namespace的二级缓存 -->
    <cache />
  3. 如果是只用了mybatis的话,就找到mybatis-config.xml,然后加入上面两步的代码

  4. 将实体类实现Serializable接口

Prev:
一篇文章带你理解设计模式
Next:
FastJson的AutoType
catalog
catalog