一起学习Mybatis----使用缓存

版权声明:本文为博主原创文章,转载请说明出处。 https://blog.csdn.net/weixin_43549578/article/details/85103532

    mybatis默认情况下是启用一级缓存的,它是SqlSession级别的,也即同一个SqlSession接口对象调用了相同的select语句,就会从缓存里面拿到,而不是再去查询一次数据库。默认情况下,select使用缓存,增删改不使用。当 Session flush 或 close 之后,该Session中的所有 Cache 就将清空。

2.二级缓存:以mapper为单位划分区域,对于访问多的查询请求且用户对查询结果实时性要求不高,此时可采用mybatis二级缓存技术降低数据库访问量,提高访问速度,但是对细粒度的数据级别的缓存实现不好。其主要特性是不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句
   
3.外部缓存:第三方提供的缓存框架
作用域:
正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持;
       一级缓存基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该Session中的所有 Cache 就将清空。
 
       二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache、Hazelcast等。

Mybatis缓存分为:一级缓存和二级缓存。

一级缓存:默认会被使用

         Mybatis内部缓存是使用了一个HashMap,map数据结构需要key/value。 key:hashCode+查询的SqlId+编写的sql查询语句。value:执行上面的查询所获得java对象。一级缓存作用域是SqlSession,每次查询先找缓存,找到使用,找不到再从数据库查询。查询到数据将数据写入缓存。
缓存启效前提条件:

  • 查询条件一样
  • 必须是同一个sqlSession,如果关闭过一次,那就另外算了。
  • 没有执行过sqlSession.clearCache();
  • 没有执行过增删改,sqlSession执行insert、update、delete等操作, commit提交后会清空缓存区域。

 二级缓存:

mybatis-config.xml配置中开启显示的定义二级缓存:

       

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

   注意:用二级缓存时entity类必须实现序列化接口 

  添加一个<cache>在xxx.xml

   <cache  eviction="FIFO"  flushInterval="60000"  size="512"  readOnly="true"/>

上面的配置意思如下:
 创建了FIFO的策略,每个1分钟刷新一次,存512个对象而且返回的对象被认为是只读的。
 
 
eviction:缓存的回收策略
 flushInterval:时间间隔,单位是毫秒,
size:引用数目,内存大就多配置点,要记住你缓存的对象数目和你运行环境的可用内存资源数目。默认值是1024
readOnly:true,只读
 
 
四大策略:
1.LRU – 最近最少使用的:移除最长时间不被使用的对象,它是默认
2.FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
3.SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
4.WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

  禁用二级缓存:设置useCache=false可以禁用当前select语句的二级缓存,即每次查询都会发出sql去查询,
默认情况是true,即该sql使用二级缓存。

刷新(清空)二级缓存:

 <update id="updateUser" parameterType="User" flushCache="true">
 UPDATE tbl_user SET NAME=#{name},age=#{age} WHERE id=#{id}
 </update>

   insert、update、delete操作数据后需要刷新缓存,如果不执行刷新缓存会出现脏读,所以默认为true,
默认情况下为true即刷新缓存,一般不用修改,知道即可。flushCache="true".

要想使某条 Select查询支持二级缓存的前提条件:

1. MyBatis支持二级缓存的总开关:全局配置变量参数 cacheEnabled=true
 <settings>
   <setting name="cacheEnabled" value="true"/>
 </settings>
 
2. 该select语句所在的Mapper,配置了<cache> 节点且有效
 
3. 该select语句的参数 useCache=true 

一级缓存和二级缓存的使用顺序:

   如果你的 MyBatis 使用了二级缓存,并且你的 Mapper 和 select 语句也配置使用了二级缓存,那么在执行 select 查询的时候, MyBatis 会先从二级缓存中取输入,其次才是一级缓存,即 MyBatis 查询数据的顺序是:
    二级缓存 ----->  一级缓存  -----> 数据库 

  总结:

  • Mybatis二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句。
  • Mybatis显示定义开启二级缓存,需要在setting全局参数中配置。

第三方缓存框架:Ehcache

     EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider。其是一个快速的、轻量级的、易于使用的、进程内的缓存。它支持read-only 和 read/write 缓存,内存和磁盘缓存。是一个非常轻量级的缓存实现,而且从 1.2 之后就支持了集群。

 EhCache三层:

    CacheManager:是缓存管理器,可以通过单例或者多例的方式创建,也是Ehcache的入口类。
    Cache:每个CacheManager可以管理多个Cache,每个Cache可以采用hash的方式管理多个Element。
    Element:用于存放真正缓存内容的。

Ehcache采用的是懒淘汰机制,每次往缓存放入数据的时候,都会存一个时间,在读取的时候要和设置的时间做TTL比较来判断是否过期。

ehcache.xml配置:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
 
 <diskStore path="java.io.tmpdir"/>
 
 <defaultCache 
   maxElementsInMemory="1000" 
   maxElementsOnDisk="10000000"
   eternal="false" 
   overflowToDisk="false" 
   timeToIdleSeconds="120"
   timeToLiveSeconds="120" 
   diskExpiryThreadIntervalSeconds="120"
   memoryStoreEvictionPolicy="LRU">
 </defaultCache>
</ehcache>
 
<!-- 
属性说明:
l diskStore:指定数据在磁盘中的存储位置。
l 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(先进先出)
-->

具体查看API:http://tool.oschina.net/apidocs/apidoc?api=ehcache2.5.2

官网:http://www.ehcache.org/documentation/

猜你喜欢

转载自blog.csdn.net/weixin_43549578/article/details/85103532