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
需求緣起:
有人咨詢博主,如下問題:
對於這個問題,試一下就知道怎麽回事了,好了,這篇博客就是為了解答此問題。
本節大綱:
(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); }
查看控制臺的打印信息:
com.kfit.ehcachedemo.Person@ea1a8d5 //從緩存中獲取到對象.
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是否能被緩存?