SpringCache 面向注解开发

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
  * allEntries :清除dishCache下的所有缓存数据
  */
    @CacheEvict(value = "dishCache",allEntries = true)
    @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",allEntries = true)
    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    中间的'_' 是字符串拼接

好记性不如烂笔头,赶紧去试试吧

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Leo丶fei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值