mybatis缓存

Maple_XL      2022-05-04     658

关键词:

MyBatis缓存

  • MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。

  • MyBatis系统中默认定义了两级缓存:一级缓存二级缓存

    • 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)
    • 二级缓存需要手动开启和配置,他是基于namespace级别的缓存。
    • 为了提高扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存

一级缓存

一级缓存也叫本地缓存:

  • 与数据库同一次会话期间查询到的数据会放在本地缓存中。
  • 以后如果需要获取相同的数据,直接从缓存中拿,不必再去查询数据库;
  • sqlsession close后被释放
  • 在一次会话中执行两次一样的sql,只有第一次被执行,第二次直接从缓存获取。

一级缓存效果

  • 会话中的所有 select 语句的结果将会被缓存。
  • 会话中所有 insert、update 和 delete 语句会刷新缓存。
  • 缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
  • 缓存不会定时进行刷新(也就是说,没有刷新间隔)。
  • 缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用。
  • 缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。
@Test
	public void test2(){
		SqlSession sqlSession = MyBatisUtil.getSqlSession();
		EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
		Employee employee = (Employee) empMapper.queryEmpById(1001);
		System.out.println(employee);
		Employee employee1 = empMapper.queryEmpById(1002);
		System.out.println(employee1);
		//直接读取缓存不会查询数据库
		Employee employee2 = empMapper.queryEmpById(1001);
		System.out.println(employee2);
		//手动清理缓存
		sqlSession.clearCache();
		//因为缓存被清理,所以sql被执行
		Employee employee3 = empMapper.queryEmpById(1001);
		System.out.println(employee3);
	}

二级缓存

默认情况下,只启用了本地的会话缓存,它仅仅对一个会话中的数据进行缓存。 要启用全局的二级缓存,只需要在你的 SQL 映射文件中添加一行:

<cache/>

这个简单语句的效果如下:

  • 映射语句文件中的所有 select 语句的结果将会被缓存。
  • 映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。
  • 缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
  • 缓存不会定时进行刷新(也就是说,没有刷新间隔)。
  • 缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用。
  • 缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

这些属性可以通过 cache 元素的属性来修改。比如:

<cache
  eviction="FIFO"	<!-- 清除策略默认LRU -->
  flushInterval="60000"
  size="512" <!-- 默认1024 -->
  readOnly="true"/>	<!-- 默认false -->

这个更高级的配置创建了一个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此对它们进行修改可能会在不同线程中的调用者产生冲突。

可用的清除策略有:

  • LRU – 最近最少使用:移除最长时间不被使用的对象。
  • FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
  • SOFT – 软引用:基于垃圾回收器状态和软引用规则移除对象。
  • WEAK – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。

提示 二级缓存是事务性的。这意味着,当 SqlSession 完成并提交时,或是完成并回滚,但没有执行 flushCache=true 的 insert/delete/update 语句时,缓存会获得更新。

关闭

  • 在核心配置文件中设置cacheEnabled=“false”可关闭所有配置文件的缓存。
  • 在映射文件中的select标签中指定useCache="false"可以关闭单条语句的缓存。
  • 在update、insert、delete语句中指定flushCache="false"可以关闭该语句对缓存的刷新。

注意:使用二级缓存需要将实体类序列化(Serializable接口)

缓存原理

自定义缓存EhCache

Ehcache是一种广泛使用的java分布式缓存,用于通用缓存;

要在应用程序中使用Ehcache,需要引入依赖的jar包

<!-- https://mvnrepository.com/artifact/org.mybatis.caches/mybatis-ehcache -->
<dependency>
   <groupId>org.mybatis.caches</groupId>
   <artifactId>mybatis-ehcache</artifactId>
   <version>1.1.0</version>
</dependency>

在mapper.xml中使用对应的缓存即可

<mapper namespace = “org.acme.FooMapper” > 
   <cache type = “org.mybatis.caches.ehcache.EhcacheCache” /> 
</mapper>

编写ehcache.xml文件,如果在加载时未找到/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:为缓存路径,ehcache分为内存和磁盘两级,此属性定义磁盘的缓存位置。参数解释如下:
      user.home – 用户主目录
      user.dir – 用户当前工作目录
      java.io.tmpdir – 默认临时文件路径
    -->
   <diskStore path="./tmpdir/Tmp_EhCache"/>
   
   <defaultCache
           eternal="false"
           maxElementsInMemory="10000"
           overflowToDisk="false"
           diskPersistent="false"
           timeToIdleSeconds="1800"
           timeToLiveSeconds="259200"
           memoryStoreEvictionPolicy="LRU"/>

   <cache
           name="cloud_user"
           eternal="false"
           maxElementsInMemory="5000"
           overflowToDisk="false"
           diskPersistent="false"
           timeToIdleSeconds="1800"
           timeToLiveSeconds="1800"
           memoryStoreEvictionPolicy="LRU"/>
   <!--
      defaultCache:默认缓存策略,当ehcache找不到定义的缓存时,则使用这个缓存策略。只能定义一个。
    -->
   <!--
     name:缓存名称。
     maxElementsInMemory:缓存最大数目
     maxElementsOnDisk:硬盘最大缓存个数。
     eternal:对象是否永久有效,一但设置了,timeout将不起作用。
     overflowToDisk:是否保存到磁盘,当系统当机时
     timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
     timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
     diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
     diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
     diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
     memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
     clearOnFlush:内存数量最大时是否清除。
     memoryStoreEvictionPolicy:可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。
     FIFO,first in first out,这个是大家最熟的,先进先出。
     LFU, Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
     LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
  -->

</ehcache>

合理的使用缓存,可以让我们程序的性能大大提升!

mybatis一级缓存,mybatis二级缓存,mybatis缓存失效(代码片段)

Mybatis一级缓存,Mybatis二级缓存,Mybatis缓存失效 ================================©Copyright蕃薯耀 2021-06-24https://www.cnblogs.com/fanshuyao/ 一、SpringBoot整合Mybatis1、pom.xml引入依赖(基于SpringBoot:2.3.12.REL 查看详情

转mybatis学习总结——mybatis缓存

【转】MyBatis学习总结(七)——Mybatis缓存一、MyBatis缓存介绍  正如大多数持久层框架一样,MyBatis同样提供了一级缓存和二级缓存的支持一级缓存:基于PerpetualCache的HashMap本地缓存,其存储作用域为Session,当Sessionflush或close... 查看详情

mybatis缓存

MyBatis缓存MyBatis缓存分为一级缓存和二级缓存一级缓存MyBatis的一级缓存指的是在一个Session域内,session为关闭的时候执行的查询会根据SQL为key被缓存(跟mysql缓存一样,修改任何参数的值都会导致缓存失效)1)单独使用MyBatis而不继承Spri... 查看详情

mybatis缓存

MyBatis缓存MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存默认情况下,只有一级缓存开启。(SqlSession级别的... 查看详情

mybatis缓存

mybatis的延迟加载和缓存技术开始 mybatis一级缓存  mybatis的二级缓存mybatis默认是没有开启二级缓存的。 开启二级缓存需要在mybatis的全局配置文件sqlMapConfig.xml中加入 除了开启二级缓存开关外,还需要在各自的map... 查看详情

mybatis的二级缓存

文章目录MyBatis的二级缓存MyBatis默认是开启一级缓存的开启MyBatis的二级缓存为什么要开启二级缓存在mybatis的配置文件中进行配置在对应的mapper映射文件中声明相关的DO对象需要实现序列化测试动态代理接口执行更新方法后会清空... 查看详情

mybatis缓存专题-一文彻底搞懂mybatis一级缓存(代码片段)

...不能使用2.什么是一级缓存3.什么情况下会命中一级缓存4.Mybatis的一级缓存机制详解5.MyBatis关闭一级缓存6.Mybatis的一级缓存机制源码分析7.Mybatis的一级缓存机制源码分析图解总结8.一级缓存什么时候被清空?9.一级缓存key是什... 查看详情

mybatis缓存专题-一文彻底搞懂mybatis一级缓存(代码片段)

...不能使用2.什么是一级缓存3.什么情况下会命中一级缓存4.Mybatis的一级缓存机制详解5.MyBatis关闭一级缓存6.Mybatis的一级缓存机制源码分析7.Mybatis的一级缓存机制源码分析图解总结8.一级缓存什么时候被清空?9.一级缓存key是什... 查看详情

mybatis0210mybatis和ehcache缓存框架整合

1.1mybatis和ehcache缓存框架整合一般不用mybatis来管理缓存而是用其他缓存框架在管理缓存,因为其他缓存框架管理缓存会更加高效,因为别人专业做缓存的而mybatis专业做sql语句的,mybatis二级缓存通过ehcache维护缓存数据。1.1.1分布... 查看详情

mybatis缓存机制

mybatis提供了缓存机制减轻数据库压力,提高数据库性能mybatis的缓存分为两级:一级缓存、二级缓存一级缓存是SqlSession级别的缓存,缓存的数据只在SqlSession内有效二级缓存是mapper级别的缓存,同一个namespace公用这一个缓存,所... 查看详情

mybatis一级缓存与二级缓存

MyBatis一级缓存  MyBatis一级缓存默认开启,一级缓存为Session级别的缓存,在执行以下操作时一级缓存会清空  1.执行session.clearCache();  2.执行CUD操作  3.session.close();//不是同一个Session对象了 MyBatis二级缓存  需要配... 查看详情

mybatis缓存

MyBatis的缓存正如大多数持久化框架一样,MyBatis提供了一级缓存和二级缓存的支持。1.一级缓存 一级缓存是基于perpetualCache(MyBatis自带)的HashMap本地缓存,作用范围为session域内,当sessionflush或者close之后,该session中所有的cac... 查看详情

mybatis——一级缓存二级缓存

一、Mybatis缓存●MyBatis包含一个非常强大的查询緩存特性,它可以非常方便地定制和配置缓存。绶存可以极大的提升查询效率。●MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存  ○ 默认情况下,只有一级缓存开启... 查看详情

ssm框架mybatis笔记---表之间的关联关系;mybatis事务;mybatis缓存机制;orm概述

MyBatis框架提供两级缓存,一级缓存和二级缓存,默认开启一级缓存。缓存就是为了提交查询效率MyBatis框架提供两级缓存,一级缓存和二级缓存,默认开启一级缓存。缓存就是为了提交查询效率 查看详情

mybatis三

1Mybatis的缓存1.1Mybatis的缓存机制Mybatis包含非常求昂达的查询缓存特性,它可以非常方便的配置和定制。缓存可以极大的提高查询效率。 Mybatis系统中默认定义了一级缓存和二级缓存。①默认情况下,只有一级缓存开启。②二... 查看详情

《深入理解mybatis原理4》mybatis缓存机制的设计与实现

《深入理解mybatis原理》MyBatis缓存机制的设计与实现本文主要讲解MyBatis非常棒的缓存机制的设计原理,给读者们介绍一下MyBatis的缓存机制的轮廓,然后会分别针对缓存机制中的方方面面展开讨论。MyBatis将数据缓存设计成两级结... 查看详情

mybatis缓存理解

缓存接触过hibernate的同学都知道hibernate中有个二级缓存,mybatis也存在二级缓存。mybatis中二级缓存有什么作用呢?mybatis提供查询缓存,可以提高查询效率,减轻数据库的压力。一级缓存一级缓存是session级别的缓存,基于PerpetualCa... 查看详情

mybatis缓存机制

MyBatis提供了一级缓存和二级缓存的支持。一级缓存一级缓存是基于PerpetualCache的HashMap本地缓存;一级缓存的作用域是SqlSession,即不同的SqlSession使用不同的缓存空间;一级缓存的开启和关闭一级缓存是默认开启的;关闭一级缓存... 查看详情