spring boot 集成 ehCache

本文分享了在SpringBoot项目中集成ehCache缓存的过程,包括常见问题及解决方法,如配置过期时间、实体类序列化等。通过具体步骤和代码示例,帮助读者快速上手。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说明

       今天在做统计报表的时候,考虑到数据比较多,所以在项目中集成ehCache减轻数据库请求压力。看似简单,网上参考也比较多,但是还遇到了几处坑,在此记录一下。 ⊙﹏⊙b

随手笔记,比较简单,想要具体了解的可以网上看看大神的博客

问题

    (1)、springboot集成了ehcache,配置了过期时间timeToIdleSeconds,发现就是不生效,问度娘后才知道需要在properties文件中指定缓存类型,不然spring boot 使用默认SimpleCacheConfiguration,不是用的ehcache。

   (2)、测试的时候第一次请求接口返回正常数据,第二次查询缓存的时候会报java.io.Serializable这个错,是因为我返回的实体类没做序列化。

               解决方案在下面

1、首先引入依赖在pom.xml文件中

 <!--开启 cache 缓存-->
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-cache</artifactId>
      </dependency>
      <!-- ehcache 缓存 -->
      <dependency>
          <groupId>net.sf.ehcache</groupId>
          <artifactId>ehcache</artifactId>
      </dependency>

2、引入配置文件 ehcache.xml(自己手残名字写错ehcach,导致启动报错,加载不到配置,懵逼。。。。。)

<?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="java.io.tmpdir"/>
  <!--defaultCache:echcache的默认缓存策略  -->
  <!--
        缓存配置
           diskStore:指定数据在磁盘中的存储位置。
           name:缓存名称。
           defaultCache:当借助CacheManager.add("demoCache")创建Cache时,EhCache便会采用<defalutCache/>指定的的管理策略,以下属性是必须的:
           maxElementsInMemory:缓存最大个数。
           eternal:对象是否永久有效,一但设置了,timeout将不起作用。
           timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
           timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
           overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。
           diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
           maxElementsOnDisk:硬盘最大缓存个数。
           diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
           diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
           memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
           clearOnFlush:内存数量最大时是否清除。
    -->
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            maxElementsOnDisk="10000000"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
        <persistence strategy="localTempSwap"/>
    </defaultCache>
    <cache name="userCache"
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            maxElementsOnDisk="10000000"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
        <persistence strategy="localTempSwap"/>
    </cache>
</ehcache>

3、在properties文件中指定缓存类型和加载xml,也就是我上面说的问题 ”(1)“。xml也可以用@ImportResource注解直接在spring boot启动类配置。

spring.cache.type=ehcache
spring.cache.ehcache.config=classpath:META-INF/mybatis/ehcache.xml

4、在spring boot 启动类也要开启缓存注解@EnableCaching,否则缓存不生效。如下

43a7eb8cbc7d34c1d991c174c0c31ad9457.jpg

 

5、以上集成工作已经完成,那如何在代码中使用呢? 如下

/**
	 * 查询请求记录数据统计
	 * 
	 * @param docNos
	 * @return
	 */
	@Cacheable(key = "#startDate+'-'+#endDate+'-'+#type",value="userCache")
	public ResponseMessage<List<Map<String, Object>>> selectReport(String startDate, String endDate, String docTemplateCode,String type) {
		ResponseMessage<List<Map<String, Object>>> rsdto = new ResponseMessage<>();
		List<Map<String, Object>> list=new ArrayList<>();
		if(StringUtils.isBlank(startDate) || StringUtils.isBlank(endDate)) {
			ResponseUtil.setResult(rsdto, null, ErrorCodeEnum.PARAMERROR, false);
			return rsdto;
		}
		/*if(StringUtils.isBlank(docTemplateCode)) {
			ResponseUtil.setResult(rsdto, null, ErrorCodeEnum.PARAMERROR, false);
			return rsdto;
		}*/
		if(StringUtils.isBlank(type)) {
			ResponseUtil.setResult(rsdto, null, ErrorCodeEnum.PARAMERROR, false);
			return rsdto;
		}
		Integer length=0;
		try {
		    length= ReportTypeEnum.getEnum(type).getValue();
		    list=docRecordTunnel.selectReportByDateTime(startDate, endDate, docTemplateCode, length);
			ResponseUtil.setResult(rsdto, list, ErrorCodeEnum.SUCCESS,true);
		} catch (Exception e) {
			log.error("DocRecordController.selectReport查询失败", e);
			ResponseUtil.setResult(rsdto, null, ErrorCodeEnum.ERROR, false);
		}
		return rsdto;
	}

 

注: 返回的实体类需要做序列化,否则查询缓存的时候会报错。如下图

953988c77b3cd7c45e1bd7eed8122659c51.jpg

 

一般情况下,我们在Sercive层进行对缓存的操作。先介绍 Ehcache 在 Spring 中的注解:
* @Cacheable : Spring在每次执行前都会检查Cache中是否存在相同key的缓存元素,如果存在就不再执行该方法,而是直接从缓存中获取结果进行返回,否则才会执行并将返回结果存入指定的缓存中。
* @CacheEvict : 清除缓存。 
* @CachePut : @CachePut也可以声明一个方法支持缓存功能。使用@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。 

简单来说,Cacheable 一般用于查询,CacheEvict 用于新增清除缓存,CachePut 用于更新;其中,value 指的是 ehcache.xml 中的缓存策略空间;key 指的是缓存的标识,同时可以用 # 来引用参数。上面代码引用参数为多个组合作为缓存key 。

5、启动项目,测试结果。具体代码我就不再贴了。

 

 

转载于:https://my.oschina.net/u/3647421/blog/3066459

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值