最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot中cache使用的實現(xiàn)示例

 更新時間:2025年10月23日 08:29:50   作者:九丶弟  
本文主要介紹了SpringBoot中cache使用的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

對于SpringBoot的Cache,其實已經(jīng)有很多文章對使用說明、底層詳解等各個角度進(jìn)行了講解。
本文則會結(jié)合更加詳細(xì)的使用場景,對cache的存儲和查詢邏輯進(jìn)行說明。

緩存的增刪改查

查詢數(shù)據(jù)列表

先看一段代碼

@Cacheable(value = "devices")
public Set<Integer> getAllDeviceId() {
    LambdaQueryWrapper<DevicePo> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(DevicePo::getIsDelete,false);
    List<DevicePo> devicePos = deviceMapper.selectList(queryWrapper);
    if(CollectionUtils.isEmpty(devicePos)){
        return Collections.emptyList();
    }
    Set<Integer> deviceIds = devicePos.stream().collect(Collectors.toMap(DevicePo::getDeviceId, DevicePo::getDeviceName)).keySet();
    return deviceIds;
}

使用@Cacheable可以讀取數(shù)據(jù)并存儲到緩存中,這比較好理解。 在這里value則是代表了一個緩存池(請允許我暫時先這么叫),表示從數(shù)據(jù)庫查詢出的數(shù)據(jù)會保存到名為devices的緩存池中。
在下次調(diào)用時,則會先檢測緩存池devices中是否有數(shù)據(jù),如果有數(shù)據(jù),就直接返回,沒有數(shù)據(jù)就執(zhí)行方法,產(chǎn)生新的數(shù)據(jù)。

為什么返回的是id集合?而不是數(shù)據(jù)集合?

在還沒有講到新增和刪除緩存數(shù)據(jù)時,可以理解為,是為了節(jié)省內(nèi)存的占用。
如果緩存的是數(shù)據(jù)集合,當(dāng)有一個【根據(jù)id獲取數(shù)據(jù)的方法時】就會造成內(nèi)存中緩存了兩份數(shù)據(jù),這無疑造成了緩存的浪費。
本質(zhì)上,你可以理解,在緩存數(shù)據(jù)集合和單條數(shù)據(jù)時,其實并沒有共用一塊數(shù)據(jù)內(nèi)存。只是非常關(guān)鍵的一個概念,千萬不要誤認(rèn)為數(shù)據(jù)集合和單條數(shù)據(jù)共用一塊數(shù)據(jù)內(nèi)存。

查詢單個數(shù)據(jù)

@Cacheable(value = "devices", key = "#id")
public DevicePo getById(Integer id) {
    if (id == null) {
        return null;
    }
    return deviceMapper.selectById(id);
}

相比于【獲取數(shù)據(jù)集合】,單條數(shù)據(jù)多了請求參數(shù),在@Cacheable注解中也多了key,雖然value都是devices,如果還是以【緩存池】來代表value的話,表面看【查詢所有數(shù)據(jù)集合方法】和【獲取單條數(shù)據(jù)】的@Cacheable注解value都為devices,好像共用了一個緩存池,而key則會被誤認(rèn)為是從【緩存池】中在數(shù)據(jù)集合中進(jìn)行了過濾,這也可能會讓人為認(rèn)為它們的數(shù)據(jù)地址也是相同的。

其實,共用【緩存池】這么說也沒毛病,key作為過濾也沒毛病,但最后的結(jié)論是錯的。

其實springBoot的cache緩存,你可以理解為是兩層嵌套的map,即Map<String,Map<String,Object>,map的key1為@Cacheable的value,key2為@Cacheable的key。
那【獲取數(shù)據(jù)集合方法】和【獲取單個數(shù)據(jù)方法】在這個map的存儲就變?yōu)榱耍?br />【獲取數(shù)據(jù)集合方法】: map.get("devices").put("all", list);
【獲取單個數(shù)據(jù)方法】: map.get("devices").put("1", obj); //假設(shè)數(shù)據(jù)id為1

到這里,在新增、修改、刪除時,如果你還是一味的只是更新單條數(shù)據(jù)緩存,就會發(fā)現(xiàn)【獲取數(shù)據(jù)集合方法】為什么沒有更新了吧。

新增一條新的數(shù)據(jù)

@CachePut(value = "devices", key = "#result.id")這是一個很標(biāo)準(zhǔn)的新增數(shù)據(jù)的注解。但是這里面會有兩個問題。
首先,可能很多文章會這么寫:

@CachePut(value = "devices", key = "#device.id")
public Device add(Device device) {
...
}

這本身沒毛病,但是,你的請求參數(shù)中有id么? 我猜肯定沒有。那我換種寫法:

/**
 * @return 返回設(shè)備id
 */
@CachePut(value = "devices", key = "#device.id")
public int add(Device device) {
...
}

如果返回的是數(shù)據(jù)id,或者boolean類型呢?寫入緩存的會是什么?還會是數(shù)據(jù)實體么?肯定不是,并且還會暴露上面那個問題,device中沒有id。
那為什么第一種寫法沒有問題? 你共用一個device實體,在填充id時,請求參數(shù)中的id已經(jīng)被填充了。如果你的請求參數(shù)與返回的device不同,這個緩存也就不會保存,因為請求參數(shù)的id為null,key為null不會保存到緩存。

第二個問題,則是結(jié)合上面的查詢,如果你也有【獲取所有數(shù)據(jù)集合方法】,那這種寫法一定不會更新所有數(shù)據(jù)集合的緩存。

我們換種寫法:

@Caching(evict = {
            @CacheEvict(value = "devices", allEntries = true),
            @CacheEvict(value = "devices", key = "#result")
    })
public int add(Device device) {
...
}

使用@Caching來處理,一個是刪除所有數(shù)據(jù)集合緩存,一個是刪除單條數(shù)據(jù)緩存,單條數(shù)據(jù)緩存的key則是用返回值(如果你的返回值是實體本身,也可以用put代替)

這樣在下次調(diào)用查詢接口時,就會重新生成緩存。

更新一條數(shù)據(jù)

邏輯與新增相同,這里就不再贅述

刪除一條數(shù)據(jù)

邏輯與新增相同,這里就不再贅述

到此這篇關(guān)于SpringBoot中cache使用的實現(xiàn)示例的文章就介紹到這了,更多相關(guān)SpringBoot cache使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring?Boot中使用Spring?Retry重試框架的操作方法

    Spring?Boot中使用Spring?Retry重試框架的操作方法

    這篇文章主要介紹了Spring?Retry?在SpringBoot?中的應(yīng)用,介紹了RetryTemplate配置的時候,需要設(shè)置的重試策略和退避策略,需要的朋友可以參考下
    2022-04-04
  • java 中volatile和lock原理分析

    java 中volatile和lock原理分析

    這篇文章主要介紹了java 中volatile和lock原理分析的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • 使用BitSet位集合,一個重復(fù)校驗工具

    使用BitSet位集合,一個重復(fù)校驗工具

    這篇文章主要介紹了使用BitSet位集合,一個重復(fù)校驗工具,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • 詳解Java ScheduledThreadPoolExecutor的踩坑與解決方法

    詳解Java ScheduledThreadPoolExecutor的踩坑與解決方法

    最近項目上反饋某個重要的定時任務(wù)突然不執(zhí)行了,很頭疼,開發(fā)環(huán)境和測試環(huán)境都沒有出現(xiàn)過這個問題。定時任務(wù)采用的是ScheduledThreadPoolExecutor,后來一看代碼發(fā)現(xiàn)踩了一個大坑。本文就來和大家聊聊這次的踩坑記錄與解決方法,需要的可以參考一下
    2022-10-10
  • Java中Retry方法的簡單實現(xiàn)

    Java中Retry方法的簡單實現(xiàn)

    這篇文章主要介紹了Java中Retry方法的簡單實現(xiàn),Retry主要是利用Java的lambda表達(dá)式和線程接口實現(xiàn)有返回值和無返回值的重試,思考了下就寫了一個簡易Retry功能分享出來,需要的朋友可以參考下
    2024-01-01
  • Java多態(tài)概念、實現(xiàn)機制與實踐應(yīng)用詳解

    Java多態(tài)概念、實現(xiàn)機制與實踐應(yīng)用詳解

    多態(tài)是指同一個方法在不同對象上具有不同的行為,通過多態(tài)程序可以在運行時決定調(diào)用哪個方法,從而提高代碼的靈活性和可擴展性,這篇文章主要介紹了Java多態(tài)概念、實現(xiàn)機制與實踐應(yīng)用的相關(guān)資料,需要的朋友可以參考下
    2026-01-01
  • java使用dom4j生成與解析xml文檔的方法示例

    java使用dom4j生成與解析xml文檔的方法示例

    這篇文章主要介紹了java使用dom4j生成與解析xml文檔的方法,結(jié)合實例形式分析了java基于dom4j操作xml節(jié)點生成xml文檔以及解析xml文檔的相關(guān)操作技巧,需要的朋友可以參考下
    2017-07-07
  • Java運行時多態(tài)性的實現(xiàn)

    Java運行時多態(tài)性的實現(xiàn)

    Java運行時多態(tài)性的實現(xiàn)...
    2006-12-12
  • vue3實現(xiàn)一個todo-list

    vue3實現(xiàn)一個todo-list

    這篇文章主要為大家詳細(xì)介紹了基于vuejs實現(xiàn)一個todolist項目,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能給你帶來幫助
    2021-08-08
  • Java Selenium實現(xiàn)多窗口切換的示例代碼

    Java Selenium實現(xiàn)多窗口切換的示例代碼

    這篇文章主要介紹了Java Selenium實現(xiàn)多窗口切換的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09

最新評論

邛崃市| 屏山县| 贵南县| 左贡县| 曲周县| 阳城县| 洞口县| 固始县| 岳阳县| 恩施市| 日土县| 梓潼县| 奇台县| 北碚区| 体育| 宜川县| 营口市| 买车| 安西县| 彰化市| 阿合奇县| 临西县| 固阳县| 鄂托克前旗| 平舆县| 平泉县| 乌苏市| 尉氏县| 旅游| 东源县| 崇礼县| 贵德县| 万源市| 乌拉特中旗| 广河县| 钟祥市| 麦盖提县| 石门县| 沧州市| 弥勒县| 宝坻区|