🌈个人主页:一条泥憨鱼(欢迎各位大佬莅临)

🎬精选专栏传送门:
❄️《数据结构》 ❄️《AI与Agent那些事》
❄️《从0开始学计算机网络》 ❄️《后端开发》
添加购物车
需求分析和设计




数据库设计

代码开发
1️⃣ 数据传输层 (DTO)
java
@Data
public class ShoppingCartDTO implements Serializable {
private Long dishId; // 菜品ID
private Long setmealId; // 套餐ID
private String dishFlavor; // 菜品口味
}
作用:接收前端传来的添加购物车请求数据,只包含必要的前端参数。
2️⃣ 实体类 (Entity)
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)
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)
java
public interface ShoppingCartService {
void addShoppingCart(ShoppingCartDTO shoppingCartDTO);
}
5️⃣ 服务实现层 (Service Implementation)
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)
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️⃣ 用户上下文工具类
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)
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)
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 接口层
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
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>
🔄 完整请求流程
XML
前端 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)
java
//清空购物车
@DeleteMapping("/clean")
@ApiOperation("清空购物车")
public Result clean(){
shoppingCartService.cleanShoppingCart();
return Result.success();
}
2️⃣ 服务接口层 (Service Interface)
java
//清空购物车
void cleanShoppingCart();
3️⃣ 服务实现层 (Service Implementation) 核心逻辑
java
//清空购物车
public void cleanShoppingCart(){
//获取到当前微信用户的id
Long userId = BaseContext.getCurrentId();
shoppingCartMapper.deleteByUserId(userId);
}
- 用户隔离 :通过
BaseContext.getCurrentId()获取当前登录用户ID - 只做一件事 :调用
shoppingCartMapper.deleteByUserId(userId)删除该用户的所有购物车数据 - 简洁至上:清空购物车不需要复杂的业务逻辑,只需按用户ID删除
4️⃣ 数据访问层 (Mapper) ⭐ 核心SQL
java
//根据用户id删除购物车数据
@Delete("delete from shopping_cart where user_id = #{userId}")
void deleteByUserId(Long userId);
🔄 完整请求流程
java
前端 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() // 返回成功
↓
前端收到成功响应,购物车已清空
至此,操作购物车的代码开发已经全部结束