基于Redis的对象数据缓存思想与实现-Spring Cache框架

发布时间:2024年01月12日

需求:Redis缓存对象数据减少服务器压力,提供快速查询性能。

案例实现(按需灵活使用!)

1.1 问题说明

用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大。

结果:系统响应慢、用户体验差

1.2 实现思路

通过Redis来缓存菜品数据,减少数据库查询操作。

缓存逻辑分析:

  • 每个套餐下的菜品保存一份缓存数据

  • 数据库中菜品数据有变更时清理缓存数据

2. 缓存套餐(注解实现!)

2.1 Spring Cache

2.1.1 介绍

Spring Cache 是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。

Spring Cache 提供了一层抽象,底层可以切换不同的缓存实现,例如:

  • EHCache

  • Caffeine

  • Redis(常用)

Server配置起步依赖:

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

2.1.2 常用注解

在SpringCache中提供了很多缓存操作的注解,常见的是以下的几个:

注解说明
@EnableCaching开启缓存注解功能,通常加在启动类上
@Cacheable在方法执行前先查询缓存中是否有数据,如果有数据,则直接返回缓存数据;如果没有缓存数据,调用方法并将方法返回值放到缓存中
@CachePut将方法的返回值放到缓存中
@CacheEvict将一条或多条数据从缓存中删除

在spring boot项目中,使用缓存技术只需在项目中导入相关缓存技术的依赖包,并在启动类上使用@EnableCaching开启缓存支持即可。

2). @CachePut注解

@CachePut 说明:

作用: 将方法返回值,放入缓存

value: 缓存的名称, 每个缓存名称下面可以有很多key

key: 缓存的key ----------> 支持Spring的表达式语言SPEL语法

3). @Cacheable注解

@Cacheable 说明:

作用: 在方法执行前,spring先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放到缓存中

value: 缓存的名称,每个缓存名称下面可以有多个key

key: 缓存的key ----------> 支持Spring的表达式语言SPEL语法

4). @CacheEvict注解

@CacheEvict 说明:

作用: 清理指定缓存

value: 缓存的名称,每个缓存名称下面可以有多个key

key: 缓存的key ----------> 支持Spring的表达式语言SPEL语法

2.2 实现思路!!!!!

实现步骤:

1). 导入Spring Cache和Redis相关maven坐标

2). 在启动类上加入@EnableCaching注解,开启缓存注解功能

3). 在用户端接口SetmealController的 list 方法上加入@Cacheable注解

4). 在管理端接口SetmealController的 save、delete、update、startOrStop等方法上加入CacheEvict注解

2.3 代码开发

按照上述实现步骤:

1). 导入Spring Cache和Redis相关maven坐标

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

2). 在启动类上加入@EnableCaching注解,开启缓存注解功能

?
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.transaction.annotation.EnableTransactionManagement;
?
@SpringBootApplication
@EnableTransactionManagement //开启注解方式的事务管理
@Slf4j
@EnableCaching //开启缓存注解功能
public class SkyApplication {
 ? ?public static void main(String[] args) {
 ? ? ? ?SpringApplication.run(SkyApplication.class, args);
 ? ? ? ?log.info("server started");
 ?  }
}

3). 在用户端接口SetmealController的 list 方法上加入@Cacheable注解

/**
 ? ? * 条件查询
 ? ? *
 ? ? * @param categoryId
 ? ? * @return
 ? ? */
 ? ?@GetMapping("/list")
 ? ?@ApiOperation("根据分类id查询套餐")
 ? ?@Cacheable(cacheNames = "setmealCache",key = "#categoryId") //key: setmealCache::100
 ? ?public Result<List<Setmeal>> list(Long categoryId) {
 ? ? ? ?Setmeal setmeal = new Setmeal();
 ? ? ? ?setmeal.setCategoryId(categoryId);
 ? ? ? ?setmeal.setStatus(StatusConstant.ENABLE);
?
 ? ? ? ?List<Setmeal> list = setmealService.list(setmeal);
 ? ? ? ?return Result.success(list);
 ?  }

4). 在管理端接口SetmealController的 save、delete、update、startOrStop等方法上加入CacheEvict注解

 /**
 ? ? * 新增套餐
 ? ? *
 ? ? * @param setmealDTO
 ? ? * @return
 ? ? */
 ? ?@PostMapping
 ? ?@ApiOperation("新增套餐")
 ? ?@CacheEvict(cacheNames = "setmealCache",key = "#setmealDTO.categoryId")//key: setmealCache::100
 ? ?public Result save(@RequestBody SetmealDTO setmealDTO) {
 ? ? ? ?setmealService.saveWithDish(setmealDTO);
 ? ? ? ?return Result.success();
 ?  }
    /**
 ? ? * 批量删除套餐
 ? ? *
 ? ? * @param ids
 ? ? * @return
 ? ? */
 ? ?@DeleteMapping
 ? ?@ApiOperation("批量删除套餐")
 ? ?@CacheEvict(cacheNames = "setmealCache",allEntries = true)
 ? ?public Result delete(@RequestParam List<Long> ids) {
 ? ? ? ?setmealService.deleteBatch(ids);
 ? ? ? ?return Result.success();
 ?  }
    /**
 ? ? * 修改套餐
 ? ? *
 ? ? * @param setmealDTO
 ? ? * @return
 ? ? */
 ? ?@PutMapping
 ? ?@ApiOperation("修改套餐")
 ? ?@CacheEvict(cacheNames = "setmealCache",allEntries = true)
 ? ?public Result update(@RequestBody SetmealDTO setmealDTO) {
 ? ? ? ?setmealService.update(setmealDTO);
 ? ? ? ?return Result.success();
 ?  }
?
 ? ?/**
 ? ? * 套餐起售停售
 ? ? *
 ? ? * @param status
 ? ? * @param id
 ? ? * @return
 ? ? */
 ? ?@PostMapping("/status/{status}")
 ? ?@ApiOperation("套餐起售停售")
 ? ?@CacheEvict(cacheNames = "setmealCache",allEntries = true)
 ? ?public Result startOrStop(@PathVariable Integer status, Long id) {
 ? ? ? ?setmealService.startOrStop(status, id);
 ? ? ? ?return Result.success();
 ?  }

2.4 功能测试

通过前后端联调方式来进行测试,同时观察redis中缓存的套餐数据。和缓存菜品功能测试基本一致,不再赘述。

文章来源:https://blog.csdn.net/qq_63535554/article/details/135461154
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。