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

Spring?緩存在項(xiàng)目中的使用詳解

 更新時(shí)間:2025年05月22日 14:51:05   作者:扛麻袋的少年  
Spring?緩存機(jī)制,Cache接口為緩存的組件規(guī)范定義,包擴(kuò)緩存的各種操作(添加緩存、刪除緩存、修改緩存等),本文給大家介紹Spring?緩存在項(xiàng)目中的使用,感興趣的朋友一起看看吧

在上文介紹了 JSR-107 規(guī)范 后, 本文來(lái)介紹一下 Spring 緩存機(jī)制相關(guān)內(nèi)容。

1.Spring 緩存機(jī)制介紹

       Spring 從 3.1開始,針對(duì)緩存定義了org.springframework.cache.Cache
org.springframework.cache.CacheManager接口,來(lái)統(tǒng)一不同的緩存技術(shù)。
并支持使用 JCache(JSR-107規(guī)范)注解來(lái)簡(jiǎn)化項(xiàng)目的開發(fā)。

       Spring 的緩存機(jī)制非常靈活,可以對(duì)容器中任意 Bean 或者 Bean 的方法進(jìn)行緩存,因此這種緩存機(jī)制可以在 JavaEE 應(yīng)用的任何層次上進(jìn)行緩存。在緩存的具體實(shí)現(xiàn)上,Spring 緩存底層也是借助其他緩存工具來(lái)實(shí)現(xiàn)的,例如 EhCache(Hibernate緩存工具),上層則以統(tǒng)一 API 編程。

       Spring 緩存機(jī)制,Cache接口為緩存的組件規(guī)范定義,包擴(kuò)緩存的各種操作 (添加緩存、刪除緩存、修改緩存等) 。在 Cache 接口下,Spring 為其提供了各種 xxxCache 的實(shí)現(xiàn)。如:RedisCacheEhCacheCacheConcurrentMapCache等;

2.Spring 緩存用到的概念

Ⅰ.兩個(gè)接口

  • Cache:緩存接口,用來(lái)定義緩存的各種操作。Spring提供的具體實(shí)現(xiàn)有:RedisCache、EhCacheCache、ConcurrentMapCache等;
  • CacheManager:緩存管理器,管理各種緩存(Cache)組件

Ⅱ.三個(gè)注解(方法層次)

  • @Cacheable:標(biāo)注在方法上,能夠根據(jù)方法的請(qǐng)求參數(shù)等對(duì)其結(jié)果進(jìn)行緩存。代表一個(gè)方法能被緩存@CacheEvict:清空緩存(標(biāo)注在刪除方法上,用來(lái)清空緩存)
  • @CachePut:更新緩存。保證方法被調(diào)用,同時(shí)更新后的結(jié)果被緩存。

Ⅲ.一個(gè)注解(功能層次)

  • @EnableCaching:開啟基于注解的緩存(想要使用緩存,就需要開啟緩存注解) Ⅳ.兩個(gè)自定義
  • keyGenerator:緩存數(shù)據(jù)時(shí)key生成策略
  • serialize:緩存數(shù)據(jù)時(shí) value 值序列化策略

3.工作原理

       每次調(diào)用需要緩存功能的方法時(shí),Spring 都會(huì)檢查指定參數(shù)的指定的目標(biāo)方法是否已經(jīng)被調(diào)用過(guò);如果有就直接從緩存中獲取方法調(diào)用后的結(jié)果,如果沒(méi)有就調(diào)用方法并緩存結(jié)果后返回給用戶。下次調(diào)用直接從緩存中獲取。

4.緩存在項(xiàng)目中的使用

       我們來(lái)準(zhǔn)備一個(gè)環(huán)境,使用 Spring Boot + MyBatis 框架,來(lái)展示一下緩存在項(xiàng)目中的使用。此處就不啰嗦環(huán)境的搭建過(guò)程了,直接來(lái)介紹 Cache 緩存在項(xiàng)目中的使用。如需項(xiàng)目demo,請(qǐng)?zhí)D(zhuǎn)至文末代碼部分。

Ⅰ.使用@EnableCaching 開啟基于注解的緩存

@SpringBootApplication
@MapperScan("com.example.cache.mapper")
@EnableCaching //開啟基于注解的緩存
public class CacheApplication {
    public static void main(String[] args) {
        SpringApplication.run(CacheApplication.class, args);
    }
}

Ⅱ.來(lái)個(gè)Controller

提示:此處的3個(gè)方法分別對(duì)應(yīng) @Cacheable、@CachePut、@CacheEvict 三個(gè)注解,接下來(lái)一一測(cè)試

@RestController
public class UserController {
    @Autowired
    UserService userService;
	/**
	 * 根據(jù)id獲取用戶信息(主要針對(duì) @Cacheable 注解介紹)
	 */
    @GetMapping("/user/{id}")
    public User user(@PathVariable("id") Integer id){
        User user = userService.getUser(id);
        return user;
    }
    /**
     * 更新用戶信息(主要針對(duì) @CachePut 注解介紹)
     */
    @PutMapping("/user")
    public User updateUser(User user) {
        User upUser = userService.updateUser(user);
        return upUser;
    }
    /**
     * 根據(jù)id刪除用戶數(shù)據(jù)(主要針對(duì) @CacheEvict 注解介紹)
     */
    @DeleteMapping("/user/{id}")
    public void deleteUser(@PathVariable("id") Integer id) {
        userService.deleteUser(id);
    }
}

Ⅲ.在需要緩存的方法上,添加@Cacheable注解,表示該方法需要被緩存

public interface UserService {
    /**
     * 根據(jù)ID獲取用戶信息
     * 此處 value 為 @Cacheable 屬性,該注解還有很多屬性,在 https://blog.csdn.net/lzb348110175/article/details/105349109 會(huì)有介紹,此處不做介紹
     * 緩存相關(guān)注解,也可以寫到具體Service實(shí)現(xiàn)類上,此處寫在了接口上
     */
    @Cacheable(value = "user"/*,key="#id"*/)
    User getUser(Integer id);
	/**
     * 更新用戶信息
     */
    @CachePut(value = "user",key = "#user.id")
    User updateUser(User user);
	/**
	 * 根據(jù)ID刪除用戶
	 */
    @CacheEvict(value = "user", key = "#id")
    void deleteUser(Integer id);
}

Ⅳ.getUser()方法實(shí)現(xiàn)

@Service
@Slf4j
public class UserServiceImpl implements UserService {
    @Autowired
    UserMapper userMapper;
    /**
     * 根據(jù)ID獲取用戶信息
     */
    @Override
    public User getUser(Integer id) {
        log.info("用戶"+id+"開始執(zhí)行數(shù)據(jù)庫(kù)查詢");
        return userMapper.getUser(id);
    }
    /**
     * 更新用戶信息
     */
    @Override
    public User updateUser(User user) {
        log.info("開始更新用戶"+user.getId()+"的數(shù)據(jù)信息");
        userMapper.updateUser(user);
        return user;
    }
	/**
     * 刪除用戶(此處僅演示刪除緩存數(shù)據(jù),實(shí)際數(shù)據(jù)庫(kù)數(shù)據(jù)不刪除,方便演示)
     */
    @Override
    public void deleteUser(Integer id) {
		System.out.println("執(zhí)行刪除緩存數(shù)據(jù)操作");
    }
}

Ⅴ.測(cè)試@Cacheable緩存配置是否生效

  • 第一步:分別調(diào)用http://localhost:8080/user/1http://localhost:8080/user/2請(qǐng)求,第一次請(qǐng)求時(shí)會(huì)調(diào)用數(shù)據(jù)庫(kù)查詢。
  • 第二步:當(dāng)再次發(fā)送相同請(qǐng)求時(shí),由于緩存中數(shù)據(jù)已經(jīng)存在,所以會(huì)通過(guò)緩存來(lái)獲取數(shù)據(jù)而不去讀取數(shù)據(jù)庫(kù)。

       @Cacheable注解共有9個(gè)屬性可配置,這些屬性的配置可參考:@Cacheable注解屬性介紹。

@Cacheable注解相關(guān)屬性介紹

       @Cacheable 注解提供的屬性,如何配置可參考:@Cacheable注解屬性介紹。

Ⅵ.測(cè)試@CachePut 是否會(huì)更新緩存

  • 第一步:我們來(lái)調(diào)用http://localhost:8080/user/1接口,該接口首先會(huì)將返回的數(shù)據(jù)存入緩存。
  • 第二步:我們來(lái)調(diào)用http://localhost:8080/user接口來(lái)更新 id=1 的用戶。
  • 第三步:再發(fā)送第一步中相同請(qǐng)求時(shí),便會(huì)通過(guò)緩存來(lái)獲取數(shù)據(jù)而不去讀取數(shù)據(jù)庫(kù),此時(shí)返回的內(nèi)容是已經(jīng)更新后的數(shù)據(jù)。

       測(cè)試結(jié)果如下:第一次請(qǐng)求,查詢數(shù)據(jù)庫(kù)返回 Mary;第二次請(qǐng)求,更新數(shù)據(jù)為Clark;第三次再次發(fā)送查詢請(qǐng)求,在更新數(shù)據(jù)時(shí)緩存會(huì)同時(shí)被更改,由于緩存存在,所以不會(huì)調(diào)用數(shù)據(jù)庫(kù)請(qǐng)求,返回的是修改后的緩存中的數(shù)據(jù)Clark。(切記:更新緩存時(shí)的 key 要與已經(jīng)存在緩存中的數(shù)據(jù) key 相同,否則緩存不會(huì)被更新。)

@CachePut 注解相關(guān)屬性介紹

       @CachePut 注解提供的屬性,如何配置可參考:@Cacheable注解屬性介紹。(此處附的參考文章是正確的,我沒(méi)有附錯(cuò),因?yàn)樗鼈兣渲枚际且粯幼系模?/p>

Ⅶ.測(cè)試@CacheEvict 是否會(huì)刪除緩存

  • 第一步:我們來(lái)調(diào)用http://localhost:8080/user/1接口,該接口首先會(huì)將返回的數(shù)據(jù)存入緩存。
  • 第二步:繼續(xù)調(diào)用該接口,便會(huì)從緩存來(lái)獲取數(shù)據(jù)。
  • 第三步:調(diào)用http://localhost:8080/user/1(發(fā)送的是 Delete 請(qǐng)求)執(zhí)行緩存刪除操作。
  • 第四步:繼續(xù)發(fā)送第一步請(qǐng)求操作,由于緩存已經(jīng)被刪除,所以當(dāng)前請(qǐng)求操作會(huì)再次去數(shù)據(jù)庫(kù)查詢。

@CacheEvict 注解相關(guān)屬性介紹

       @CacheEvict 注解提供的屬性,如何配置可參考:@Cacheable注解屬性介紹。(此處附的參考文章是正確的,我沒(méi)有附錯(cuò),因?yàn)樗鼈兣渲枚际且粯幼系模ㄇ杏洠簞h除緩存時(shí)的 key 要與已經(jīng)存在緩存中的數(shù)據(jù) key 相同,否則緩存不會(huì)被刪除。)除此之外,@CacheEvict 注解還提供了額外兩個(gè)屬性:allEntries、beforeInvocation。這兩個(gè)屬性如何使用,介紹如下:

  • allEntries:清除指定緩存中的所有數(shù)據(jù),默認(rèn)為 false;(使用該屬性就不需要使用 key 屬性了)
  •        allEntries = false,默認(rèn)代表清除這個(gè)緩存中指定 key 的數(shù)據(jù)。
  •        allEntries = true,指定清除這個(gè)緩存中所有的數(shù)據(jù)。
  • beforeInvocation:清除緩存的操作是否在方法之前執(zhí)行,默認(rèn)為false;
  •     beforeInvocation = false,默認(rèn)代表緩存清除操作是在方法執(zhí)行之后執(zhí)行;如果出現(xiàn)異常緩存就不會(huì)清除。     beforeInvocation = true,代表清除緩存操作是在方法運(yùn)行之前執(zhí)行,無(wú)論方法是否出現(xiàn)異常,緩存都清除。

Ⅷ.(了解)@Caching注解—應(yīng)用于復(fù)雜緩存規(guī)則的指定

//可以使用@Caching 來(lái)解決滿足項(xiàng)目開發(fā)的復(fù)雜緩存規(guī)則
@Caching(
	cacheable = {
        @Cacheable(value = "user",key = "#name")
    },
    put = {
        @CachePut(value = "user",key = "#result.id"),
        @CachePut(value = "user",key = "#result.email")
    },
    evict = {
        @CacheEvict(value = "user",key = "#name")
    }
)
User getUserByName(String name);

Ⅸ.(了解)@CacheConfig注解—應(yīng)用于抽取當(dāng)前類下緩存使用的公共配置

       比如 UserService 類下的所有操作,①緩存都是存在 key = “user” 下,②使用的 keyGenerator 都是我們自定義的,那么我們可以使用 @CacheConfig 注解來(lái)抽取緩存的公共配置,并將該注解標(biāo)注在該 UserService類上即可。(公共配置支持:cacheNames、keyGeneratorcacheManager、cacheResolver 4個(gè)屬性的配置)

@CacheConfig(cacheNames="emp",cacheManager = "employeeCacheManager",keyGenerator = "myKeyGenerator",cacheResolver = "myCacheResolver") //抽取緩存的公共配置
public interface UserService{
	//代碼省略
}

5.附上demo

     Spring cache 緩存使用demo

百度網(wǎng)盤下載地址:

鏈接: https://pan.baidu.com/s/1nxUOTAuQIHsiQRD7Bifi5w

提取碼: 2jyz 

到此這篇關(guān)于Spring 緩存在項(xiàng)目中的使用的文章就介紹到這了,更多相關(guān)Spring 緩存在項(xiàng)目使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • mybatis中使用not?in與?in的寫法說(shuō)明

    mybatis中使用not?in與?in的寫法說(shuō)明

    這篇文章主要介紹了mybatis中使用not?in與?in的寫法說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • MyBatis中SQL片段復(fù)用使用方法詳解

    MyBatis中SQL片段復(fù)用使用方法詳解

    在使用 MyBatis 進(jìn)行數(shù)據(jù)庫(kù)操作時(shí),常常會(huì)遇到一些 SQL 語(yǔ)句的部分內(nèi)容重復(fù)出現(xiàn)的情況,比如多個(gè)查詢語(yǔ)句都涉及相同的字段列表,這時(shí),MyBatis 的 SQL 片段復(fù)用功能就派上用場(chǎng)了,接下小編給大家介紹了MyBatis中SQL片段復(fù)用使用方法,需要的朋友可以參考下
    2024-12-12
  • 后端Long類型ID傳給前端精度丟失(變00)的原因分析及解決方案

    后端Long類型ID傳給前端精度丟失(變00)的原因分析及解決方案

    在Java中l(wèi)ong是一種基本數(shù)據(jù)類型,用于存儲(chǔ)64位的整數(shù)值,這篇文章主要介紹了后端Long類型ID傳給前端精度丟失(變00)的原因分析及解決方案,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2026-03-03
  • Java判斷用戶輸入月份的季節(jié)

    Java判斷用戶輸入月份的季節(jié)

    這篇文章主要為大家詳細(xì)介紹了Java判斷用戶輸入月份的季節(jié),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • java實(shí)現(xiàn)雙色球彩票游戲

    java實(shí)現(xiàn)雙色球彩票游戲

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)雙色球彩票游戲,超級(jí)簡(jiǎn)單的邏輯,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • Java基于UDP協(xié)議的聊天室功能

    Java基于UDP協(xié)議的聊天室功能

    這篇文章主要為大家詳細(xì)介紹了Java基于UDP協(xié)議的聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • Netty如何設(shè)置為Https訪問(wèn)

    Netty如何設(shè)置為Https訪問(wèn)

    這篇文章主要介紹了Netty如何設(shè)置為Https訪問(wèn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Java中使用 @Builder 注解的簡(jiǎn)單示例

    Java中使用 @Builder 注解的簡(jiǎn)單示例

    @Builder簡(jiǎn)化構(gòu)建但存在復(fù)雜性,需配合其他注解,導(dǎo)致可變性、抽象類型處理難題,鏈?zhǔn)骄幊谭亲罴褜?shí)踐,適合長(zhǎng)期對(duì)象,避免與@Data混用,改用@Getter更佳,本文給大家介紹到底應(yīng)不應(yīng)該使用@Builder的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2025-07-07
  • Java實(shí)現(xiàn)指定線程執(zhí)行順序的三種方式示例

    Java實(shí)現(xiàn)指定線程執(zhí)行順序的三種方式示例

    這篇文章主要介紹了Java實(shí)現(xiàn)指定線程執(zhí)行順序的三種方式,包括通過(guò)共享對(duì)象鎖加上可見(jiàn)變量,通過(guò)主線程Join()以及通過(guò)線程執(zhí)行時(shí)Join()等三種實(shí)現(xiàn)方法,需要的朋友可以參考下
    2019-01-01
  • Java CAS原子操作詳解

    Java CAS原子操作詳解

    在synchronized的優(yōu)化過(guò)程中我們看到大量使用了CAS操作,CAS全稱Compare And Set(或Compare And Swap),簡(jiǎn)單來(lái)說(shuō)CAS操作就是一個(gè)虛擬機(jī)實(shí)現(xiàn)的原子操作
    2023-02-02

最新評(píng)論

开平市| 吉安市| 彩票| 康保县| 夏邑县| 大英县| 山西省| 濮阳市| 四会市| 彝良县| 托克逊县| 利津县| 江油市| 安康市| 乐业县| 靖西县| 枝江市| 嘉善县| 新沂市| 青龙| 安龙县| 永顺县| 休宁县| 九江县| 万载县| 西贡区| 乐陵市| 桓台县| 陈巴尔虎旗| 大港区| 江安县| 娄底市| 图片| 瓮安县| 商丘市| 乐东| 云浮市| 阿拉尔市| 于都县| 浮山县| 永顺县|