MyBatis(6),缓存

MyBatis(6),缓存

MyBatis 内置了一个强大的事务性查询缓存机制,它可以非常方便地配置和定制。
如果没有缓存,那么每次查询的时候都需要从数据库中加载数据,这会造成IO的性能问题,所以,在很多情况下如果连续执行两条相同的sql语句,可以直接从缓存中获取,如果获取不到,那么再去查询数据库,这意味着查询完成的结果需要放到缓存中.
MyBatis默认情况下,只启用了本地的会话缓存(一级缓存),它仅仅对一个会话中的数据进行缓存。

缓存分类

  • 一级缓存:表示sqlSession级别的缓存,每次查询的时候会开启一个会话,此会话相当于一次连接,关闭之后自动失效
  • 二级缓存:全局范围内的缓存,sqlSession关闭之后才会生效
  • 第三方缓存:集成第三方的组件,来充当缓存的作用

一级缓存

表示将数据存储在sqlSession中,关闭之后自动失效,默认情况下是开启的
在同一个会话之内,如果执行了多个相同的sql语句,那么除了第一个之外,所有的数据都是从缓存中进行查询的
在某些情况下,一级缓存可能会失效
1.在同一个方法中,可能会开启多个会话,此时需要注意,会话跟方法没有关系,不是一个方法就只能有一个会话,所以严格记住,缓存的数据是保持在sqlSession中的
2.当传递对象的时候,如果对象中的属性值不同,也不会走缓存
3.当在一个会话中,如果修改了数据,那么缓存会失效(没有提交也是会失效的),不同会话是相互不受影响的
注意:当一个方法中有其它的会话的时候,其它会话修改数据不会影响当前会话的缓存
4.如果在一个会话过程中,手动清空了缓存,那么缓存也会失效

二级缓存

表示的是全局缓存,必须要等到sqlSession关闭之后才会生效
默认是关闭的,如果需要开启的话,需要进行如下设置
1.修改全局配置文件,在settings中添加配置

<settings>
    <!--开启二级缓存-->
    <setting name="cacheEnabled" value="true"/>
</settings>

2.指定在哪个映射文件中使用缓存的配置

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yangqihang.dao.EmpDao">
	<select>...</select>
    <cache></cache>
</mapper>

3.对应的Java实体类必须要实现序列化的接口

public class Emp implements Serializable{
	//省略
}

在使用二级缓存的时候,可以包含多个属性值:

<!--
eviction:缓存淘汰机制
	LRU:最近最少使用
	FIFO:先进先出,按照添加缓存的顺序执行
	SOFT:软引用,基于垃圾回收器状态和软引用规则移除对象.
	WEAK:弱引用,更积极地基于垃圾收集器状态和弱引用规则移除对象.
flushInterval:设置多长时间进行缓存刷新
size:引用的条数,是一个正整数,缓存中可以存储多少个对象,一般不设置,如果设置的话不要太大,会导致内存溢出
readOnly:只读属性
	true:只读缓存,会给所有的调用的方法返回该对象的实例,不安全
	false:读写缓存,只是返回缓存对象的拷贝,比较安全
-->
<cache eviction="LRU" size="512" flushInterval="60000" readOnly="true"></cache>

问题

一级缓存和二级缓存有没有可能同时存在?
不会同时存在,因为二级缓存生效的时候是在sqlSession关闭的时候

当查询数据的时候,我们是先查询一级缓存还是先查询二级缓存?
先查询二级缓存,然后再查询一级缓存

第三方缓存

以ehcache为例

导入pom依赖

<!-- 第三方缓存ehcache -->
<dependency>
    <groupId>org.mybatis.caches</groupId>
    <artifactId>mybatis-ehcache</artifactId>
    <version>1.2.0</version>
</dependency>

导入ehcache配置

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
    <!-- 磁盘保存路径 -->
    <diskStore path="D:\ehcache" />

    <defaultCache
            maxElementsInMemory="1"
            maxElementsOnDisk="10000000"
            eternal="false"
            overflowToDisk="true"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
    </defaultCache>
    <!--
    属性说明:
    diskStore:指定数据在磁盘中的存储位置。
    defaultCache:当借助CacheManager.add("demoCache")创建Cache时,EhCache便会采用<defalutCache/>指定的的管理策略

    以下属性是必须的:
    maxElementsInMemory - 在内存中缓存的element的最大数目
    maxElementsOnDisk - 在磁盘上缓存的element的最大数目,若是0表示无穷大
    eternal - 设定缓存的elements是否永远不过期。如果为true,则缓存的数据始终有效,如果为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断
    overflowToDisk - 设定当内存缓存溢出的时候是否将过期的element缓存到磁盘上

    以下属性是可选的:
    timeToIdleSeconds - 当缓存在EhCache中的数据前后两次访问的时间超过timeToIdleSeconds的属性取值时,这些数据便会删除,默认值是0,也就是可闲置时间无穷大
    timeToLiveSeconds - 缓存element的有效生命期,默认是0.,也就是element存活时间无穷大
    diskSpoolBufferSizeMB 这个参数设置DiskStore(磁盘缓存)的缓存区大小.默认是30MB.每个Cache都应该有自己的一个缓冲区.
    diskPersistent - 在VM重启的时候是否启用磁盘保存EhCache中的数据,默认是false。
    diskExpiryThreadIntervalSeconds - 磁盘缓存的清理线程运行间隔,默认是120秒。每个120s,相应的线程会进行一次EhCache中数据的清理工作
    memoryStoreEvictionPolicy - 当内存缓存达到最大,有新的element加入的时候, 移除缓存中element的策略。默认是LRU(最近最少使用),可选的有LFU(最不常使用)和FIFO(先进先出)
     -->
</ehcache>

类似开启二级缓存的步骤

setting设置和在指定映射文件中开启缓存配置,需要设置type属性

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

这样第三方缓存就好了,每次查询会在diskStore 指定的路径下生成文件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值