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

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



一、代码实现缓存

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();
    }
相关推荐
YUELEI11841 分钟前
langchain 缓存 Caching
缓存·langchain
孤独的人1 小时前
WordPress 性能优化:从插件到 CDN 的全方位缓存设置指南
spring·缓存·性能优化
MAGICIAN...13 小时前
【Redis】--持久化机制
数据库·redis·缓存
我真的是大笨蛋13 小时前
JVM调优总结
java·jvm·数据库·redis·缓存·性能优化·系统架构
拾忆,想起19 小时前
Redis复制延迟全解析:从毫秒到秒级的优化实战指南
java·开发语言·数据库·redis·后端·缓存·性能优化
破烂儿1 天前
基于机器学习的缓存准入策略研究
人工智能·机器学习·缓存
参.商.1 天前
【Day21】146.LRU缓存 (Least Recently Used)
leetcode·缓存·golang
Dorcas_FE1 天前
axios请求缓存与重复拦截:“相同请求未完成时,不发起新请求”
前端·spring·缓存
码熔burning1 天前
Redis 的三种高效缓存读写策略!
redis·缓存·mybatis
Armyyyyy丶2 天前
Redis底层实现原理之五大基础结构
数据结构·redis·缓存