Spring Boot Ehcache使用@Cacheable同key不同value是否能被缓存?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Boot Ehcache使用@Cacheable同key不同value是否能被缓存?相关的知识,希望对你有一定的参考价值。
【视频&交流平台】
http://study.163.com/course/introduction.htm?courseId=1004329008
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使用数组配置了多个,那么会是什么结果呢?自己试试吧!
本文出自 “11132439” 博客,请务必保留此出处http://11142439.blog.51cto.com/11132439/1978566
以上是关于Spring Boot Ehcache使用@Cacheable同key不同value是否能被缓存?的主要内容,如果未能解决你的问题,请参考以下文章
使用 EhCache 进行 Spring Boot 缓存不起作用
Spring Boot 2.x基础教程:EhCache缓存的使用
Spring Boot Oauth2缓存UserDetails到Ehcache
spring boot spring cache ehcache3.x整合