Java Web 网络商城案例演示十四(设计订单表)

Java Web 网络商城案例演示十四(设计订单表)

订单模块

1、模型的抽取
2、提交订单
3、查询我的订单
4、订单详情
5、支付功能
6、权限过滤器
在这里插入图片描述

一、模型的抽取

订单:本次交易记录,描述

1、分析超市小票:

在这里插入图片描述

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

第一种方式:
在这里插入图片描述
弊端:数据冗余严重
DB原则:存储最少的数据,办更多的事情

第二种方式

一个表专注于交易的描述,订单表orders
在这里插入图片描述
Ordes表中的会员id列参照了用户表上的uid
订单状态:

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

另外一个表专注于每笔订单的一个详细的交易情况,订单项orderitem
在这里插入图片描述
orderitem表中的商品的id,所在订单编号是参照了商品表订单id的商品pid(流水号)

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

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

数据库当中创建表

1、订单表orders
在这里插入图片描述
其中:
oid:UUIDUtils
orderTime:new Date();
total:从购物车获取
state:1
address:null
name:null
telephone:null
uid:从session中的用户获取到

保存订单项:
向订单项表中插入数据,描述当前订单的一个详细的购买信息,部分数据是来自购物车,部分数据需要通过程序赋予。
2、订单表orderitem
提交的商品表
在这里插入图片描述
itemid:UUIDUtils
uid:来自于购物车中的购物项
total:来自购物车中的购物项
pid:来自购物车上购物项下商品对象的pid
oid:来自于当前订单的id

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

用户点击提交订单,将购物车中的数据以订单/订单的形式保存来,然后清空购物车
在这里插入图片描述
保存订单:
为订单表中插入一行数据,描述本次及交易,这行数据部分数据是通过程序赋予的,部分数据来自购物车,部分数据来自session中的用户

步骤实现

创建OrderServlet OrderService OrderServiceImpl OrderDaoImpl
Order{User user,List list = new ArrayList}
OrderItem{Product product,Order order}
创建Order{User user,List list = new ArrayList}

public class Order {
	private String oid; //订单编号
	private Date ordertime; //下单时间
	private double total; //总计
	private int state; //状态
	private String address; //收货人地址
	private String name; //收货人姓名
	private String telephone; //收货人电话
	//程序对象和对象发送关系,而不是对象和对象的属性发送关系
	//设计Order目的:让Order携带更多的数据向service,dao传递,user对象是可以携带更多的数据
	private User user;
	//程序中体现订单对象和订单之间关系,我们再在项目中的部分功能中有类似的需求:查询订单的同时还需要获取订单下所有的订单项
	private List<OrderItem> list = new ArrayList<OrderItem>();
	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 List<OrderItem> getList() {
		return list;
	}
	public void setList(List<OrderItem> list) {
		this.list = list;
	}
	public Order() {
		// TODO Auto-generated constructor stub
	}
	public Order(String oid, Date ordertime, double total, int state, String address, String name, String telephone,
			User user, List<OrderItem> list) {
		super();
		this.oid = oid;
		this.ordertime = ordertime;
		this.total = total;
		this.state = state;
		this.address = address;
		this.name = name;
		this.telephone = telephone;
		this.user = user;
		this.list = list;
	}
	@Override
	public String toString() {
		return "Order [oid=" + oid + ", ordertime=" + ordertime + ", total=" + total + ", state=" + state + ", address="
				+ address + ", name=" + name + ", telephone=" + telephone + ", user=" + user + ", list=" + list + "]";
	}
}

创建OrderItem{Product product,Order order}

package cn.itzheng.store.domain;

public class OrderItem {
	private String itemid;// id
	private int quantity; // 数量
	private double total;// 小计

	// 1、对象对应对象
	// 2、product,order携带更多的数据
	private Product product;// 获取其对象上的商品ip即为pid
	private Order order;// 获取对象上的oid,当前订单id
	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;
	}
	public OrderItem() {
		// TODO Auto-generated constructor stub
	}
	public OrderItem(String itemid, int quantity, double total, Product product, Order order) {
		super();
		this.itemid = itemid;
		this.quantity = quantity;
		this.total = total;
		this.product = product;
		this.order = order;
	}
	@Override
	public String toString() {
		return "OrderItem [itemid=" + itemid + ", quantity=" + quantity + ", total=" + total + ", product=" + product
				+ ", order=" + order + "]";
	}
}

创建OrderServlet

创建saveOrder方法
确认用户登录状态
创建订单对象,为订单对象赋值
遍历购物项的同时,创建订单项
调用业务层功能:保存订单
清空购物车
将订单放入request
转发/jsp/order_info.jsp
return “/jsp/order_info.jsp”;



public class OrderServlet extends BaseServlet {

	// saveOrder 将购物车中的信息以订单的形式保存
	public String saveOrder(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException, SQLException {
		// TODO Auto-generated method stub
		// 确认用户登录状态 从session当中获取对应user
		User user = (User) request.getSession().getAttribute("loginUser");
		if (null == user) {

			request.setAttribute("msg", "请登录之后在下单");
			return "/jsp/info.jsp";
		}

		// 从session作用域当中获取购物车
		Cart cart = (Cart) request.getSession().getAttribute("cart");

		// 创建订单对象,为订单对象赋值
		Order order = new Order();
		order.setOid(UUIDUtils.getCode());// oid获取随机的
		order.setOrdertime(new Date());// 获取当前时间
		order.setTotal(cart.getTotal());// 获取当前总金额
		order.setState(1);
		order.setUser(user);// 将当前用户放入到订单当中
		// 遍历购物项的同时,创建订单项,为订单项赋值
		for (CartItem item : cart.getCartItems()) {// 遍历购物车当中的购物项,cart.getCartItems():获取到购物车当中所有的商品的集合

			OrderItem orderItem = new OrderItem();
			orderItem.setItemid(UUIDUtils.getCode());// 设置商品编号
			orderItem.setQuantity(item.getNum());// 设置订单的商品的数量是Cart当中CartItem商品项的数量
			orderItem.setTotal(item.getSubTotal());//将商品的小计设置搭配订单项的金额当中
			orderItem.setProduct(item.getProduct());//获取到商品项当中的每一个商品,将商品项放入到订单项当中
			
			//设置当前的订单项属于那个订单:程序的角度体验订单订单项和订单对应关系
			orderItem.setOrder(order);//将订单放入到订单项当中,以便获取订单编号
			order.getList().add(orderItem);//将每一个订单项放入的到对应的订单当中

		}
		
		//调用业务层功能,保存订单
		OrderService orderService = new OrderServiceImpl();
		//将订单数据,用户数据,订单下所有的订单项都传递到service层
		orderService.saveOrder(order);
		//清空购物车
		cart.clearCart();
		//将订单信息放入request
		request.setAttribute("order", order);
		//转发到/jsp/order_info.jsp
		return "/jsp/order_info.jsp";
	}
}

OrderService

public interface OrderService {

	void saveOrder(Order order) throws SQLException;

}

OrderServiceImpl


public class OrderServiceImpl implements OrderService {

	OrderDao orderDao = new OrderDaoImpl();
	
	@Override
	public void saveOrder(Order order) throws SQLException {
		
		/*
		 * try { //保存订单和订单下所有的订单项(同时成功或者同时失败) //开启数据的事务 JDBCUtils.startTransaction();
		 * OrderDao orderDao = new OrderDaoImpl();
		 * 
		 * orderDao.saveOrder(order);
		 * 
		 * for(OrderItem item:order.getList()) {//遍历所有的订单项 orderDao.saveOrderItem(item);
		 * }
		 * 
		 * 
		 * } catch (Exception e) { // TODO: handle exception
		 * JDBCUtils.commitAndClose();//关闭事务 }
		 */
		
		Connection conn = null;
		try {
			//获取到链接
			conn = JDBCUtils.getConnection();
			//开启事务
			conn.setAutoCommit(false);//开启事务
			
			//保存订单
			orderDao.savaOrder(conn,order);
			
			//保存订单项
			//遍历订单上的每一个购物项
			for(OrderItem item:order.getList()) {
				orderDao.savaOrderItem(conn,item);
				
			}
			//提交事务
			conn.commit();
			
			
		} catch (Exception e) {
			// TODO: handle exception
			
			//如果有异常
			//回滚事务
			conn.rollback();
		}
			
	}
}

OrderDao

public interface OrderDao {
	void savaOrderItem(Connection conn, OrderItem item) throws SQLException;
	void savaOrder(Connection conn, Order order)throws SQLException;
}
public class OrderDaoImpl implements OrderDao {
	// 保存订单
	@Override
	public void savaOrder(Connection conn, Order order) throws SQLException {
		// TODO Auto-generated method stub
		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 savaOrderItem(Connection conn, OrderItem item) throws SQLException {
		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);
	}

}

修改/jsp/order_info.jsp
在这里插入图片描述
在这里插入图片描述

我的订单查询

原理分析:

在这里插入图片描述

步骤实现

1、准备工作:
在header.jsp

<li><a href="${pageContext.request.contextPath}/OrderServlet?method=findMyOrdersWithPage&num=1">我的订单</a></li>

2、OrderServlet—>findMyOrdersWithPage
获取用户信息
获取当前页
调用业务层功能:查询当前用户订单信息,返回PageModel
将PageModel放入request
转发到/jsp/order_list.jsp
3、OrderService当中实现findMyOrdersWithPage方法

public interface OrderService {
	PageModel findMyOrdersWithPage(User user, int curNum)throws SQLException;
}

4、OrderService当中实现findMyOrdersWithPage方法

@Override
	public PageModel findMyOrdersWithPage(User user, int curNum) throws SQLException {
		// 1、创建PageModel对象,目的:接收并且携带分页参数
		//select count(*) from orders where uid = ?  统计当前用户的所有订单
		int totalRecords = orderDao.getTotalRecords(user);		
		PageModel pm = new PageModel(curNum, totalRecords, 3);		
		//2、关联集合 select * from orders where uid = ? limit ?,?;		
		List list = orderDao.findMyOrdersWithPage(user,pm.getStartIndex(),pm.getPageSize());
		pm.setList(list);
		//3、关联url
		pm.setUrl("OrderServlet?method=findMyOrdersWithPage");
		return pm;
	}

5、在OrderDao当中实现findMyOrdersWithPage

public interface OrderDao {
	List findMyOrdersWithPage(User user, int startIndex, int pageSize)throws SQLException;
}

在OrderDaoImpl 当中实现findMyOrdersWithPage

public class OrderDaoImpl implements OrderDao {
	@Override
	public List findMyOrdersWithPage(User user, int startIndex, int pageSize) throws SQLException {
		// TODO Auto-generated method stub
		String sql = "select * from orders where uid = ? limit ?,?";
		QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
		// 获取到分页信息相关的list集合(Order集合)
		List<Order> list = qr.query(sql, new BeanListHandler<Order>(Order.class), user.getUid(), startIndex, pageSize);
		// 遍历所有订单
		for (Order order : list) {
			// 获取到每笔订单oid 查询每笔订单下订单项以及订单项对应的商品信息
			String oid = order.getOid();
			// SELECT * FROM orderItem,product返回的是笛卡尔集
			// 商品编号必须匹配(保证是同一个商品) 并通过的是oid来查询即订单编号来查询
			sql = "select * from orderItem o ,product p where o.pid=p.pid and oid=?";
			List<Map<String, Object>> list02 = qr.query(sql, new MapListHandler(), oid);// 获取到的是笛卡尔集的所有对应的商品集合
			// 遍历list集合
			for (Map<String, Object> map : list02) {
				// 实例化
				OrderItem orderItem = new OrderItem();
				Product product = new Product();
				// 由于BeanUtlis将字符串“1992-3-3”向user对象的setBithday();方法传递参数有问题,手动向BeanUtils注册一个时间类型转换器
				// 1、创建时间类型的转换器
				DateConverter dt = new DateConverter();
				// 2、设置转换的格式
				dt.setPattern("yyyy-MM-dd");
				// 3、注册转换器
				ConvertUtils.register(dt, Date.class);// 将Date对象设置为dt当中的格式
				try {
					// 将map中属于orderItem的数据自动填充到orderItem对象上
					BeanUtils.populate(orderItem, map);
					// 将map中属于product的数据自动填充到product对象上
					BeanUtils.populate(product, map);

					// 让每一个订单项和商品项发生关系
					orderItem.setProduct(product);// 将商品项当中的内容放到订单项当中

					order.getList().add(orderItem);// 将订单项放到订单当中的list集合当中

				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			// 根据订单id,查询当前订单下所有的订单项以及订单项对应的商品信息
			// select * from product;

		}
		return list;
	}

6、在order_list.jsp
遍历数据时,2个循环,大循环遍历订单,小循环遍历的是订单上的订单项

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>   
<!doctype html>
<html>

	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title>会员登录</title>
		<link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap.min.css" type="text/css" />
		<script src="${pageContext.request.contextPath}/js/jquery-1.11.3.min.js" type="text/javascript"></script>
		<script src="${pageContext.request.contextPath}/js/bootstrap.min.js" type="text/javascript"></script>
		<!-- 引入自定义css文件 style.css -->
		<link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css" type="text/css"/>

		<style>
			body {
				margin-top: 20px;
				margin: 0 auto;
			}
			
			.carousel-inner .item img {
				width: 100%;
				height: 300px;
			}
		</style>
	</head>

	<body>

			<%@ include file="/jsp/header.jsp" %>

		<div class="container">
			<div class="row">

				<div style="margin:0 auto; margin-top:10px;width:950px;">
					<strong>我的订单</strong>
					<table class="table table-bordered">
					<c:forEach items="${page.list}" var="o">	
						<tbody>
							<tr class="success">
								<th colspan="5">
									订单编号:${o.oid}
									总金额:¥${o.total}<c:if test="${o.state==1}">
										<a href="${pageContext.request.contextPath}/OrderServlet?method=findOrderByOid&oid=${o.oid}">付款</a>
									</c:if>	 
									<c:if test="${o.state==2}">未发货</c:if>
									<c:if test="${o.state==3}">
										<a href="">签收</a>
									</c:if>	 
									<c:if test="${o.state==4}">结束</c:if>	 
								</th>
							</tr>
							<tr class="warning">
								<th>图片</th>
								<th>商品</th>
								<th>价格</th>
								<th>数量</th>
								<th>小计</th>
							</tr>
						<c:forEach items="${o.list}" var="item">	
							<tr class="active">
								<td width="60" width="40%">
									<input type="hidden" name="id" value="22">
									<img src="${pageContext.request.contextPath}/${item.product.pimage}" width="70" height="60">
								</td>
								<td width="30%">
									<a target="_blank">${item.product.pname}</a>
								</td>
								<td width="20%">
									¥${item.product.shop_price}
								</td>
								<td width="10%">
									${item.quantity}
								</td>
								<td width="15%">
									<span class="subtotal">¥${item.total}</span>
								</td>
							</tr>
						  </c:forEach>
						</tbody>
					  </c:forEach>	
					</table>
					<%@ include file="/jsp/pageFile.jsp" %>
				</div>
			</div>
		</div>
		<%@ include file="/jsp/footer.jsp" %>
	</body>

</html>
原创文章 76 获赞 151 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_44757034/article/details/105146284