• 《苍穹外卖》知识梳理6-缓存商品,购物车功能


    苍穹外卖实操笔记六—缓存商品,购物车功能

    一.缓存菜品

      可以使用redis进行缓存;另外,在实现缓存套餐时可以使用spring cache提高开发效率;
      通过缓存数据,降低访问数据库的次数;
    在这里插入图片描述
    使用的缓存逻辑:
    1.每个分类下保存一份缓存数据;就是一对key-value(dish_1表示属于分类1的菜品列表)
    2.数据库中的菜品有变更时,及时清理缓存数据;
    在这里插入图片描述

    1.1缓存菜品数据;直接使用redis即可;
    @RestController("userDishController")
    @RequestMapping("/user/dish")
    @Slf4j
    @Api(tags = "C端-菜品浏览接口")
    public class DishController {
    
        @Autowired
        private DishService dishService;
    
        @Autowired
        private RedisTemplate redisTemplate;
    
        /**
         * 根据分类id查询菜品
         *
         * @param categoryId
         * @return
         */
        @GetMapping("/list")
        @ApiOperation("根据分类id查询菜品")
        public Result<List<DishVO>> list(Long categoryId) {
            //构造redis中的key
            String key="dish_"+categoryId;
            //查询redis中是否存在菜品
            List<DishVO> dishVOList = (List<DishVO>) redisTemplate.opsForValue().get(key);
            //如果存在,直接返回,无需访问数据库
            if (dishVOList!=null&&dishVOList.size()>0){
                return Result.success(dishVOList);
            }
    
            Dish dish = new Dish();
            dish.setCategoryId(categoryId);
            dish.setStatus(StatusConstant.ENABLE);//查询起售中的菜品
    
            //如果不存在,查询数据库,将查询到数据放入redis中
            dishVOList = dishService.listWithFlavor(dish);
            redisTemplate.opsForValue().set(key,dishVOList);
    
            return Result.success(dishVOList);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    1.2清理缓存菜品数据

    新增菜品,修改菜品,批量删除菜品,起售,停售菜品都需要清理缓存数据;

    二.缓存购物车

    2.1 spring-cache

    在这里插入图片描述
    在启动类上开启缓存注解功能

    @SpringBootApplication
    @EnableTransactionManagement //开启注解方式的事务管理
    @Slf4j
    @EnableCaching //开启缓存注解功能
    public class SkyApplication {
        public static void main(String[] args) {
            SpringApplication.run(SkyApplication.class, args);
            log.info("server started");
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    @CachePut注解
      将方法的返回值放到缓缓存中,Spring Cache有自己的命名规则:
    比如@CachePut(cacheNames=“userCache” , key=“abc”),则缓存中的Key就是userCache::abc
      另外,如果需要动态的进行拼接Key值可以使用Sring el表达式语言,从参数或返回值中获取内容;

    //1.从参数中动态获取,key=后变的参数要与函数的形参一致;
    @PostMapping
    @CachePut(cacheNames="userCache" , key="#user.id")
    public User save(@RequestBody User user){
    	userSerivce.insert(user);
    	return user;
    }
    
    //2.从返回值中动态获取,key=后边是固定的result
    @PostMapping
    @CachePut(cacheNames="userCache" , key="#result.id")
    public User save(@RequestBody User user){
    	userSerivce.insert(user);
    	return user;
    }
    
    //3.从多个参数中动态获取,key=后边是#p0(表示第一个参数);#p1(表示第2个参数)
    @PostMapping
    @CachePut(cacheNames="userCache" , key="#p0.id")
    public User save(@RequestBody User user,String dishName){
    	userSerivce.insert(user);
    	return user;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    @Cacheable注解
    用法大致宇@CachePut相同,效果不同,会先到redis中查询有无结果,如果有则不调用下边的方法,如果没有才调用,并随后将被调用的方法的返回值加入redis中;

    @PostMapping
    @Cacheable(cacheNames="userCache" , key="#user.id")
    public User save(@RequestBody User user){
    	userSerivce.insert(user);
    	return user;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    @CacheEvict注解
    清理缓存数据

    //该代码一次只清理一条数据,删除指定key的键值对;
    @PostMapping
    @CacheEvict(cacheNames="userCache" , key="#user.id")
    public User save(@RequestBody User user){
    	userSerivce.insert(user);
    	return user;
    }
    
    //该代码一次能够清理所有的数据;
    @PostMapping
    @CacheEvict(cacheNames="userCache" , allEntries=true)
    public User save(@RequestBody User user){
    	userSerivce.insert(user);
    	return user;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    2.2 在项目中使用spring-cache

    1.导入maven坐标;

    
    <dependency>
         <groupId>org.springframework.bootgroupId>
         <artifactId>spring-boot-starter-data-redisartifactId>
     dependency>
     
    
     <dependency>
         <groupId>org.springframework.bootgroupId>
         <artifactId>spring-boot-starter-cacheartifactId>
     dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.在启动类上加上@EnableCaching

    @SpringBootApplication
    @EnableTransactionManagement //开启注解方式的事务管理
    @Slf4j
    @EnableCaching //开启缓存注解功能
    public class SkyApplication {
        public static void main(String[] args) {
            SpringApplication.run(SkyApplication.class, args);
            log.info("server started");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

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

    //当用户获取套餐列表时会将套餐内容设置到redis中
      @GetMapping("/list")
      @ApiOperation("根据分类id查询套餐")
      @Cacheable(cacheNames = "setmealCache",key = "#categoryId")  //key
      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);
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    4.在管理端SetmealController的save,delete,update,startOrStop等方法上加上CacheEvict注解;

    //新增时,删除指定套餐;
     @PostMapping
     @ApiOperation("新增套餐")
     @CacheEvict(cacheNames = "setmealCache",key = "#setmealDTO.categoryId")
     public Result save(@RequestBody SetmealDTO setmealDTO) {
         setmealService.saveWithDish(setmealDTO);
         return Result.success();
     }
    
    //批量删除套餐时,删除缓存中所有的套餐数据;
    @DeleteMapping
    @ApiOperation("批量删除套餐")
    @CacheEvict(cacheNames = "setmealCache",allEntries = true)
    public Result delete(@RequestParam List<Long> ids){
        setmealService.deleteBatch(ids);
        return Result.success();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
  • 相关阅读:
    Cholesterol-PEG-DBCO,CLS-PEG-DBCO,胆固醇-聚乙二醇-二苯基环辛炔一种环炔烃
    面试经典150题——Day36
    BeanFactory和ApplicationContext的区别
    [附源码]计算机毕业设计基于springboot框架的资产管理系统设计与实现
    网易游戏学院系列——书籍《游戏设计》【笔记】
    构建简单物体
    CSDN每日一练 |『小艺读书』『小Q的鲜榨柠檬汁』『分层遍历二叉树』2023-10-19
    牛客网刷题记录 || 运算符与分支
    AxureRP9的新特性介绍和技巧分享
    若依RuoYi-Vue分离版—PageHelper分页的坑
  • 原文地址:https://blog.csdn.net/linjianshaonian_/article/details/136094649