尚硅谷JavaWeb笔记——书城项目(第八阶段:订单模块添加)

第八阶段-订单模块

由订单界面分析订单的模型分析可得到如下的功能分析图。具体地,一个Order订单中会包含多个订单项,同一个订单中的各个订单项的订单号也是相同的。由于订单项是参考订单id的(外键),因此需要先由Order订单,再有订单中的各个订单项

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NZ9PzfYU-1614147841094)(/Users/gaojunsong/Library/Application Support/typora-user-images/Java学习/JAVAWeb/image-20210221135642967.png)]

Step1:构建数据库表

根据数据库关系模型关系,可构建订单表以及订单项表。其中订单表涉及订单号,下单时间,价格,状态,用户id的信息,每一个订单项对应唯一的订单号(外键),同时订单项由自身id,商品名称,价格,总价

create table t_order(
  `order_id` varchar(50) primary key ,
  `create_time` datetime,
  `price` decimal(11,2),
  `status` int,
  `user_id` int,
  foreign key (`user_id`) references t_user(`id`)
);

create table t_order_item(
    `id` int primary key auto_increment,
    `name` varchar(100),
    `count` int,
    `price` decimal(11,2),
    `total_price` decimal(11,2),
    `order_id` varchar(50),
    foreign key (`order_id`) references t_order(`order_id`)
)

Step2:构建pojo类对象

基于上述数据库表,可以在pojo中构建order类以及orderItem类

order类

public class Order {
  private String orderId;
  private Date creatTime;
  private BigDecimal price;
  //0 未发货 1 已发货 2 已签收
  private Integer status = 0;
  private Integer userId;

  public Order() {
  }

  public Order(String orderId, Date creatTime, BigDecimal price, Integer status, Integer userId) {
    this.orderId = orderId;
    this.creatTime = creatTime;
    this.price = price;
    this.status = status;
    this.userId = userId;
  }
  
  //getset方法
}

orderItem类

public class OrderItem {
  private Integer id;
  private String name;
  private Integer count;
  private BigDecimal price;
  private BigDecimal totalPrice;
  private String orderId;

  public OrderItem() {
  }

  public OrderItem(Integer id, String name, Integer count, BigDecimal price, BigDecimal totalPrice, String orderId) {
    this.id = id;
    this.name = name;
    this.count = count;
    this.price = price;
    this.totalPrice = totalPrice;
    this.orderId = orderId;
  }
  // getset方法
}

Step3:Dao层的编写与测试

根据上述分析,在Dao层调用了生成订单的方法后就会在数据控中创建一个订单以及订单项的的sql语句为:

insert into t_order(`order_id`, `creat_time`, `price`, `status`, `user_id`) values(?,?,?,?,?)
insert into t_order_item(`name`, `count`, `price`, `total_price`, `order_id`) values(?,?,?,?,?)

因此,Dao层的传入数据应当是一个order对象以及orderItem对象

先定义接口规范,这里以保存订单为例

public interface OrderDao {
    public int saveOrder(Order order);
}

public interface OrderItemDao {
    public int saveOrderItem(OrderItem orderItem);
}

对应的实现类代码如下:

/*
*	在数据库中保存一个订单,需要传入一个order对象
*/
public class OrderDaoImpl extends BaseDao implements OrderDao {
  @Override
  public int saveOrder(Order order) {
    System.out.println("OrderDaoImpl 程序在[" +Thread.currentThread().getName() + "]中");


    String sql = "insert into t_order(`order_id`, `creat_time`, `price`, `status`, `user_id`) values(?,?,?,?,?)";
    int i = update(sql, order.getOrderId(), order.getCreatTime(), order.getPrice(), order.getStatus(), order.getUserId());
    return i;
  }
}

/*
*	在数据库中保存一个订单项,需要传入一个orderItem对象
*/
public class OrderItemDaoImpl extends BaseDao implements OrderItemDao {
  @Override
  public int saveOrderItem(OrderItem orderItem) {
    System.out.println(" OrderItemDaoImpl 程序在[" +Thread.currentThread().getName() + "]中");

    String sql = "insert into t_order_item(`name`, `count`, `price`, `total_price`, `order_id`) values(?,?,?,?,?)";
    int i = update(sql, orderItem.getName(), orderItem.getCount(), orderItem.getPrice(), orderItem.getTotalPrice(), orderItem.getOrderId());
    return i;
  }
}

Step4:Service层的编写与测试

在Service层灰调用Dao层,Service层的createOrder()方法需要给Dao层传递一个order对象,同时返回该order对象的订单号。其需要从Web层获取购物车对象以及用户的id信息,从而完成order对象以及orderItem对象的封装。在这一层中涉及OrderDaoOrderItemDao以及bookDao三个Dao对象的方法。

首先写Service层的接口规范

public interface OrderService {
    public String creatOrder(Cart cart, Integer userId);
}

实现流程如下:

  1. 利用从Web层中得到的购物车对象cart,以及当前用户Id生成唯一的订单号信息OrderId
  2. 利用订单号OrderId创建一个order对象,并将调用orderDao层的orderSave()方法该对象保存至数据库
  3. 遍历当前购物车中的每个数据项,利用相关信息创建orderItem项,并调用orderItemSave()方法将这些对象都依次保存至数据库中
  4. 调用book.setSales()方法更新数据库中图书的库存和销量信息
  5. 清空购物车,返回订单号

上述过程对应代码如下;

public class OrderServiceImpl implements OrderService {
  private OrderDao orderDao = new OrderDaoImpl();
  private OrderItemDao orderItemDao = new OrderItemDaoImpl();
  private BookDao bookDao = new BookDaoImpl();

  @Override
  public String creatOrder(Cart cart, Integer userId) {

    // 订单号===唯一性
    String orderId = System.currentTimeMillis() + "" + userId;
    // 创建一个订单对象
    Order order = new Order(orderId, new Date(), cart.getTotalPrice(), 0, userId);
    // 保存订单
    orderDao.saveOrder(order);

    // 遍历购物车中每一个商品项转换成为订单项保存到数据库
    for (Map.Entry<Integer, CartItem> entry : cart.getItems().entrySet()) {
      // 获取每一个购物车中的商品项
      CartItem cartItem = entry.getValue();
      // 转换为每一个订单项
      OrderItem orderItem = new OrderItem(null, cartItem.getName(), cartItem.getCount(), cartItem.getPrice(), cartItem.getTotalPrice(), orderId);
      // 保存订单项到数据库
      orderItemDao.saveOrderItem(orderItem);
      // 更新库存和销量
      Book book = bookDao.queryBookById(cartItem.getId());
      book.setSales(book.getSales() + cartItem.getCount());
      book.setSales(book.getStock() - cartItem.getCount());
      bookDao.updateBook(book);
    }
    // 清空购物车
    cart.clear();
    return orderId;
  }
}

Step5:Web层的编写与测试

Web层中,需要获取用户的点击信息(在购物车页面点击结算按钮),同时将当前页面信息展示为订单号

具体步骤如下:

  1. 获取当前用户对应的session中的cart对象,以及用户的id信息
    • 如果当前用户信息为空,让其进入登陆页面
  2. 调用Service层的creatOrder()方法并获取对应的订单编号信息
  3. 将订单编号信息保存至Session域中并将响应重定向至/pages/cart/checkout.jsp页面。

对应源码如下:

protected void creatOrder(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  // 先获取Cart购物车对象
  Cart cart = (Cart)request.getSession().getAttribute("cart");
  // 获取Userid
  User loginUser = (User)request.getSession().getAttribute("user");
  if (loginUser == null) {
    request.getRequestDispatcher("/pages/user/login.jsp").forward(request, response);
    return;
  }

  Integer userId = loginUser.getId();
  // 调用orderService.createOrder(Cart,Userid);生成订单
  String orderId = orderService.createOrder(cart, userId);


  request.getSession().setAttribute("orderId", orderId);
  response.sendRedirect(request.getContextPath() + "/pages/cart/checkout.jsp");
}
  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值