Spring Boot Ehcache使用@Cacheable同key不同value是否能被缓存?

【视频&交流平台】

à SpringBoot网易云课堂视频

http://study.163.com/course/introduction.htm?courseId=1004329008

à Spring Boot交流平台

http://412887952-qq-com.iteye.com/blog/2321532



需求缘起:

有人咨询博主,如下问题:


 

上面的问题翻译下就是:使用@Cacheable同key不同value是否能被缓存?

对于这个问题,试一下就知道怎么回事了,好了,这篇博客就是为了解答此问题。

本节大纲:

(1)问题1:@Cacheable中的value代表什么?

(2)问题2:value对应的ehcache.xml的缓存策略是怎么定义的?

(3)验证1:EHCache不同cache缓存同一个key第二次是否可以缓存?

(4)验证2:@Cacheable同一个key不同的value是否会缓存?

(5)提问:在value中配置了多个,会是什么情况?

接下来看下具体的内容:

(1)问题1:@Cacheable中的value代表什么?

看如下代码:

    @Cacheable(value="demo",key="‘demoInfo_‘+#id")
    @Override
    public DemoInfofindByIdTT(Long id){
       System.err.println("findByIdTT-->没有走缓存!,id="+id);
       returndemoInfoRepository.findOne(id);
    }

在使用@Cacheable的时候,有一个配置value,这是是表示什么呢?

value属性表示使用哪个缓存策略,缓存策略在ehcache.xml。

(2)问题2:value对应的ehcache.xml的缓存策略是怎么定义的?

我们看ehcache.xml的定义:

  <cache
       name="demo"   
       eternal="false"
       maxElementsInMemory="100"
       overflowToDisk="false"
       diskPersistent="false"
       timeToIdleSeconds="0"
       timeToLiveSeconds="300"
memoryStoreEvictionPolicy="LRU" />

这个name:缓存对象的名称,那么这个名称有什么作用呢?

我们可以通过定义不同的name,声明不同的缓存对象:缓存算法、缓存超时时间、缓存最大数目。不同不同的name会创建不同的cache对象。

cache:缓存管理器内可以放置若干cache,存放数据的实质,所有cache都实现了Ehcache接口,这是一个真正使用的缓存实例;通过缓存管理器的模式,可以在单个应用中轻松隔离多个缓存实例,独立服务于不同业务场景需求,缓存数据物理隔离,同时需要时又可共享使用。

所以从这句话可以看出,在单个应用中多个不同的cache之间是不同的缓存实例。那么对于同一个key,不同的缓存对象缓存信息也就没法生效了。

(3)验证1:EHCache不同cache缓存同一个key第二次是否可以缓存?

这个代码大家可以自己编写,这里提供一个样例:

  @Test
    public void testEHCache(){
       //此CACHE_NAME、CACHE_NAME2需要在配置文件ehcache.xml 中存在.
       final String CACHE_NAME = "sampleCache1";
       final String CACHE_NAME2 = "sampleCache2";
       String key20 = "person20";
        Person person20 = new Person("person20", 20);
       EHCacheStorage.getInstance().put(CACHE_NAME, key20, person20);
       
       Person p20 = (Person)EHCacheStorage.getInstance().get(CACHE_NAME, key20);
       System.out.println(p20);
       Person p20_2 =(Person)EHCacheStorage.getInstance().get(CACHE_NAME2, key20);
       System.out.println(p20_2);
    }

查看控制台的打印信息:

[email protected] //从缓存中获取到对象.

null //未获取到.

所以不同的cache对象是独立的。

(4)验证2:@Cacheable同一个key不同的value是否会缓存?

代码如下:

  @Cacheable(value="demo",key="‘demoInfo_‘+#id")
    @Override
    public DemoInfo findById1(Long id){
       System.err.println("findById1-->没有走缓存!,id="+id);
       return demoInfoRepository.findOne(id);
    }
 
    @Cacheable(value="demoTT",key="‘demoInfo_‘+#id")
    @Override
    public DemoInfofindByIdTT(Long id){
       System.err.println("findByIdTT-->没有走缓存!,id="+id);
       return demoInfoRepository.findOne(id);
    }

测试代码:

@RequestMapping("/findById4")
    public String findById4(longid){
       System.out.println("findById4请求-->id="+id);
       System.out.println(demoInfoService.findById1(id));
       System.out.println(demoInfoService.findById1(id));
       System.out.println(demoInfoService.findByIdTT(id));
       return "ok";
    }

打印信息:

findById4请求-->id=2

findById1-->没有走缓存!,id=2

Hibernate: select demoinfo0_.id as id1_0_0_, demoinfo0_.name asname2_0_0_, demoinfo0_.pwd as pwd3_0_0_, demoinfo0_.state as state4_0_0_ fromdemo_info demoinfo0_ where demoinfo0_.id=?

DemoInfo [id=2, name=张三,pwd=123456, state=0]

DemoInfo[id=2, name=张三, pwd=123456, state=0]//第二查询就直接从缓存中获取了。

findByIdTT-->没有走缓存!,id=2//这个是不同的valu,所以没有走缓存。

DemoInfo [id=2, name=张三, pwd=123456, state=0]

注意:这里要特别说明的地方,也就是【findByIdTT-->没有走缓存】但是并没有进行select查询打印,这个是为什么,这个就是说到jpa的一级缓存(也叫session缓存),jpa直接从以及缓存中进行获取了,所以没有走数据库查询。(对于一级缓存,不清楚的小盆友,可以自行查资料了解)。

那么怎么模拟不走一级缓存呢?很简单,变成两个请求即可,如下:

   @RequestMapping("/findById4_1")
    public String findById4_1(longid){
       System.out.println("findById4_1请求-->id="+id);
       System.out.println(demoInfoService.findById1(id));
       System.out.println(demoInfoService.findById1(id));
       return "ok";
    }
    
    @RequestMapping("/findById4_2")
    public String findById4_2(longid){
       System.out.println("findById4_2请求-->id="+id);
       System.out.println(demoInfoService.findByIdTT(id));
       return "ok";
    }

先访问http://127.0.0.1:8080/findById4_1?id=2

在访问2:http://127.0.0.1:8080/findById4_2?id=2

打印结果如下:

findById4_1请求-->id=2

findById1-->没有走缓存!,id=2

Hibernate: select demoinfo0_.id as id1_0_0_, demoinfo0_.name asname2_0_0_, demoinfo0_.pwd as pwd3_0_0_, demoinfo0_.state as state4_0_0_ fromdemo_info demoinfo0_ where demoinfo0_.id=?

DemoInfo [id=2, name=张三,pwd=123456, state=0]

DemoInfo[id=2, name=张三, pwd=123456, state=0]

findById4_2请求-->id=2

findByIdTT-->没有走缓存!,id=2

Hibernate: select demoinfo0_.id as id1_0_0_, demoinfo0_.name asname2_0_0_, demoinfo0_.pwd as pwd3_0_0_, demoinfo0_.state as state4_0_0_ fromdemo_info demoinfo0_ where demoinfo0_.id=?

DemoInfo [id=2, name=张三, pwd=123456, state=0]

好了,结论已经很明显了,就解答到这里。

(5)提问:在value中配置了多个,会是什么情况?

如下代码:

    @Cacheable(value={"demo","demoTT"},key="‘demoInfo_‘+#id")
    @Override
    public DemoInfo findById1(Long id){
       System.err.println("findById1-->没有走缓存!,id="+id);
       return demoInfoRepository.findOne(id);
    }

在这里value使用数组配置了多个,那么会是什么结果呢?自己试试吧!

时间: 2024-08-07 11:41:39

Spring Boot Ehcache使用@Cacheable同key不同value是否能被缓存?的相关文章

spring boot redis序列化key-value时key值前面出现多余值

参考网址:https://blog.csdn.net/yunhaibin/article/details/9001198# 业务涉及将之前的一主二从redis集群改造后5主5从的redis集群,改造完成后发现一个问题,往redis里面写数据时,key值钱面会出现多余的值(比正常的key值里面多了个t6),如下图 用redis链接客户端访问时,会显示乱码,如下图 经参考大神文章,在redis.xml配置增加redis序列化相关匹配信息解决 <bean id="redisTemplate&qu

Spring Boot缓存应用实践

缓存是最直接有效提升系统性能的手段之一.个人认为用好用对缓存是优秀程序员的必备基本素质. 本文结合实际开发经验,从简单概念原理和代码入手,一步一步搭建一个简单的二级缓存系统. 一.通用缓存接口 1.缓存基础算法 (1).FIFO(First In First Out),先进先出,和OS里的FIFO思路相同,如果一个数据最先进入缓存中,当缓存满的时候,应当把最先进入缓存的数据给移除掉.(2).LFU(Least Frequently Used),最不经常使用,如果一个数据在最近一段时间内使用次数很

Spring Boot 2.X整合Spring-cache,让你的网站速度飞起来

计算机领域有人说过一句名言:“计算机科学领域的任何问题都可以通过增加一个中间层来解决”,今天我们就用Spring-cache给网站添加一层缓存,让你的网站速度飞起来. 本文目录 一.Spring Cache介绍二.缓存注解介绍三.Spring Boot+Cache实战1.pom.xml引入jar包2.启动类添加@EnableCaching注解3.配置数据库和redis连接4.配置CacheManager5.使用缓存注解6.查看缓存效果7.注意事项 一.Spring Cache介绍 Spring

Spring Boot 和 Redis 常用操作

1    第4-2课:Spring Boot 和 Redis 常用操作 Redis 是目前使用最广泛的缓存中间件,相比 Memcached,Redis 支持更多的数据结构和更丰富的数据操作,另外 Redis 有着丰富的集群方案和使用场景,这一课我们一起学习 Redis 的常用操作. 1.1    Redis 介绍 Redis 是一个速度非常快的非关系数据库(Non-Relational Database),它可以存储键(Key)与 5 种不同类型的值(Value)之间的映射(Mapping),可

以Spring整合EhCache为例从根本上了解Spring缓存这件事(转)

前两节"Spring缓存抽象"和"基于注解驱动的缓存"是为了更加清晰的了解Spring缓存机制,整合任何一个缓存实现或者叫缓存供应商都应该了解并清楚前两节,如果只是为了快速的应用EhCache到Spring项目中,请直接前往第三节"Spring整合EhCache缓存". 一.   Spring缓存抽象 1.       注意和核心思想 Spring自身并没有实现缓存解决方案,但是对缓存管理功能提供了声明式的支持,能够与多种流行的缓存实现进行集成.

spring boot学习(十三)SpringBoot缓存(EhCache 2.x 篇)

SpringBoot 缓存(EhCache 2.x 篇) SpringBoot 缓存 在 Spring Boot中,通过@EnableCaching注解自动化配置合适的缓存管理器(CacheManager),Spring Boot根据下面的顺序去侦测缓存提供者: * Generic * JCache (JSR-107) * EhCache 2.x * Hazelcast * Infinispan * Redis * Guava * Simple 关于 Spring Boot 的缓存机制: 高速缓

Spring Boot 集成 Ehcache 缓存,三步搞定!

本次内容主要介绍基于Ehcache 3.0来快速实现Spring Boot应用程序的数据缓存功能.在Spring Boot应用程序中,我们可以通过Spring Caching来快速搞定数据缓存. 接下来我们将介绍如何在三步之内搞定 Spring Boot 缓存. 1. 创建一个Spring Boot工程 你所创建的Spring Boot应用程序的maven依赖文件至少应该是下面的样子: <?xml version="1.0" encoding="UTF-8"?

Spring Boot整合EhCache

本文讲解Spring Boot与EhCache的整合. 1 EhCache简介 EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点,是Hibernate中默认CacheProvider.Ehcache是一种广泛使用的开源Java分布式缓存.主要面向通用缓存,Java EE和轻量级容器.它具有内存和磁盘存储,缓存加载器,缓存扩展,缓存异常处理程序,一个gzip缓存servlet过滤器,支持REST和SOAP api等特点. 2 Spring Boot整合EhCache步骤 2.

Spring 4 Ehcache Configuration Example with @Cacheable Annotation

http://www.concretepage.com/spring-4/spring-4-ehcache-configuration-example-with-cacheable-annotation Spring 4 Ehcache Configuration Example with @Cacheable Annotation By Arvind Rai, March 16, 2015 In this page, we will learn Spring 4 Ehcache configu