日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

SpringCache 面向注解開發

作者:Leo丶fei 更新時間: 2022-07-21 編程語言

Spring Cache是一個框架,實現了基于注解的緩存功能,只需要簡單地加一個注解,就能實現緩存功能,大大簡化我們在業務中操作緩存的代碼。

Spring Cache只是提供了一層抽象,底層可以切換不同的cache實現。具體就是通過CacheManager接口來統一不同的緩存技術。CacheManager是Spring提供的各種緩存技術抽象接口

在SpringCache中提供了很多緩存操作的注解,常見的是以下的幾個:

注解 說明
@EnableCaching 開啟緩存注解功能
@Cacheable 在方法執行前spring先查看緩存中是否有數據,如果有數據,則直接返回緩存數據;若沒有數據,調用方法并將方法返回值放到緩存中
@CachePut 將方法的返回值放到緩存中
@CacheEvict 將一條或多條數據從緩存中刪除

?其實在我們基本的pom文件中spring-boot-starter-web 下面的 spring-mvc中的 spring-context中有相關依賴,可以使用spring cache 的基礎功能,如果使用基本功能就可以不用導入redis坐標

使用的時候只需要添加注解自動裝配

@Autowired

private CacheManager cacheManager

然后要在啟動類上加入注解

@EnableCaching

集成Redis

在使用上述默認的ConcurrentHashMap做緩存時,服務重啟之后,之前緩存的數據就全部丟失了,操作起來并不友好。在項目中使用,我們會選擇使用redis來做緩存,主要需要操作以下幾步:

1.POM.XML文件導入依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

application.yml文件中

spring:
  redis:
    host: 192.168.200.200
    port: 6379
    password: root@123456
    database: 0
  cache:
    redis:
      time-to-live: 1800000   #設置緩存過期時間,可選  以毫秒來計算

3.啟動類上加入@EnableCaching注解

在使用方法上加上相對應的注解

保存@CachePut(將方法的返回值放到緩存中)

  
  /**
  * CachePut:將方法返回值放入緩存
  * value:緩存的名稱,每個緩存名稱下面可以有多個key
  * key:緩存的key
  */
   @CachePut(value = "dishCache",key="#dishDto.id")
   //@CachePut(value = "dishCache",key="#result.id")
    @PostMapping
    public R<String> save (@RequestBody DishDto dishDto){
        log.info(dishDto.toString());

        dishService.saveWithFlavor(dishDto);
        return R.success("新增菜品成功");
    }

此處的value是設置緩存名稱,根據你自己的項目中的分類使用自己定義,然后這一類通用,后面的key就是動態的獲取了,此處建議比較好記的方法,方法中形參是什么,最好就寫什么,此處小編的是dishDto.id? 然后保存的話,根據id保存,因為id唯一所以key如此寫

key的寫法如下:

#user.id : #user指的是方法形參的名稱, id指的是user的id屬性 , 也就是使用user的id屬性作為key ;

#user.name: #user指的是方法形參的名稱, name指的是user的name屬性 ,也就是使用user的name屬性作為key ;

#result.id : #result代表方法返回值,該表達式 代表以返回對象的id屬性作為key ;

#result.name : #result代表方法返回值,該表達式 代表以返回對象的name屬性作為key ;

如果你不知道其他方式怎么寫,可以點擊CachePut,進入源碼

?一定要注意前面一定要加上? ? #

如果第一次進入源碼,沒有這些注解,注意你的idea右上角,會有提示讓你下載,點擊下載配置就可以

@CacheEvict注解? ?(將一條或多條數據從緩存中刪除)

/**
* CacheEvict:清理指定緩存
* value:緩存的名稱,每個緩存名稱下面可以有多個key
* key:緩存的key    ---->支持Spring的表達式語言SPEL
*/

//@CacheEvict(value = "userCache",key = "#p0")  //#p0 代表第一個參數
//@CacheEvict(value = "userCache",key = "#root.args[0]") //#root.args[0] 代表第一個參數
@CacheEvict(value = "userCache",key = "#id") //#id 代表變量名為id的參數
@DeleteMapping("/{id}")
public void delete(@PathVariable Long id){
    userService.removeById(id);
}

@CacheEvict注解? ?(將一條或多條數據從緩存中刪除)

update的方法也是需要刪除以前的緩存的信息,所有也是用CacheEvict


    @PutMapping
    //@CacheEvict(value = "dishCache",key="#p0..id")
    //@CacheEvict(value = "dishCache",key="#result.id")
    //@CacheEvict(value = "dishCache",key="#root.args[0].id")
    @CacheEvict(value = "dishCache",key="#dishDto.id")
    public R<String> update (@RequestBody DishDto dishDto){
        log.info(dishDto.toString());

        dishService.updateWithFlavor(dishDto);
        return R.success("更新菜品成功");
    }

@Cacheable注解? (在方法執行前spring先查看緩存中是否有數據,如果有數據,則直接返回緩存數據;若沒有數據,調用方法并將方法返回值放到緩存中)

/**
* Cacheable:在方法執行前spring先查看緩存中是否有數據,如果有數據,則直接返回緩存數據;若沒有數據,調用方法并將方法返回值放到緩存中
* value:緩存的名稱,每個緩存名稱下面可以有多個key
* key:緩存的key
* condition:條件,滿足條件時才緩存數據
* unless:滿足條件則不緩存
*/
@Cacheable(value = "dishCache",key="#id",unless = "#result==null")
    @GetMapping("/{id}")
    public R<DishDto> get(@PathVariable Long id){
        DishDto dishDto = dishService.getByIdFlavor(id);
        return R.success(dishDto);
    }

緩存非null值

在@Cacheable注解中,提供了兩個屬性分別為: condition, unless?

condition : 表示滿足什么條件, 再進行緩存 ;

unless : 表示滿足條件則不緩存 ; 與上述的condition是反向的 ;

在list方法上加注解@Cacheable

在list方法中進行查詢時,有兩個查詢條件,如果傳遞了id,根據id查詢; 如果傳遞了name, 根據name查詢,那么我們緩存的key在設計的時候,就需要既包含id,又包含name。 具體的代碼實現如下:

@Cacheable(value = "dishCache",key = "#dish.id + '_' + #dish.name")
@GetMapping("/list")
public List<Dish> list(dish dish){
    LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(dish.getId() != null,Dish::getId,dish.getId());
    queryWrapper.eq(dish.getName() != null,Dish::getName,dish.getName());
    List<Dish> list = dishService.list(queryWrapper);
    return list;
}

這里根據傳遞過來的具體信息,設計緩存key? ? 中間的'_' 是字符串拼接

好記性不如爛筆頭,趕緊去試試吧

原文鏈接:https://blog.csdn.net/m0_68884224/article/details/125897588

欄目分類
最近更新