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

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

一.缓存菜品

  可以使用redis进行缓存;另外,在实现缓存套餐时可以使用spring cache提高开发效率;
  通过缓存数据,降低访问数据库的次数;
苍穹外卖实操笔记六---缓存商品,购物车功能_第1张图片
使用的缓存逻辑:
1.每个分类下保存一份缓存数据;就是一对key-value(dish_1表示属于分类1的菜品列表)
2.数据库中的菜品有变更时,及时清理缓存数据;
苍穹外卖实操笔记六---缓存商品,购物车功能_第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清理缓存菜品数据

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

二.缓存购物车

2.1 spring-cache

苍穹外卖实操笔记六---缓存商品,购物车功能_第3张图片
在启动类上开启缓存注解功能

@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表达式语言,从参数或返回值中获取内容;

//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中;

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

@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;
}
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>

2.在启动类上加上@EnableCaching

@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注解

//当用户获取套餐列表时会将套餐内容设置到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注解;

//新增时,删除指定套餐;
 @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();
}

你可能感兴趣的:(《苍穹外卖》实操总结系列,笔记,缓存)