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

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

一.缓存菜品

可以使用redis进行缓存;另外,在实现缓存套餐时可以使用spring cache提高开发效率;

通过缓存数据,降低访问数据库的次数;

使用的缓存逻辑:

1.每个分类下保存一份缓存数据;就是一对key-value(dish_1表示属于分类1的菜品列表)

2.数据库中的菜品有变更时,及时清理缓存数据;

1.1缓存菜品数据;直接使用redis即可;
java 复制代码
@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清理缓存菜品数据

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

二.缓存购物车

2.1 spring-cache

在启动类上开启缓存注解功能

java 复制代码
@SpringBootApplication
@EnableTransactionManagement //开启注解方式的事务管理
@Slf4j
@EnableCaching //开启缓存注解功能
public class SkyApplication {
    public static void main(String[] args) {
        SpringApplication.run(SkyApplication.class, args);
        log.info("server started");
    }

@CachePut注解

将方法的返回值放到缓缓存中,Spring Cache有自己的命名规则:

比如@CachePut(cacheNames="userCache" , key="abc"),则缓存中的Key就是userCache::abc

另外,如果需要动态的进行拼接Key值可以使用Sring el表达式语言,从参数或返回值中获取内容;

java 复制代码
//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;
}

@Cacheable注解

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

java 复制代码
@PostMapping
@Cacheable(cacheNames="userCache" , key="#user.id")
public User save(@RequestBody User user){
	userSerivce.insert(user);
	return user;
}

@CacheEvict注解

清理缓存数据

java 复制代码
//该代码一次只清理一条数据,删除指定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;
}
2.2 在项目中使用spring-cache

1.导入maven坐标;

xml 复制代码
<!--redis对应的坐标-->
<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-redis</artifactId>
 </dependency>
 
<!--Spring Cache对应的坐标-->
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-cache</artifactId>
 </dependency>

2.在启动类上加上@EnableCaching

java 复制代码
@SpringBootApplication
@EnableTransactionManagement //开启注解方式的事务管理
@Slf4j
@EnableCaching //开启缓存注解功能
public class SkyApplication {
    public static void main(String[] args) {
        SpringApplication.run(SkyApplication.class, args);
        log.info("server started");
    }
}

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

java 复制代码
//当用户获取套餐列表时会将套餐内容设置到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);
  }

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

java 复制代码
//新增时,删除指定套餐;
 @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();
}
相关推荐
9命怪猫3 小时前
AI大模型-提示工程学习笔记5-零提示
人工智能·笔记·学习·ai·提示工程
达子6664 小时前
笔记-使用ffmpeg产生rtsp视频流,然后用进行VLC播放
windows·笔记·ffmpeg
m0_726965986 小时前
Harmony开发【笔记1】报错解决(字段名写错了。。)
笔记·bug·debug·harmonyos
huaqianzkh6 小时前
Redis的内存预分配策略
数据库·redis·缓存
有馬公生6 小时前
有关Redis的相关概述
数据库·redis·缓存
1101 11016 小时前
STM32-笔记39-SPI-W25Q128
笔记·stm32·嵌入式硬件
瞳绣6 小时前
【redis初阶】初识Redis
数据库·redis·缓存
Lovely Ruby7 小时前
大纲笔记幕布的替换
笔记
Spcarrydoinb8 小时前
python学习笔记—14—函数
笔记·python·学习
轻口味11 小时前
【每日学点鸿蒙知识】调试、网络、缓存、富文本编辑等
缓存·华为·harmonyos