一、简介
(1)Ehcache 缓存简介
Ehcache 是一个纯Java的进程内缓存框架,具有快速上手简单等特点,是 hibernate 中默认的缓存提供方;
(2)hibernate 缓存
hibernate 三级缓存机制简介:
- 一级缓存:基于 session 级别分配一块缓存空间,缓存访问的对象信息。session 关闭后会自动清除缓存。
- 二级缓存:是 sessionFactory 对象缓存,可以被创建多个 session对象共享,二级缓存默认是关闭的,如果需要使用需要手动开启,并且依赖 Ehcache 组件。
- 三级缓存:查询缓存,配置开启改缓存的情况下,重复使用下一个 SQL 查询某个范围内数据,会进行缓存。
(3)Ehcache 缓存特点
-
快速、简单、并且提供多种缓存策略;
-
缓存数据有两级:内存 和 磁盘,无需担心容量问题;
-
缓存数据会在虚拟机重启的过程中写入磁盘;
-
可以通过 RMI、可插入API 等方式进行分布式缓存;
-
具有缓存和缓存管理器的侦听接口;
-
支持多缓存管理器实例,以及一个实例的多个缓存区域;
-
提供 hibernate 的缓存实现;
(4)Ehcache 和 redis 区别
-
Ehcache:直接 再 JVM 虚拟中缓存,速度快,效率高,不适合处理大规模缓存数据,在分布式环境下,缓存数据共享操作复杂;
-
Redis:作为独立的缓存中间件,在分布式缓存系统中非常好用,缓存数据共享,有效支撑大量数据缓存,支持哨兵模式,集群模式 等高可用的成熟方案;
二、SpringBoot 整合 Ehcache
(1)引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
(2)配置application.yml
spring:
cache:
ehcache:
config: classpath:ehcache.xml
(3)编写 ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<!--
diskStore:为缓存路径,ehcache分为内存和磁盘两级,此属性定义磁盘的缓存位置,可以自定义目录,确保用户有权限即可。参数解释如下:
user.home – 用户主目录
user.dir – 用户当前工作目录
java.io.tmpdir – 默认临时文件路径
-->
<!-- 操作系统缓存的临时目录,内存满后写入该目录 -->
<diskStore path="java.io.tmpdir"/>
<!-- <diskStore path="C:/Users/admin/ehcache/"/> -->
<defaultCache
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
maxElementsOnDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
<persistence strategy="localTempSwap"/>
</defaultCache>
<!-- 注意:这里的 userEntity 需要和 @Cacaheable 中的 value 或 cacheNames 对应上 -->
<cache name="userEntity"
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
maxElementsOnDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
<persistence strategy="localTempSwap"/>
</cache>
<!-- maxElementsInMemory:内存中最大缓存对象数,根据服务器资源配置 -->
<!-- eternal: 默认为false,设置true表示对象永不过期,此时会忽略timeToIdleSeconds和timeToLiveSeconds属性, -->
<!-- maxElementsOnDisk:硬盘中最大缓存对象数,若是0表示无穷大 -->
<!-- overflowToDisk:true表示当内存缓存的对象数目达到了maxElementsInMemory界限后,会把溢出的对象写到硬盘缓存中。
注意:如果缓存的对象要写入到硬盘中的话,则该对象必须实现了Serializable接口才行。-->
<!-- diskSpoolBufferSizeMB:磁盘缓存区大小,默认为30MB。每个Cache都应该有自己的一个缓存区。-->
<!-- diskPersistent:是否缓存虚拟机重启期数据 -->
<!-- diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认为120秒 -->
<!-- timeToIdleSeconds: 设定允许对象处于空闲状态的最长时间,单位(秒)。自对象最近一次被访问后,
空闲时间超过了timeToIdleSeconds属性值,这个对象就会过期,如果该属性值为0,则对象无限期地处于空闲状态
EHCache将把它从缓存中清空。只有当eternal属性为false,该属性才有效。
-->
<!-- timeToLiveSeconds:设定允许对象存在于缓存中的最长时间,单位(秒)。自对象被存放到缓存中后,
在缓存中的时间超过了timeToLiveSeconds属性值,这个对象就会过期,如果该属性值为0,则对象无限期地存在于缓存中。
EHCache将把它从缓存中清除。只有当eternal属性为false,该属性才有效。timeToLiveSeconds必须大于timeToIdleSeconds属性,才有意义 -->
<!-- memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。
可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。-->
</ehcache>
配置参数说明:
- maxElementsInMemory:磁盘缓存中最多可以存放的元素数量;
- eternal:缓存中对象是否永久有效;
- timeToIdleSeconds:当 eternal=false 时使用,缓存数据有效期(单位:秒),时间段内没有访问该元素,将被清除;
- timeToLiveSeconds:缓存数据的存活时间;
- maxElementsInMemory:内存中最多可以存放的元素数量,overflowToDisk=true,则会将 Cache 中多出的元素放入磁盘文件中,若 overflowToDisk=false,则根据 memoryStoreEvictionPolicy 策略替换 Cache 中原有的元素;
- diskExpiryThreadIntervalSeconds:磁盘缓存的清理线程运行间隔;
- memoryStoreEvictionPolicy:缓存释放策略,LRU 会优先清理最少使用的缓存;
- localTempSwap:持久化策略,当堆内存或者非堆内存里面的元素已经满了的时候,将其中的元素临时的存放再磁盘上,重启后就会消失;
(4)添加启动类注解
@EnableCaching // Ehcache 开启注解
@SpringBootApplication
public class Application {
public static void main(String[] args) {SpringApplication.run(Application.class,args) ;}
}
(5)使用示例
@Service
public class CacheService {
private static final Logger LOGGER = LoggerFactory.getLogger(CacheService.class);
@Resource
private UserMapper userMapper;
// 在缓存有效期内,首次查询才访问数据库
@Cacheable(value="userEntity")
public UserEntity getById(Integer id) {
LOGGER.info("getById..." + id); // 通过日志,标识方法是否执行
return userMapper.selectById(id);
}
// 该ID数据数据更新,清空该ID缓存
@CacheEvict(value="userEntity", key="#id")
public void updateUser(Integer id) {
UserEntity user = new UserEntity();
user.setId(id);
user.setUserName("myName");
userMapper.updateById(user);
}
}
注解详解:
-
@Cacheable:注解标记在一个方法上,也可以标记在一个类上。(标记在一个方法上 标识该方法支持缓存,该方法被调用后将其返回值缓存起来,下次同样的请求参数职系那个该方法时可以直接从缓存中获取结果,而不需要再次执行该方法。)
-
@CacheEvit:注解标记在需要清除缓存元素的方法或类上的。(标记在类上时,表示其中所有的方法的执行都会触发缓存的清除操作,并且可以按照指定属性清除。)
-
@CacheConfig:声明在类上,指定本类上所有使用缓存的方法的缓存名称,如有注解@Cacheable的方法。
-
@Cacheable:使用@Cacheable注解的方法,Spring在每次执行前都会检查Cache中是否存在相同key的缓存元素,如果存在就不再执行该方法,而是直接从缓存中获取结果进行返回,如果存在则执行方法,并将返回结果存入指定的缓存中 -
@CachePut:使用@CachePut注解的方法,Spring在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中;
@CachePut(key = "#user.id") public User updateUserById(User user) { return user; } -
@CacheEvict:清除缓存,属性allEntries为true则删除所有缓存,属性beforeInvocation表示缓存的清除是在方法前执行还是方法后执行,默认是为false,方法执行后删除;
@CacheEvict(beforeInvocation=false) public void deleteUserById(Integer id) { //去数据库中删除(CacheEvict 属性 beforeInvocation=false 在删除数据库之后删除,=true则是删除数据库之前删除) } -
@Caching:分组注解,可以包含多个@Cacheable和@CachePut,一般在复杂业务的情况下使用
附录
- 官网地址:Ehcache(www.ehcache.org/)Documentation (ehcache.org)
- GitHub 地址:ehcache · GitHub(github.com/ehcache)