🌈个人主页:一条泥憨鱼(欢迎各位大佬莅临)
🎬精选专栏传送门:
❄️《数据结构》 ❄️《AI与Agent那些事》
❄️《从0开始学计算机网络》 ❄️《后端开发》
添加购物车
需求分析和设计
数据库设计
代码开发
1️⃣ 数据传输层 (DTO)
ShoppingCartDTO.java
@Data public class ShoppingCartDTO implements Serializable { private Long dishId; // 菜品ID private Long setmealId; // 套餐ID private String dishFlavor; // 菜品口味 }作用:接收前端传来的添加购物车请求数据,只包含必要的前端参数。
2️⃣ 实体类 (Entity)
ShoppingCart.java
@Data @Builder public class ShoppingCart implements Serializable { private Long id; private String name; // 商品名称 private Long userId; // 用户ID private Long dishId; // 菜品ID private Long setmealId; // 套餐ID private String dishFlavor; // 口味 private Integer number; // 数量 private BigDecimal amount; // 金额 private String image; // 图片 private LocalDateTime createTime; // 创建时间 }作用:购物车的完整数据模型,对应数据库表结构。
3️⃣ 控制层 (Controller)
ShoppingCartController.java
@RestController @RequestMapping("/user/shoppingCart") @Api(tags = "C端购物车相关接口") public class ShoppingCartController { @Autowired private ShoppingCartService shoppingCartService; @PostMapping("/add") @ApiOperation("添加购物车") public Result add(@RequestBody ShoppingCartDTO shoppingCartDTO){ log.info("添加购物车,商品信息为:{}", shoppingCartDTO); shoppingCartService.addShoppingCart(shoppingCartDTO); return Result.success(); } }- 路由:
POST /user/shoppingCart/add - 功能:接收JSON请求,调用service层处理,返回成功结果
- 使用
@Slf4j:启用Lombok日志
4️⃣ 服务接口层 (Service Interface)
ShoppingCartService.java
public interface ShoppingCartService { void addShoppingCart(ShoppingCartDTO shoppingCartDTO); }5️⃣ 服务实现层 (Service Implementation)
ShoppingCartServiceImpl.java
@Service @Slf4j public class ShoppingCartServiceImpl implements ShoppingCartService { @Autowired private ShoppingCartMapper shoppingCartMapper; @Autowired private DishMapper dishMapper; @Autowired private SetmealMapper setmealMapper; public void addShoppingCart(ShoppingCartDTO shoppingCartDTO){ // 1. 构建查询条件 ShoppingCart shoppingCart = new ShoppingCart(); BeanUtils.copyProperties(shoppingCartDTO, shoppingCart); Long userId = BaseContext.getCurrentId(); // 获取当前登录用户ID shoppingCart.setUserId(userId); // 2. 查询当前用户的购物车中是否已有该商品 List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart); // 3. 如果存在该商品,数量+1 if(list != null && list.size() > 0){ ShoppingCart cart = list.get(0); cart.setNumber(cart.getNumber() + 1); shoppingCartMapper.updateNumberById(cart); } // 4. 如果不存在,需要新增一条记录 else { // 判断是菜品还是套餐 Long dishId = shoppingCartDTO.getDishId(); if(dishId != null){ // 添加的是菜品 Dish dish = dishMapper.getById(dishId); shoppingCart.setName(dish.getName()); shoppingCart.setImage(dish.getImage()); shoppingCart.setAmount(dish.getPrice()); } else { // 添加的是套餐 Long setmealId = shoppingCartDTO.getSetmealId(); Setmeal setmeal = setmealMapper.getById(setmealId); shoppingCart.setName(setmeal.getName()); shoppingCart.setImage(setmeal.getImage()); shoppingCart.setAmount(setmeal.getPrice()); } shoppingCart.setNumber(1); shoppingCart.setCreateTime(LocalDateTime.now()); shoppingCartMapper.insert(shoppingCart); } } }核心业务逻辑:
- 用户隔离:通过
BaseContext.getCurrentId()获取当前用户ID,确保每个用户只能操作自己的购物车 - 存在性检查:先查询购物车是否已存在相同商品(判断条件:userId + dishId/setmealId + dishFlavor)
- 数量累加:如果已存在,只需将数量
number + 1 - 新增记录:如果不存在,根据 dishId 或 setmealId 查询商品信息,插入新记录
6️⃣ 数据访问层 (Mapper)
ShoppingCartMapper.java
@Mapper public interface ShoppingCartMapper { // 动态条件查询 List<ShoppingCart> list(ShoppingCart shoppingCart); // 根据id修改商品数量 @Update("update shopping_cart set number = #{number} where id = #{id}") void updateNumberById(ShoppingCart shoppingCart); // 插入购物车数据 @Insert("insert into shopping_cart(name, image, user_id, dish_id, setmeal_id, dish_flavor, number, amount, create_time) " + "values(#{name}, #{image}, #{userId}, #{dishId}, #{setmealId}, #{dishFlavor}, #{number}, #{amount}, #{createTime})") void insert(ShoppingCart shoppingCart); }7️⃣ 用户上下文工具类
BaseContext.java
public class BaseContext { public static ThreadLocal<Long> threadLocal = new ThreadLocal<>(); public static Long getCurrentId() { return threadLocal.get(); } public static void setCurrentId(Long id) { threadLocal.set(id); } }查看购物车
需求分析和设计
代码开发
1️⃣ 控制层 (Controller)
ShoppingCartController.java
@GetMapping("/list") @ApiOperation("查看购物车") public Result<List<ShoppingCart>> list (){ List<ShoppingCart> list = shoppingCartService.showShoppingCart(); return Result.success(list); }- 路由:
GET /user/shoppingCart/list - 返回类型:
Result<List<ShoppingCart>>- 包装了购物车列表 - 功能:查询当前用户的购物车列表并返回
2️⃣ 服务实现层 (Service Implementation)
ShoppingCartServiceImpl.java
//查看购物车 public List<ShoppingCart> showShoppingCart(){ //获取到当前微信用户的id Long userId = BaseContext.getCurrentId(); ShoppingCart shoppingCart = ShoppingCart.builder() .userId(userId) .build(); List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart); return list; }- 用户隔离:通过
BaseContext.getCurrentId()获取当前登录用户ID - 构建查询条件:只按
userId查询,确保用户只能看到自己的购物车 - 调用Mapper:执行数据库查询并返回结果
3️⃣ Mapper 接口层
ShoppingCartMapper.java
@Mapper public interface ShoppingCartMapper { //动态条件查询 List<ShoppingCart> list(ShoppingCart shoppingCart); //根据id修改商品数量 @Update("update shopping_cart set number = #{number} where id = #{id}") void updateNumberById(ShoppingCart shoppingCart); //插入购物车数据 @Insert("insert into shopping_cart...") void insert(ShoppingCart shoppingCart); }4️⃣ MyBatis XML 映射文件核心SQL
ShoppingCartMapper.xml
<select id="list" resultType="com.sky.entity.ShoppingCart"> select * from shopping_cart <where> <if test="userId != null"> and user_id = #{userId} </if> <if test="setmealId != null"> and setmeal_id = #{setmealId} </if> <if test="dishId != null"> and dish_id = #{dishId} </if> <if test="dishFlavor != null"> and dish_flavor = #{dishFlavor} </if> </where> </select>🔄 完整请求流程
前端 GET /user/shoppingCart/list ↓ ShoppingCartController.list() ↓ ShoppingCartServiceImpl.showShoppingCart() ├── 1. 获取当前用户ID (BaseContext.getCurrentId()) ├── 2. 构建查询条件: ShoppingCart(userId=当前用户) └── 3. 调用 shoppingCartMapper.list() ↓ ShoppingCartMapper.xml.list() ↓ 执行动态SQL: SELECT * FROM shopping_cart WHERE user_id = ? ↓ 返回 List<ShoppingCart> ↓ Result.success(list) 包装结果 ↓ 前端收到购物车列表清空购物车
需求分析和设计
代码开发
1️⃣ 控制层 (Controller)
ShoppingCartController.java
//清空购物车 @DeleteMapping("/clean") @ApiOperation("清空购物车") public Result clean(){ shoppingCartService.cleanShoppingCart(); return Result.success(); }2️⃣ 服务接口层 (Service Interface)
ShoppingCartService.java
//清空购物车 void cleanShoppingCart();3️⃣ 服务实现层 (Service Implementation)核心逻辑
ShoppingCartServiceImpl.java
//清空购物车 public void cleanShoppingCart(){ //获取到当前微信用户的id Long userId = BaseContext.getCurrentId(); shoppingCartMapper.deleteByUserId(userId); }- 用户隔离:通过
BaseContext.getCurrentId()获取当前登录用户ID - 只做一件事:调用
shoppingCartMapper.deleteByUserId(userId)删除该用户的所有购物车数据 - 简洁至上:清空购物车不需要复杂的业务逻辑,只需按用户ID删除
4️⃣ 数据访问层 (Mapper) ⭐核心SQL
ShoppingCartMapper.java
//根据用户id删除购物车数据 @Delete("delete from shopping_cart where user_id = #{userId}") void deleteByUserId(Long userId);🔄 完整请求流程
前端 DELETE /user/shoppingCart/clean ↓ ShoppingCartController.clean() ↓ ShoppingCartServiceImpl.cleanShoppingCart() ├── 1. 获取当前用户ID (BaseContext.getCurrentId()) └── 2. 调用 shoppingCartMapper.deleteByUserId(userId) ↓ 执行SQL: DELETE FROM shopping_cart WHERE user_id = ? ↓ 数据库中该用户的所有购物车记录被删除 ↓ Result.success() // 返回成功 ↓ 前端收到成功响应,购物车已清空至此,操作购物车的代码开发已经全部结束