用户在购物车中提交订单,将购物车中的数据以订单/订单项的形式保存下来,之后清空购物车。
整体技术路线:客户端点击提交订单至OrderServlet中saveOrder方法中,将购物车中的购物信息以订单形式保存,清空购物车,之后将订单放入request,转发到订单详情页面。
将购物车中信息抽取成两个数据库表,分别是:
(1)order表:表示此次交易的所有商品项,类似于超市小票;
为订单表中插入一行数据,描述本次交易,这行数据部分数据是通过程序赋予,部分数据来自于购物车的,部分数据来自于session中的用户,其中字段包含:
oid:UUIDUtils orderTime:new Date(); total: 从购物车获取 state:1 address: null name:null telephone:null uid:从session中的用户获取
(2)orderitem表:表示此次订单中的每个订单项,类似于小票中的各个商品项;
向订单项表中插入数据,描述当前订单的详细的购买信息,部分数据来自于购物车,部分数据需要通过程序赋予
itemid: UUIDUtils quantity:来自于购物车中的购物项 total:来自于购物车中的购物项 pid:来自于购物车上的购物项下商品对象pid oid:来自于当前订单id
注:商品提交时需要加入事务,一旦订单或订单项提交失败,则全部回滚
思路:点击cart.jsp页面中的【提交订单】,调用服务器端的OrderServlet中的saveOrder方法,之后调用OrderService OrderServiceImp OrderDao OrderDaoImp中的saveOrder方法,最终将数据存入数据库。
代码如下:
购物车界面:cart.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
购物车
<%@ include file="/jsp/header.jsp" %>
开启剁手模式
订单详情
图片
商品
价格
数量
小计
操作
${item.product.pname}
¥${item.product.shop_price}
¥${item.subTotal}
删除
登录后确认是否享有优惠
赠送积分: ${cart.total} 商品金额: ¥${cart.total}元
<%@ include file="/jsp/footer.jsp" %>
OrderServlet.java
ackage cn.itcast.store.web.servlet;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.itcast.store.domain.Cart;
import cn.itcast.store.domain.CartItem;
import cn.itcast.store.domain.Order;
import cn.itcast.store.domain.OrderItem;
import cn.itcast.store.domain.PageModel;
import cn.itcast.store.domain.User;
import cn.itcast.store.service.OrderService;
import cn.itcast.store.service.serviceImp.OrderServiceImp;
import cn.itcast.store.utils.PaymentUtil;
import cn.itcast.store.utils.UUIDUtils;
import cn.itcast.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";
}
}
OrderService.java
package cn.itcast.store.service;
import java.util.List;
import cn.itcast.store.domain.Order;
import cn.itcast.store.domain.PageModel;
import cn.itcast.store.domain.User;
public interface OrderService {
void saveOrder(Order order)throws Exception;
}
OrderServiceImp.java
package cn.itcast.store.service.serviceImp;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import cn.itcast.store.dao.OrderDao;
import cn.itcast.store.dao.daoImp.OrderDaoImp;
import cn.itcast.store.domain.Order;
import cn.itcast.store.domain.OrderItem;
import cn.itcast.store.domain.PageModel;
import cn.itcast.store.domain.User;
import cn.itcast.store.service.OrderService;
import cn.itcast.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.java
package cn.itcast.store.dao;
import java.sql.Connection;
import java.util.List;
import cn.itcast.store.domain.Order;
import cn.itcast.store.domain.OrderItem;
import cn.itcast.store.domain.User;
public interface OrderDao {
void saveOrder(Connection conn, Order order)throws Exception;
void saveOrderItem(Connection conn, OrderItem item)throws Exception;
}
OrderDaoImp.java
package cn.itcast.store.dao.daoImp;
import java.sql.Connection;
import java.util.List;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.DateConverter;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import cn.itcast.store.dao.OrderDao;
import cn.itcast.store.domain.Order;
import cn.itcast.store.domain.OrderItem;
import cn.itcast.store.domain.Product;
import cn.itcast.store.domain.User;
import cn.itcast.store.utils.JDBCUtils;
public class OrderDaoImp implements OrderDao {
@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);
}
}
Order.java
package cn.itcast.store.domain;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class Order {
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 List list = 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 List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
}
OrderItem.java
package cn.itcast.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;
}
}
order_info.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
下订单
<%@ include file="/jsp/header.jsp" %>
<%@ include file="/jsp/footer.jsp" %>