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

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

一.缓存菜品

可以使用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();
}
相关推荐
大筒木老辈子1 小时前
Linux笔记---协议定制与序列化/反序列化
网络·笔记
草莓熊Lotso1 小时前
【C++】递归与迭代:两种编程范式的对比与实践
c语言·开发语言·c++·经验分享·笔记·其他
酷ku的森2 小时前
Redis中的Zset数据类型
数据库·redis·缓存
我爱挣钱我也要早睡!4 小时前
Java 复习笔记
java·开发语言·笔记
汇能感知9 小时前
摄像头模块在运动相机中的特殊应用
经验分享·笔记·科技
阿巴Jun9 小时前
【数学】线性代数知识点总结
笔记·线性代数·矩阵
茯苓gao9 小时前
STM32G4 速度环开环,电流环闭环 IF模式建模
笔记·stm32·单片机·嵌入式硬件·学习
是誰萆微了承諾10 小时前
【golang学习笔记 gin 】1.2 redis 的使用
笔记·学习·golang
利刃大大10 小时前
【高并发内存池】五、页缓存的设计
c++·缓存·项目·内存池
DKPT10 小时前
Java内存区域与内存溢出
java·开发语言·jvm·笔记·学习