苍穹外卖day07缓存部分分析

苍穹外卖Day07部分聚焦于缓存功能的实现与优化,通过引入redis缓存机制,结合Spring Cache 注解,降低了数据库负载,提升其响应速度。

以下是清除缓存功能代码:

java 复制代码
@RestController
@RequestMapping("/admin/dish")
@Slf4j
@Api("菜品相关接口")
public class DishController {

    @Autowired
    DishService dishService;

    @Autowired
    RedisTemplate redisTemplate;

    @GetMapping("/list")
    @ApiOperation("根据分类id查询菜品")
    public Result<List<DishVO>> getByCategoryId(Long categoryId) {
        log.info("根据分类id查询菜品");
        String key = "dish:" + categoryId;
        List<DishVO> a = (List<DishVO>) redisTemplate.opsForValue().get(key);
        System.out.println(a);
        if (a != null && a.size() > 0) {
            return Result.success(a);
        }
        Dish dish = new Dish();
        dish.setCategoryId(categoryId);
        dish.setStatus(StatusConstant.DISABLE);
        a = dishService.listWithFlavor(dish);
        redisTemplate.opsForValue().set(key, a);
        return Result.success(a);
    }

    @PostMapping("/status/{status}")
    @ApiOperation("菜品起售停售")
    public Result startOrStop(@PathVariable Integer status, Long id) {
        dishService.startOrStop(status,id);
        cleanCache();
        return Result.success();
    }
    private void cleanCache() {
        Set set = redisTemplate.keys("dish:*");
        redisTemplate.delete(set);
    }
}

在startOrStop方法中,当执行菜品起售停售操作后,会调用 cleanCache 私有方法来清理 Redis 缓存。在 cleanCache 方法里,通过 Set set = redisTemplate.keys("dish:*"); 利用 Redis 的 keys 命令获取所有以 "dish:" 开头的键值,也就是获取所有与菜品相关的缓存键,然后使用 redisTemplate.delete(set),将这些键对应的缓存数据全部删除。

这样可以确保在菜品状态发生改变后,缓存中的菜品数据能及时更新,避免前端获取到旧的不符合实际状态的菜品信息,从而保证了缓存数据与数据库数据的一致性。但是使用keys命令在生产环境中如果数据量很大可能会影响性能,因为它需要遍历所有键,可以考虑采用更精准的缓存失效策略,比如根据具体变更的菜品 id 来有针对性地删除相关缓存,而不是批量删除所有菜品缓存,也可以使用Spring Cache注解。

Spring Cache

  1. @EnableCaching:加在启动类上,用于开启缓存注解功能,使得项目中可以使用Spring Cache的其他注解。
  2. @Cacheable:放在方法上,在方法执行前先查询缓存中是否存在缓存数据,存在数据直接将数据返回;没有缓存数据,通过反射调用方法并将方法的返回值放到缓存中。
  3. @CachePut:将方法的返回值放到缓存中,通常用于在方法执行完毕后更新缓存中的数据。
  4. @CacheEvict:用于将一条或多条数据从缓存中删除,可以根据具体的 key 删除指定的缓存数据,也可以使用allEntries = true 删除整个缓存名称下的所有数据。

以下为使用spring cahce注解的代码:

java 复制代码
@RestController
@RequestMapping("/admin/dish")
@Slf4j
@Api("菜品相关接口")
@EnableCaching
public class DishController {

    @Autowired
    DishService dishService;

    @Autowired
    RedisTemplate redisTemplate;

    @GetMapping("/list")
    @ApiOperation("根据分类id查询菜品")
    @Cacheable(cacheNames = "dishCache", key = "#categoryId")
    public Result<List<DishVO>> getByCategoryId(Long categoryId) {
        log.info("根据分类id查询菜品");
        Dish dish = new Dish();
        dish.setCategoryId(categoryId);
        dish.setStatus(StatusConstant.DISABLE);
        List<DishVO> a = dishService.listWithFlavor(dish);
        return Result.success(a);
    }

    @PostMapping("/status/{status}")
    @ApiOperation("菜品起售停售")
    @CacheEvict(cacheNames = "dishCache", allEntries = true)
    public Result startOrStop(@PathVariable Integer status, Long id) {
        dishService.startOrStop(status, id);
        return Result.success();
    }
}

这段代码使用@Cacheable(cacheNames = "dishCache", key = "#categoryId") 注解, cacheNames 指定了缓存的名称空间为 "dishCache",用于将菜品相关的缓存数据统一归类管理,方便后续维护与排查问题。

key = "#categoryId" 则以传入的菜品分类 id作为缓存的键,使得在查询菜品时,系统能够依据分类 id 精准地在 "dishCache" 缓存区域中查找对应数据。当缓存中有匹配的数据时,直接返回缓存数据,不再执行方法体中的数据库查询代码,大大加快了响应速度。

相关推荐
爱干饭的boy21 分钟前
教师管理系统
java·开发语言·c++·windows·python·青少年编程
顾北辰2030 分钟前
基本算法——分类
java·spring boot·机器学习
儒道易行41 分钟前
【网络安全实验室】SQL注入实战详情
java·数据库·安全·web安全·网络安全
开心工作室_kaic41 分钟前
springboot521基于Spring Boot的校园闲置物品交易系统(论文+源码)_kaic
java·spring boot·后端
Java知识日历1 小时前
【内含代码】Spring Boot整合深度学习框架DJL
java·人工智能·spring boot·后端·深度学习
AI人H哥会Java1 小时前
【Spring】Spring DI(依赖注入)详解—集合类型的注入——List、Set、Map的配置与注入
java·开发语言·后端·spring·架构
晚安~~1 小时前
旅游管理系统|Java|SSM|VUE| 前后端分离
java·开发语言·tomcat·maven
正在绘制中1 小时前
Java重要面试名词整理(十八):Sentinel
java·面试·sentinel
superCleanCoder1 小时前
logback之自定义pattern使用的转换器
java·spring boot·logback
cxks-从新开始1 小时前
基于 SensitiveWordBs 实现敏感词过滤功能
java