《苍穹外卖》知识梳理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清理缓存菜品数据

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

二.缓存购物车

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");
    }

@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坐标;

<!--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

@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();
}
### 关于苍穹外卖的技术架构总结 苍穹外卖作为一个典型的餐饮配送平台,其技术架构主要围绕前端交互、后端服务以及数据库设计展开。以下是对其技术架构的详细分析: #### 前端设计 前端部分负责与用户的直接交互,通常采用现代框架如 React 或 Vue.js 来实现动态页面渲染和用户体验优化。对于苍穹外卖而言,前端的主要功能模块包括但不限于: - **分类展示**:通过 API 接口获取并显示所有的菜品分类[^1]。 - **菜单浏览**:支持用户根据分类 ID 查询对应的菜品列表或套餐组合。 - **购物车管理**:提供缓存机制来存储用户选择的商品信息,在未登录状态下也能保存临时数据。 #### 后端逻辑处理 后端作为整个系统的业务核心,承担着请求解析、数据操作和服务调用的任务。常见的开发语言有 Java (Spring Boot), Python (Django/Flask),Node.js 等。具体到苍穹外卖项目上,则实现了以下几个关键接口: - `GET /categories` - 获取所有可用的食物类别; - `POST /dishes/{categoryId}` - 根据指定ID返回特定类别的菜肴详情; - `PUT /sets/{setId}/items` - 查找属于某个定制化套组内的成员项; - 缓冲区维护用于提升性能表现的同时减少频繁访问底层资源造成的负担;另外还涉及订单创建流程控制等方面的内容. #### 数据库选型与表结构规划 为了满足高并发读写需求同时兼顾成本效益考量, 可能会选择关系型数据库 MySQL 配合 NoSQL 解决方案 Redis/MongoDB 组成混合模式部署环境. 主要实体及其关联关系如下所示: ```sql CREATE TABLE categories ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255) NOT NULL UNIQUE ); CREATE TABLE dishes ( id INT PRIMARY KEY AUTO_INCREMENT, category_id INT REFERENCES categories(id), title TEXT NOT NULL, price DECIMAL(10 , 2 ) DEFAULT '0.00' , description LONGTEXT COMMENT 'Detailed info about dish' ); ``` 上述 SQL 片段定义了一个简单的两级层次模型——其中每种食品所属的大类由外键约束绑定至相应的记录条目之上. ### §相关问题§ 1. 如何进一步提高苍穹外卖应用中的搜索效率? 2. 在实际生产环境中如何保障大规模分布式系统下的一致性和可靠性? 3. 是否可以分享一些针对移动端适配的最佳实践案例研究材料? 4. 对于新加入团队的研发人员来说,快速熟悉该项目有哪些推荐的学习路径或者资料链接吗? 5. 如果考虑未来扩展国际化版本的话,当前这套设计方案存在哪些潜在局限性需要提前规避呢?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黒猫.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值