苍穹外卖-day07

[!IMPORTANT]

  1. 缓存菜品的目的是什么?如何通过Redis实现缓存菜品数据?
  2. 在Controller层中,如何构造Redis的key并查询Redis中是否存在菜品数据?
  3. 当数据库中菜品数据发生变更时,如何保证Redis缓存中的数据与数据库保持一致?
  4. Spring Cache的作用是什么?常用的注解有哪些?
  5. 如何在Spring Boot项目中使用Spring Cache?
  6. 添加购物车的逻辑是什么?
  7. 如何查看购物车中的菜品和套餐?
  8. 如何清空购物车中的数据? 删除购物车的一个商品呢?

  1. 缓存菜品的目的是什么?如何通过Redis实现缓存菜品数据?

    1. 目的:通过缓存菜品数据,减少数据库查询操作,提升系统性能。
    2. 实现:将每个分类下的菜品数据保存到Redis中,使用dish_分类id作为key。当查询菜品时,先从Redis中获取数据,如果不存在再从数据库中查询,并将查询结果存入Redis。
  2. 在Controller层中,如何构造Redis的key并查询Redis中是否存在菜品数据?

    1. 构造keyString key = "dish_" + categoryId;
    2. 查询Redis:使用redisTemplate.opsForValue().get(key)方法查询Redis中是否存在菜品数据。如果存在,直接返回;如果不存在,则查询数据库并将结果存入Redis。
  3. 当数据库中菜品数据发生变更时,如何保证Redis缓存中的数据与数据库保持一致?

    • 清理缓存:在新增、修改、删除菜品等操作后,调用自定义的cleanCache方法清理对应的缓存数据。cleanCache方法通过redisTemplate.delete(keys)删除Redis中与菜品相关的缓存。
  4. Spring Cache的作用是什么?常用的注解有哪些?

    1. 作用:Spring Cache提供了一层缓存抽象,简化了缓存操作,支持多种缓存实现(如Redis、EHCache等)。
    2. 常用注解
      1. @EnableCaching:开启缓存功能。
      2. @Cacheable:在方法执行前查询缓存,如果缓存存在则直接返回,否则执行方法并将结果存入缓存。
      3. @CachePut:将方法的返回值存入缓存。
      4. @CacheEvict:从缓存中删除数据。
  5. 如何在Spring Boot项目中使用Spring Cache?

    1. 导入Spring Cache和Redis的依赖。
    2. 在启动类上添加@EnableCaching注解。
    3. 在需要缓存的方法上使用@Cacheable@CachePut@CacheEvict注解。
  6. 添加购物车的逻辑是什么?

    • 购物车数据是关联用户的,在表结构中,我们需要记录,每一个用户的购物车数据是哪些
    • 菜品列表展示出来的既有套餐,又有菜品,如果用户选择的是套餐,就保存套餐ID(setmeal_id),如果用户选择的是菜品,就保存菜品ID(dish_id)
    • 对同一个菜品/套餐,如果选择多份不需要添加多条记录,增加数量number即可
    用户 ShoppingCartController ShoppingCartService ShoppingCartMapper DishMapper SetmealMapper 数据库 发起添加购物车请求(携带ShoppingCartDTO) 记录日志:"添加购物车,商品信息为:xxx" 调用 addShoppingCart(shoppingCartDTO) 获取当前用户ID (BaseContext.getCurrentId()) 抛出异常 "用户未登录" 将DTO转换为ShoppingCart对象 调用 list(shoppingCart) 查询购物车条目 执行SQL查询 返回查询结果 返回购物车列表 数量+1 调用 updateNumberById(shoppingCart) 执行更新操作 返回更新结果 操作完成 调用 getById(dishId) 查询菜品信息 返回菜品数据 返回Dish对象 调用 getById(setmealId) 查询套餐信息 返回套餐数据 返回Setmeal对象 alt [添加的是菜品] [添加的是套餐] 设置商品名称/图片/价格 调用 insert(shoppingCart) 执行插入操作 返回插入结果 操作完成 alt [商品已存在] [商品不存在] alt [用户未登录] [用户已登录] 返回操作结果 返回成功响应(Result.success()) 用户 ShoppingCartController ShoppingCartService ShoppingCartMapper DishMapper SetmealMapper 数据库

    Controller 层逻辑
    1. 请求接收

      接口路径:POST /user/shoppingCart/add

      参数接收:通过 @RequestBody 解析请求体中的 ShoppingCartDTO 对象

    2. 日志记录

      记录入参日志:log.info("添加购物车,商品信息为:{}", shoppingCartDTO)

    3. 服务调用

      调用 Service 方法:shoppingCartService.addShoppingCart(shoppingCartDTO)

    4. 响应返回

      统一返回结构:Result.success()


    Service 层逻辑
    1. 用户验证
      1. 获取当前用户 ID:BaseContext.getCurrentId()
      2. 验证失败处理:用户未登录时抛出 RuntimeException("用户未登录")
    2. 数据转换
      1. DTO 转实体:BeanUtils.copyProperties(shoppingCartDTO, shoppingCart)
      2. 补充用户 ID:shoppingCart.setUserId(userId)
    3. 购物车查询
      1. 执行查询:shoppingCartMapper.list(shoppingCart)
      2. 查询条件:用户 ID + 菜品/套餐 ID + 口味(若存在)
    4. 分支处理逻辑
      1. 场景 1:商品已存在

        1. 获取已存在条目:shoppingCartList.get(0)
        2. 更新数量:setNumber(原有数量 + 1)
        3. 执行更新:shoppingCartMapper.updateNumberById()
      2. 场景 2:商品不存在

        1. 类型判断
          1. 菜品:dishMapper.getById(dishId) 补全名称/价格/图片
          2. 套餐:setmealMapper.getById(setmealId) 补全信息
        2. 数据初始化
          1. 设置默认数量:number = 1
          2. 记录创建时间:createTime = LocalDateTime.now()
        3. 数据插入
          • 执行插入:shoppingCartMapper.insert()
  7. 如何查看购物车中的菜品和套餐?

    用户 ShoppingCartController ShoppingCartService ShoppingCartMapper 数据库 发起GET请求 /user/shoppingCart/list 调用 showShoppingCart() 构建查询条件(userId=当前用户ID) 调用 list(ShoppingCart查询对象) 执行SQL查询(WHERE user_id=?) 返回购物车数据列表 返回List<ShoppingCart> 返回购物车数据 返回Result.success(data) 用户 ShoppingCartController ShoppingCartService ShoppingCartMapper 数据库
    1. Controller 层处理

      1. 接收请求ShoppingCartController 中的 list() 方法处理该请求。
      2. 调用 Service:通过 shoppingCartService.showShoppingCart() 调用服务层逻辑。
      3. 返回响应:将结果包装为统一响应结构 Result.success(data)
    2. Service 层逻辑

      1. 用户身份验证

        • 隐式通过 BaseContext.getCurrentId() 获取当前用户 ID(若未登录,请求会在拦截器阶段被拦截)。
      2. 构建查询条件

        • 使用建造者模式动态构造查询对象:

          ShoppingCart.builder()
                      .userId(BaseContext.getCurrentId())
                      .build();
          
      3. 执行查询

        • 调用 shoppingCartMapper.list() 方法,传入包含 userId 的查询对象。
      4. 返回数据

        • 直接返回从数据库查询到的 List<ShoppingCart> 原始数据。
  8. 如何清空购物车中的数据? 删除购物车的一个商品呢

    用户 ShoppingCartController ShoppingCartService ShoppingCartMapper 数据库 发起DELETE请求 调用 cleanShoppingCart() deleteByUserId(当前用户ID) DELETE FROM shopping_cart WHERE user_id=? 删除结果 操作完成 返回空 返回Result.success() 发起POST请求 记录日志 调用 subShoppingCart(DTO) 转换DTO为实体对象 设置userId list(查询条件) SELECT * FROM shopping_cart WHERE ... 返回购物车条目 List<ShoppingCart> number = number - 1 updateNumberById() UPDATE shopping_cart SET number=? 更新结果 操作完成 deleteById(id) DELETE FROM shopping_cart WHERE id=? 删除结果 操作完成 alt [商品存在且数量>1] [商品存在且数量=1] 返回空 返回Result.success() 用户 ShoppingCartController ShoppingCartService ShoppingCartMapper 数据库

清空购物车功能逻辑步骤

  1. Controller 层处理
    1. 调用 shoppingCartService.cleanShoppingCart() 方法。
  2. Service 层处理
    1. 获取当前用户 ID:BaseContext.getCurrentId()
    2. 调用 shoppingCartMapper.deleteByUserId(userId) 删除用户所有购物车数据。
  3. 返回结果
    1. 返回 Result.success() 表示操作成功。

删除单个商品功能逻辑步骤

  1. Controller 层处理

    1. 记录日志:log.info("删除购物车中的一个商品{}", shoppingCartDTO)
    2. 调用 shoppingCartService.subShoppingCart(shoppingCartDTO)
  2. Service 层处理

    1. 数据转换:将 ShoppingCartDTO 转换为 ShoppingCart 对象,并设置用户 ID。
    2. 查询商品:调用 shoppingCartMapper.list(shoppingCart) 查询购物车中是否存在该商品。
    3. 分支处理
      1. 商品存在且数量 > 1
        1. 更新数量:shoppingCart.setNumber(shoppingCart.getNumber() - 1)
        2. 调用 shoppingCartMapper.updateNumberById(shoppingCart) 更新数据库。
      2. 商品存在且数量 = 1
        1. 调用 shoppingCartMapper.deleteById(shoppingCart.getId()) 删除记录。
    4. 商品不存在
      1. 当前逻辑未处理,可能导致异常。
  3. 返回结果

    • 返回 Result.success() 表示操作成功。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值