1. 程式人生 > >Spring Boot Ehcache使用@Cacheable同key不同value是否能被緩存?

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

spring boot

【視頻&交流平臺】

à 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);
    }


查看控制臺的打印信息:

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是否能被緩存?