文章目录
一、mybatis中的缓存
1.什么是缓存:
缓存是一般的ORM 框架都会提供的功能,目的就是提升查询的效率和减少数据库的压力。跟Hibernate 一样,MyBatis 也有一级缓存和二级缓存,并且预留了集成第三方缓存的接口。
MyBatis 跟缓存相关的类都在cache 包里面,其中有一个Cache 接口,只有一个默认的实现类 PerpetualCache,它是用HashMap 实现的。
缓存的适用:
经常查询并不经常改变的数据【可以使用缓存】
2.一级缓存:
① 进行select查询后会生成响应的sql语句的缓存。
② 对于缓存的内容,其实是是保存在map中的(可以debug进行查看)
③ Mybatis中的一级缓存是默认开着的(LRU – 最近最少使用)
④ 一级缓存的作用域在一次sqlSession中有效(sqlSession.close()前)
⑤ 在一个sqlSession中,如果有增删改操作,那么该sqlSession中的缓存将不能再使用,因为增删改可能改变原数据
手动清除缓存:sqlSession.clearCache()
3.二级缓存(全局缓存):
①.一级缓存的作用域太低,所以需要二级缓存
②.是基于namespace级别的缓存,一个命名空间,对应一个二级缓存.二级缓存的作用域是一个xxxMapper.xml
③.工作机制:
①一个会话查询的信息A,该数据会首先被存放到一级缓存中
②如果当今会话关闭,那么当前会话中一级缓存的内容将会存放到二级缓存中
③新的会话查询的信息A,可以直接从二级缓存中取
④不同的map查询的结果会存放在自己对应的缓存(map)中
4.开启全局缓存的步骤:
①.设置mybatis的核心配置文件mybatis-config.xml
<settings>
<setting name="cacheEnabled" value="true" />
</settings>
②.要启用全局的二级缓存,只需要在你的 SQL 映射文件(xxxMapper.xml)中添加一行:
<cache/>
当然也可以进行修改配置:
<cache
eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true"/>
这个更高级的配置创建了一个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此对它们进行修改可能会在不同线程中的调用者产生冲突。
可用的清除策略有:
- LRU – 最近最少使用:移除最长时间不被使用的对象。
- FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
- SOFT – 软引用:基于垃圾回收器状态和软引用规则移除对象。
- WEAK – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。
默认的清除策略是 LRU。
名词解释:
-
flushInterval(刷新间隔)属性可以被设置为任意的正整数,设置的值应该是一个以毫秒为单位的合理时间量。 默认情况是不设置,也就是没有刷新间隔,缓存仅仅会在调用语句时刷新。
-
size(引用数目)属性可以被设置为任意正整数,要注意欲缓存对象的大小和运行环境中可用的内存资源。默认值是 1024。
-
readOnly(只读)属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓存对象的相同实例。 因此这些对象不能被修改。这就提供了可观的性能提升。而可读写的缓存会(通过序列化)返回缓存对象的拷贝。 速度上会慢一些,但是更安全,因此默认值是 false。
提示 :
二级缓存是事务性的。这意味着,当 SqlSession 完成并提交时,或是完成并回滚,但没有执行 flushCache=true 的 insert/delete/update 语句时,缓存会获得更新。
③.养成一个好的习惯,对于实体类,实现序列化接口,避免不必要的麻烦
5.特点:
①. 映射语句文件中的所有 select 语句的结果将会被缓存。
②. 映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。
③. 缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
④. 缓存不会定时进行刷新(也就是说,没有刷新间隔)。
⑤. 缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用。
⑥. 缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。
6.缓存中的执行顺序(原理):
①.查看二级缓存有没有要是使用的数据,没有执行②
②.查看一级缓存没有要是使用的数据,没有执行③
③.查询数据库,并执行④
④.存到一级缓存中,当关闭SQLSession时,执行⑤
⑤.存到二级缓存中
二、第三方缓存-Ehcache
1.介绍:
Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存,Java EE和轻量级容器。
2.使用步骤
①. maven依赖:
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-ehcache -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.0.0</version>
</dependency>
②.在相关的xxxMapper.xml中使用ehcache
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
③.创建并编写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="java.io.tmpdir/Tmp_EhCache"/>
<!--
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,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
-->
<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"/>
</ehcache>
注意:我试了,但是不能用,因为在ehcache.xml抓取不到xsi:noNamespaceSchemaLocation