外卖开发(六)—— 高查询量数据的缓存

外卖开发(六)------ 高查询量数据的缓存



一、代码实现缓存

1、查询缓存

在查询的时候,先去redis中查找数据,如果存在则直接返回数据;否则就去数据库进行查找,并将查找结果存入redis中,并返回数据。(redis的key设置为categoryId)

java 复制代码
@GetMapping("list")
    public Result<List<DishVO>> list(Long categoryId){
        //查询redis中是否存在数据 存在则直接去redis 否则去查数据库
        //构造key
        String key = "dish_" + categoryId;
        
        //查询redis中是否存在数据
        List<DishVO> list = (List<DishVO>) redisTemplate.opsForValue().get(key);
        if (list !=null && list.size()>0){
            return Result.success(list);
        }
        
        //如果不存在,只能去数据库查找
        Dish dish = new Dish();
        dish.setCategoryId(categoryId);
        dish.setStatus(StatusConstant.ENABLE); //查询起售中的商品
        List<DishVO> listVO =  dishService.listWithFlavor(dish);
        
        //将数据放入redis
        redisTemplate.opsForValue().set(key,listVO);
        return Result.success(listVO);
    }

2、修改数据时删除缓存

如果数据库中数据更新,如删除、修改、增加等,需要对redis缓存进行删除,保持数据一致性。(redis的key设置为categoryId)

新增菜品中,只需对相应的数据进行删除。

java 复制代码
 /**
     * 新增菜品
     * @param dishDTO
     * @return
     */
    @PostMapping
    @ApiOperation("新增菜品")
    public Result addDish(@RequestBody DishDTO dishDTO){
        log.info("新增菜品:{}",dishDTO);
        dishService.insertDish(dishDTO);
        //清理缓存
        String key = "dish_" + dishDTO.getCategoryId();
        redisTemplate.delete(key);

        return Result.success();
    }

删除菜品、修改菜品涉及到复杂的数据库操作,为简化redis操作,直接删除所有redis缓存

java 复制代码
/**
     * 批量删除菜品
     * @param ids
     * @return
     */
    @DeleteMapping
    @ApiOperation("批量删除菜品")
    public Result deleteDish(@RequestParam List<Long> ids){
        dishService.deleteDish(ids);
        
        //删除全部redis缓存
        Set keys = redisTemplate.keys("dish_*");  //获取redis中所有的key------通配符dish_*获取,并删除全部
        redisTemplate.delete(keys);
        
        return Result.success();
    }

二、spring cache注解实现

Spring Cache是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。
Spring Cache提供了一层抽象,底层可以切换不同的缓存实现,例如:

EHCache
Caffeine
Redis

xml 复制代码
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
<version>2.7.3</version>
</dependency>


1、Cacaheable

@Cacheable(cacheNames = "setmealCache",key = "#categoryId")
@Cacheable(cacheNames = "setmealCache",key = "#setmeal.id") //如果形参是实体类对象,可以用 ". " 来获取属性值

@Cacheable中有两个参数,第一个是cacheNames,指定了redis数据库中的key值的前半部分(通用标识),第二个是唯一标识,可以动态指定方法形参中的属性值,比如将唯一的id作为Redis的key值的的后半部分,这样就可以唯一的标识为一个redis。

总结来说,@Cacheable 中指定的参数,可以表示为:"setmealCache::#categoryId",其中每一个冒号都代表一层,有两个冒号,且冒号中间没有东西,则表示为Empty。如下图所示

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

2、CacheEvict

@CacheEvict(cacheNames = "setmealCache",key = "#setmealDTO.categoryId") 删除指定的cache,cacheName和key一起指定Redis的key
@CacheEvict(cacheNames = "setmealCache",allEntries = true) 删除cacheName下所有的cache,allEntires = true 指定为删除所有

java 复制代码
/**
     * 新增套餐
     * @param setmealDTO
     * @return
     */
    @PostMapping
    @ApiOperation("新增套餐")
    @CacheEvict(cacheNames = "setmealCache",key = "#setmealDTO.categoryId")
    public Result insertSetmeal(@RequestBody SetmealDTO setmealDTO){
        setmealService.addSetmeal(setmealDTO);
        
        return Result.success();
    }
java 复制代码
/**
     * 修改套餐
     * @param setmealDTO
     * @return
     */
    @PutMapping
    @ApiOperation("修改套餐")
    @CacheEvict(cacheNames = "setmealCache",allEntries = true)
    public Result update(@RequestBody SetmealDTO setmealDTO){
        setmealService.update(setmealDTO);

        return Result.success();
    }
相关推荐
呼啦啦56121 小时前
C++vector
java·c++·缓存
刘~浪地球1 天前
数据库与缓存--分库分表实战指南
网络·数据库·缓存
深蓝电商API1 天前
Redis在海淘场景下的缓存策略设计
数据库·redis·缓存·海淘
杰克尼1 天前
redis(day04-达人探店)
数据库·redis·缓存
一只小bit1 天前
Redis 初步入门教程:简单介绍和安装配置
数据库·redis·缓存
juniperhan1 天前
Flink 系列第 3 篇:核心概念精讲|分布式缓存 + 重启策略 + 并行度 底层原理 + 代码实战 + 生产规范
大数据·分布式·缓存·flink
難釋懷1 天前
Nginx实现本地缓存查询
nginx·spring·缓存
刘~浪地球1 天前
数据库与缓存--Redis 集群架构与优化
数据库·redis·缓存
IT枫斗者1 天前
AI Agent 设计模式全景解析:从单体智能到分布式协作的架构演进
人工智能·redis·分布式·算法·spring·缓存·设计模式
一个有温度的技术博主1 天前
Redis缓存预热:解决服务冷启动的“数据库杀手”问题
数据库·redis·缓存