Mybatis之缓存


Mybatis 缓存

![屏幕快照 2018-11-13 下午11.20.32](Mybatis之缓存/屏幕快照 2018-11-13 下午11.20.32.png)

默认情况下是没有开启缓存的,除了局部的 session 缓存,可以增强变现而且处理循环 依赖也是必须的。要开启二级缓存,你需要在你的 SQL 映射文件中添加一行:

一级缓存

Mybatis一级缓存的生命周期和SqlSession一致。

Mybatis的缓存是一个粗粒度的缓存,没有更新缓存和缓存过期的概念,同时只是使用了默认的hashmap,也没有做容量上的限定。

Mybatis的一级缓存最大范围是SqlSession内部,有多个SqlSession或者分布式的环境下,有操作数据库写的话,会引起脏数据,建议是把一级缓存的默认级别设定为Statement,即不使用一级缓存。

一级缓存失效的几种情况

  • 相同sqlSession 不同的sql语句
  • 相同sqlSession 相同的sql语句 但是两条语句之间有增加删除修改操作
  • 相同sqlSession 相同的sql语句 但是两条语句之间有sqlSession.clearCache();操作
  • 不同的sqlSession、

一级缓存有关的设置

默认为SESSION(可能在并发的情况下引起脏读,建议设置为statement)

<settings>
    <setting name="localCacheScope" value="STATEMENT"/>
</settings>

二级缓存

二级缓存是namespace级别的,一个namespace对应一个二级缓存

如果会话关闭一级缓存的内容会保存到二级缓存中

1.一个会话查询一条数据,这个数据就会被保存在一级缓存中

2.如果会话关闭,一级缓存中的数据就会被保存在二级缓存中,新的会话查询信息就会参照二级缓存。(若会话没有关闭 下一个会话查询同一个对象 二级缓存不起作用)

3.不同的namespace数据会放在自己的缓存中(map)

开启方法

默认是true 但是为了清晰配置 只要是确定的都建议显示声明

<settings>
    <setting name="cacheEnabled" value="true"/>
</settings>

在XXXMapper.xml的namespace标签内加入

<cache blocking="" eviction="" flushInterval="" readOnly="" size="" type=""/>

注意:需要让pojo实现序列化接口Serializable 并且定义唯一的serialVersionUID

默认策略

它将采用默认的行为进行缓存:

  • 映射文件中所有的select语句将被缓存

  • 映射文件中所有的insert、update和delete语句将刷新缓存

  • 缓存将使用LRU(Least Recently Used)最近最少使用策略算法来回收

  • 刷新间隔(no Flush Interval,没有刷新间隔),缓存不会以任何时间顺序来刷新

  • 缓存会存储列表集合和对象(无论查询方法返回什么)的1024个引用

  • 缓存会被视为read/write(可读/可写)的缓存,意味着对象检索不是共享的,而且可以安全的被调用者修改,而不干扰其他调用者或者线程所做的潜在修改


    标签属性介绍:

  • flushInterval(刷新间隔)可以被设置为任意的正整数(60601000这种形式是不允许的),而且它们代表一个合理的毫秒形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。 -

  • size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的可用内存资源数目。默认值是1024. -

  • readOnly(只读)属性可以被设置为true或false。只读的缓存会给所有调用者返回缓存对象的相同实例(引用),因此这些对象不能被修改,这提供了很重要的性能优势。可读写的缓存会返回缓存对象的拷贝(通过反序列化)。这会慢一些,但是安全,因此默认是false

  • eviction:(缓存回收策略)

    • LRU:最少使用原则,移除最长时间不使用的对象
    • FIFO:先进先出原则,按照对象进入缓存顺序进行回收
    • SOFT:软引用,移除基于垃圾回收器状态和软引用规则的对象
    • WEAK:弱引用,更积极的移除移除基于垃圾回收器状态和弱引用规则的对象

有关缓存的设置/属性

1.cacheEnabled默认是true 若改为false则是关闭了二级缓存 对一级缓存无影响。

2.select标签内的useCache 默认为true 若改为false则关闭的是二级缓存 对一级缓存无影响

3.每个增删改标签 都有flushCache属性 默认为true 。在执行增删改操作后 一级二级缓存都会被清除。

4.select标签 flushCache属性 默认为false 如果改为true每次查询前都会情况缓存。

5.sqlSession.clearCache()只会清空一级缓存

6.localCacheScope:本地缓存作用域 一级缓存SESSION 若要禁用 设置为STATEMENT

缓存的查找顺序

二级 一级

缓存的实现

![屏幕快照 2018-10-17 下午9.19.49](Mybatis之缓存/屏幕快照 2018-10-17 下午9.19.49.png)

mybatis的缓存实现很简单 如PerpetualCache 仅仅是把数据存到map中,但是我们可以定制缓存的实现类(自定义缓存)

使用第三方cachae:ehcache

1.pom.xml中新增两个依赖

<dependency>
    <groupId>org.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>3.6.0</version>
</dependency>

<dependency>
    <groupId>org.mybatis.caches</groupId>
    <artifactId>mybatis-ehcache</artifactId>
    <version>1.0.3</version>
</dependency>

2.ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="false">
    <diskStore path="/Users/bxan/study/ehcache"/>
    <!--
    强制默认缓存配置。这些设置将应用于缓存
    programmtically使用缓存管理器创建添加(字符串cachename)。
    -->
    <!--
       name:缓存名称。
       maxElementsInMemory:缓存最大个数。
       eternal:对象是否永久有效,一但设置了,timeout将不起作用。
       timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
       timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
       overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。
       diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
       maxElementsOnDisk:硬盘最大缓存个数。
       diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
       diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
       memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
       clearOnFlush:内存数量最大时是否清除。
    -->
    <defaultCache
            maxElementsInMemory="1000"
            maxElementsOnDisk="10000000"
            eternal="false"
            overflowToDisk="true"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"
    />

</ehcache>

3.在XXXMapper.xml中指定

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

​ 其他的mapper中可以使用引用<cache-ref namespace="Dao.XXXMapper"/>


文章作者: Bxan
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Bxan !
  目录