Spring Boot添加商品到购物车报错、分类不加载及实体关联、账单页开发问题
问题修复与实现方案
一、分类下拉框无数据修复
问题原因
- 控制器返回makeABill页面时,未将全部分类数据存入Model
- 前端Thymeleaf遍历对象错误,当前遍历的
cartItem是单个购物车对象,不存在分类集合
修复步骤
- 新增
CategoriesRepository接口继承JpaRepository<Categories, Long> - 修改
CartItemsControllers的createCartItemForm方法,注入分类、商品Repository,将数据放入Model:
@Autowired private CategoriesRepository categoriesRepository; @Autowired private ProductsRepository productsRepository; @GetMapping("/cart/create") public String createCartItemForm(Model model) { CartItem cartItem = new CartItem(); model.addAttribute("cartItem",cartItem); // 加入全部分类数据 model.addAttribute("categories", categoriesRepository.findAll()); // 加入全部商品数据(如果用联动可后续用Ajax加载,也可初始化全量) model.addAttribute("allProducts", productsRepository.findAll()); return "makeABill"; }
- 修正前端分类下拉框代码:
<select class="form-control form-control-sm" id="category" name="category" autofocus> <option value="">Select Category</option> <option th:each = "category: ${categories}" th:value="${category.categories_id}" th:text="${category.categoryName}"> </option> </select>
- 商品下拉框可以做分类联动,选分类后过滤对应分类的商品,也可以直接遍历allProducts,示例:
<select class="form-control form-control-sm" id="product" name="product" autofocus> <option value="">Select Product</option> <option th:each = "product: ${allProducts}" th:value="${product.product_id}" th:text="${product.product_name}"> </option> </select>
二、实体关联关系修正
当前实体关联存在多处错误,修正如下:
Orders实体新增客户关联,修正购物车项映射:
@Entity @RequiredArgsConstructor @AllArgsConstructor @Data public class Orders { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long order_id; // 新增关联客户 @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "customer_order_fk", insertable = false, updatable = false) private Customers customer; // 修正mappedBy,值为CartItem实体中关联Orders的属性名 @OneToMany(fetch = FetchType.LAZY,mappedBy = "order",cascade = CascadeType.ALL) private Set<CartItem> cartItem; private double total_price; }
Products实体修正客户关联的外键列:
// 修正空的@JoinColumn @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "customer_id") private Customers customer;
- 补充
CartItem实体核心字段:
@Entity @Data public class CartItem { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long cart_item_id; @ManyToOne @JoinColumn(name = "product_id") private Products product; private Integer quantity; @ManyToOne @JoinColumn(name = "order_order_id") private Orders order; private Customers customer; }
三、表单数据关联Order实现
修改saveCartItem方法的逻辑,关联所有实体:
@PostMapping("/cart/save") public String saveCartItem(@ModelAttribute("cartItem") CartItem cartItem, HttpSession session) { // 1. 先保存客户信息 Customers savedCustomer = customersRepository.save(cartItem.getCustomer()); // 2. 创建/获取当前订单(如果是同个客户多次加购可以用Session存当前订单ID) Orders currentOrder = new Orders(); currentOrder.setCustomer(savedCustomer); // 3. 关联购物车项和订单 cartItem.setOrder(currentOrder); cartItem.setCustomer(savedCustomer); // 4. 计算当前购物车项金额,累加订单总金额 BigDecimal itemTotal = cartItem.getProduct().getProduct_price().multiply(new BigDecimal(cartItem.getQuantity())); currentOrder.setTotal_price(currentOrder.getTotal_price() + itemTotal.doubleValue()); // 5. 保存订单级联保存购物车项 ordersRepository.save(currentOrder); // 6. 刷新页面时携带当前订单的购物车列表,用于表格渲染 return "redirect:/cart/create?orderId=" + currentOrder.getOrder_id(); }
后续订单列表页直接查询Orders实体,即可关联获取对应客户、所有购物车商品信息。
四、账单HTML页面实现
- 新增控制器接口,根据订单ID查询账单数据:
@GetMapping("/bill/{orderId}") public String showBill(@PathVariable Long orderId, Model model) { Orders order = ordersRepository.findById(orderId).orElseThrow(() -> new RuntimeException("订单不存在")); model.addAttribute("order", order); model.addAttribute("cartItems", order.getCartItem()); return "bill"; }
- 账单页
bill.html核心内容,渲染客户信息、商品明细、总金额即可。
内容的提问来源于stack exchange,提问作者Hesham Eldawy
相关产品推荐
相关产品推荐

