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

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



一、代码实现缓存

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();
    }
相关推荐
艾斯比的日常1 小时前
提升接口性能之缓存
缓存
想要打 Acm 的小周同学呀3 小时前
Redis三剑客解决方案
数据库·redis·缓存
HBryce244 小时前
CPU多级缓存与缓存一致性协议
缓存
库库林_沙琪马5 小时前
Redis 缓存穿透、击穿、雪崩:问题与解决方案
数据库·redis·缓存
早起的年轻人11 小时前
Docket Desktop 安装redis 并设置密码
数据库·redis·缓存
草字11 小时前
vue,vue3 keepalive没有效果,无法缓存页面include无效,keep-alive
前端·vue.js·缓存
oioihoii11 小时前
深入理解 C++17 的缓存行接口
java·c++·缓存
qw94911 小时前
Redis(高阶篇)03章——缓存双写一致性之更新策略探讨
数据库·redis·缓存
神马都会亿点点的毛毛张11 小时前
【SpringBoot教程】SpringBoot整合Caffeine本地缓存及Spring Cache注解的使用
java·spring boot·后端·spring·缓存·caffeine
清风细雨_林木木12 小时前
Mac 清理缓存,提高内存空间
macos·缓存