商城模块java_Javaweb网上商城项目实战(22)提交订单模块

本文介绍了网上商城项目中订单模块的设计思路,从最初的表设计问题到改进方案,包括订单表`orders`和订单项表`orderitem`。详细讲解了提交订单的原理,涉及用户信息、购物车数据、事务处理等,同时提供了Order和OrderItem的Java类实现以及相关Servlet、Service、DAO的代码示例。文章最后展示了提交订单成功后数据库的更新效果。
摘要由CSDN通过智能技术生成

分析订单表-以超市小票为例

超市小票案例

会员ID:583381

流水号:jlf_ba_31_sy003_1002

交易时间:2018年3月10日08:41:53

商品名称 商品价格 商品数量 小计

好日子 15 2 30

芙蓉王 25 2 50

黄鹤楼 15 3 45

大前门 10 1 10

总金额:135元

设计表,存储小票上的数据

会员id 流水号 交易时间 商品名称 商品价格 商品数量 小计 总金额

1231231 XXX XXXX 好日子 15 2 30 135

1231231 XXX XXXX 芙蓉王 25 2 50 135

1231231 XXX XXXX 黄鹤楼 15 3 45 135

1231231 XXX XXXX 大前门 10 1 10 135

这种是我们最直接的想法,直接把订单项存到一个表中,但是这种设计有一个严重的弊端。

[v_error]弊端:数据冗余严重。[/v_error]

[v_notice]DB原则:存储最少的数据,办更多的事情。[/v_notice]

改进方案

一个表专注于交易描述,订单表 orders

订单id(流水号) 会员id 交易时间 总金额 收货人姓名 地址 电话 订单状态(1234)

1123 1231231 XXXX 135

1124 1234444 YYYY 200

orders表中的会员id列参照了用户表uid

订单状态:

买家:下单未付款,付款未发货,已发货,签收

卖家: 未付款,发货,未签收,已收货(结束)

一个表专注于每笔订单详细交易情况,订单项orderitem

订单项id 商品id 数量 小计 所在订单编号

001 p003 2 30 1123

002 p005 2 50 1123

003 p101 3 45 1123

004 p220 1 10 1123

005 p334 1 101 1124

006 p556 3 54 1124

007 p445 5 45 1124

orderitem表中的商品id参照了商品表的pid

orderitem表中的所在订单编号参照了订单表的订单id

我们本次项目所用的就是第二个方案,之前我们已经完成了表的设计

gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==

提交订单原理分析

用户点击提交订单,将购物车中的数据以订单/订单项形式保存下来。

gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==

保存订单:

为订单表中插入一行数据,描述本次交易,这行数据部分数据是通过程序赋予,部分数据来自购物车的,部分数据来自session中的用户。

oid:UUIDUtils orderTime:new Date(); total: 从购物车获取

state:1 address: null name:null telephone:null uid:从session中的用户获取

保存订单项:

向订单项表中插入数据,描述当前订单的详细的购买信息,部分数据来自于购物车,部分数据需要通过程序赋予。

itemid: UUIDUtils quantity:来自于购物车中的购物项

total:来自于购物车中的购物项 pid:来自于购物车上的购物项下商品对象pid oid:来自于当前订单id

[v_warn]提交订单时,订单以及订单项必须同时成功(事务)[/v_warn]

具体实现

实现订单模块相关程序

创建OrderServlet、OrderService、OrderServiceImp、OrderDao、OrderDaoImp。

在domain中创建Order和OrderItem。

Order.java

根据数据库Order表创建

gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==

package com.geekerstar.store.domain;

import java.util.ArrayList;

import java.util.Date;

import java.util.List;

public class Order {

@Override

public String toString() {

return "Order [oid=" + oid + ", ordertime=" + ordertime + ", total=" + total + ", state=" + state + ", address="

+ address + ", name=" + name + ", telephone=" + telephone + ", user=" + user + ", list=" + list + "]";

}

private String oid; //订单编号

private Date ordertime; //下单时间

private double total; //总计

private int state; //状态

private String address; //收货人地址

private String name; //收货人姓名

private String telephone; //收货人电话

// private String uid;

// 1_程序对象和对象发生关系,而不是对象和对象的属性发生关系

// 2_设计Order目的:让order携带订单上的数据向service,dao传递,user对象是可以携带更多的数据

private User user;

// 程序中体现订单对象和订单项之间关系,我们再项目中的部分功能中有类似的需求:查询订单的同时还需要获取订单下所有的订单项

private Listlist = new ArrayList();

public String getOid() {

return oid;

}

public void setOid(String oid) {

this.oid = oid;

}

public Date getOrdertime() {

return ordertime;

}

public void setOrdertime(Date ordertime) {

this.ordertime = ordertime;

}

public double getTotal() {

return total;

}

public void setTotal(double total) {

this.total = total;

}

public int getState() {

return state;

}

public void setState(int state) {

this.state = state;

}

public String getAddress() {

return address;

}

public void setAddress(String address) {

this.address = address;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getTelephone() {

return telephone;

}

public void setTelephone(String telephone) {

this.telephone = telephone;

}

public User getUser() {

return user;

}

public void setUser(User user) {

this.user = user;

}

public ListgetList() {

return list;

}

public void setList(Listlist) {

this.list = list;

}

}

OrderItem

根据数据库orderitem表创建

gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==

package com.geekerstar.store.domain;

public class OrderItem {

private String itemid; //id

private int quantity; //数量

private double total; //小计

//1_对象对应对象

//2_product,order携带更多的数据

private Product product;

private Order order;

public String getItemid() {

return itemid;

}

public void setItemid(String itemid) {

this.itemid = itemid;

}

public int getQuantity() {

return quantity;

}

public void setQuantity(int quantity) {

this.quantity = quantity;

}

public double getTotal() {

return total;

}

public void setTotal(double total) {

this.total = total;

}

public Product getProduct() {

return product;

}

public void setProduct(Product product) {

this.product = product;

}

public Order getOrder() {

return order;

}

public void setOrder(Order order) {

this.order = order;

}

}

JSP页面准备工作

在Cart.jsp中修改提交订单链接到OrderServlet

OrderServlet中增加saveOrder方法

package com.geekerstar.store.web.servlet;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.geekerstar.store.domain.Cart;

import com.geekerstar.store.domain.CartItem;

import com.geekerstar.store.domain.Order;

import com.geekerstar.store.domain.OrderItem;

import com.geekerstar.store.domain.User;

import com.geekerstar.store.service.OrderService;

import com.geekerstar.store.service.serviceImp.OrderServiceImp;

import com.geekerstar.store.utils.UUIDUtils;

import com.geekerstar.store.web.base.BaseServlet;

public class OrderServlet extends BaseServlet {

// saveOrder 将购物车中的信息以订单的形式保存

public String saveOrder(HttpServletRequest req, HttpServletResponse resp) throws Exception {

// 确认用户登录状态

User user = (User) req.getSession().getAttribute("loginUser");

if (null == user) {

req.setAttribute("msg", "请登录之后在下单");

return "/jsp/info.jsp";

}

// 获取购物车

Cart cart = (Cart) req.getSession().getAttribute("cart");

// 创建订单对象,为订单对象赋值

Order order = new Order();

order.setOid(UUIDUtils.getCode());

order.setOrdertime(new Date());

order.setTotal(cart.getTotal());

order.setState(1);

order.setUser(user);

// 遍历购物项的同时,创建订单项,为订单项赋值

for (CartItem item : cart.getCartItems()) {

OrderItem orderItem = new OrderItem();

orderItem.setItemid(UUIDUtils.getCode());

orderItem.setQuantity(item.getNum());

orderItem.setTotal(item.getSubTotal());

orderItem.setProduct(item.getProduct());

// 设置当前的订单项属于哪个订单:程序的角度体检订单项和订单对应关系

orderItem.setOrder(order);

order.getList().add(orderItem);

}

// 调用业务层功能:保存订单

OrderService OrderService = new OrderServiceImp();

// 将订单数据,用户的数据,订单下所有的订单项都传递到了service层

OrderService.saveOrder(order);

// 清空购物车

cart.clearCart();

// 将订单放入request

req.setAttribute("order", order);

// 转发/jsp/order_info.jsp

return "/jsp/order_info.jsp";

}

}

修改web.xml

web.xml中添加

OrderServlet

OrderServlet

com.geekerstar.store.web.servlet.OrderServlet

OrderServlet

/OrderServlet

在Cart.java中做如下修改

//返回MAP中所有的值

public CollectiongetCartItems(){

return map.values();

}

在OrderService中创建方法

void saveOrder(Order order)throws Exception;

在OrderServiceImp中实现方法,用事务实现

package com.geekerstar.store.service.serviceImp;

import java.sql.Connection;

import java.sql.SQLException;

import java.util.List;

import com.geekerstar.store.dao.daoImp.OrderDaoImp;

import com.geekerstar.store.domain.Order;

import com.geekerstar.store.domain.OrderItem;

import com.geekerstar.store.domain.PageModel;

import com.geekerstar.store.domain.User;

import com.geekerstar.store.service.OrderService;

import com.geekerstar.store.utils.JDBCUtils;

public class OrderServiceImp implements OrderService {

OrderDao orderDao=new OrderDaoImp();

@Override

public void saveOrder(Order order) throws SQLException {

//保存订单和订单下所有的订单项(同时成功,失败)

/*try {

JDBCUtils.startTransaction();

OrderDao orderDao=new OrderDaoImp();

orderDao.saveOrder(order);

for(OrderItem item:order.getList()){

orderDao.saveOrderItem(item);

}

JDBCUtils.commitAndClose();

} catch (Exception e) {

JDBCUtils.rollbackAndClose();

}

*/

Connection conn=null;

try {

//获取连接

conn=JDBCUtils.getConnection();

//开启事务

conn.setAutoCommit(false);

//保存订单

orderDao.saveOrder(conn,order);

//保存订单项

for (OrderItem item : order.getList()) {

orderDao.saveOrderItem(conn,item);

}

//提交

conn.commit();

} catch (Exception e) {

//回滚

conn.rollback();

}

}

}

OrderDao中添加方法

void saveOrder(Connection conn, Order order)throws Exception;

void saveOrderItem(Connection conn, OrderItem item)throws Exception;

OrderDaoImp中实现两个方法

@Override

public void saveOrder(Connection conn, Order order) throws Exception {

String sql="INSERT INTO orders VALUES(?,?,?,?,?,?,?,?)";

QueryRunner qr=new QueryRunner();

Object[] params={order.getOid(),order.getOrdertime(),order.getTotal(),order.getState(),order.getAddress(),order.getName(),order.getTelephone(),order.getUser().getUid()};

qr.update(conn,sql,params);

}

@Override

public void saveOrderItem(Connection conn, OrderItem item) throws Exception {

String sql="INSERT INTO orderitem VALUES(?,?,?,?,?)";

QueryRunner qr=new QueryRunner();

Object[] params={item.getItemid(),item.getQuantity(),item.getTotal(),item.getProduct().getPid(),item.getOrder().getOid()};

qr.update(conn,sql,params);

}

修改订单详情页面

这是原来的订单详情页面,我们将对其做修改

gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==

order_info.jsp中获取订单信息,由于页面较多就不一一展示了,详情请看源码,并且原理和之前的一样,可以参考下面的图片进行修改。

gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==

效果演示

运行程序,添加两件商品到购物车,然后点击提交订单按钮

gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==

此时跳到这个页面

gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==

然后我们查看数据库,发现订单信息已经添加到数据库了,提交订单成功

gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==

gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==

源码下载

[dm href=’https://www.jikewenku.com/product/1700.html’]下载地址[/dm]

导航目录

[dm href=’https://www.jikewenku.com/project/2786.html’]查看导航[/dm]

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值