订单模块类创建及配置
购物完成之后,提交订单,生成一个订单
订单表和商品的关系:
订单和商品的关系是多对多,一个订单可以有多个商品,一个商品可以属于多个订单。
如果是多对多的关系,那么建表的时候应该建第三张表(中间表),存订单表和商品表的id。
中间表:订单项表:
订单表和商品表是多对多关系,可以通过两个一对多的形式完成多对多的关联关系。即商品对订单项是一对多,订单对订单项也是一对多,两个表对中间表的一对多关系相当于商品和订单表的多对多关系。
说下这样处理的好处,如果你把商品表和订单表的关系创建成多对多的关系,中间表只会维护商品id和订单id,中间的订单表的其他字段是不会自动维护的,如果配成一对多,其他自动就可以自动维护。
订单表:
/***
* 订单表
*
*/
@SuppressWarnings("serial")
public class Order implements Serializable {
private long oid;// 订单id
private Double total; // 总计
private Date orderTime;// 订单下单时间
private int state; // 订单状态
private String name;// 用户名
private String addr; // 地址
private String phone;// 用户电话
// 订单所属用户
private User user;
// 订单中包含多个订单项
private Set<OrderItem> orderItems = new HashSet<OrderItem>();
//省略setter getter方法
OrderItem订单项表:
@SuppressWarnings("serial")
public class OrderItem implements Serializable{
private long itemid; //订单项id
private int count; //订单数量
private Double subtotal; //订单小计
// 商品对象
private Product product;
// 订单对象
private Order order;
//省略setter getter方法
Order.hbm.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.shopping.order.entity.Order" table="orders">
<id name="oid">
<generator class="native"/>
</id>
<property name="total"/>
<property name="orderTime"/>
<property name="state"/>
<property name="name"/>
<property name="phone"/>
<property name="addr"/>
<!-- 订单与用户关联配置 -->
<!-- 一个用户有多个订单 ,多个订单属于一个用户-->
<many-to-one name="user" lazy="false" class="com.shopping.user.entity.User" column="uid"/>
<!-- 订单与订单项关联配置 -->
<!-- 一个订单包含多个订单项 -->
<set name="orderItems" lazy="false" cascade="save-update">
<key column="oid"/>
<one-to-many class="com.shopping.order.entity.OrderItem"/>
</set>
</class>
</hibernate-mapping>
OrderItem.hbm.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.shopping.order.entity.OrderItem" table="orderitem">
<id name="itemid">
<generator class="native"/>
</id>
<property name="count"/>
<property name="subtotal"/>
<!-- 订单项是多方, product是一方-->
<many-to-one name="product" lazy="false" class="com.shopping.product.entity.Product" column="pid"></many-to-one>
<!-- 订单项是多方 ,order是一方-->
<many-to-one name="order" class="com.shopping.order.entity.Order" column="oid"/>
</class>
</hibernate-mapping>
这里说明一下,在Oder中用到了User对象,表示多个订单属于一个用户,如果你不需要在User中需要Order,则不用写以下代码:
Set<Order> orders = new HashSet<Order>();
//用到就写,不用就可以不用写,不会影响建表
订单模块跳转到订单页面
在购物车页面点击提交订单的时候:
应该跳转到订单页面,订单页面见上面第一张图。
<a href="${ pageContext.request.contextPath }/order_saveOrder.do" id="submit" class="submit">提交订单</a>
OrderAction:
package com.shopping.order.action;
import org.hibernate.criterion.Order;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import com.shopping.base.BaseAction;
@SuppressWarnings("serial")
@Controller
@Scope("prototype")
public class OrderAction extends BaseAction<Order> {
public String saveOrder(){
System.out.println("order..");
return "saveSuccess";
}
}
跳转成功。
提交订单,1.把订单和订单项保存到数据库。2.把订单信息显示到页面上
补全saveOrder方法:
public String saveOrder() {
// System.out.println("order..");
// 1.保存数据到数据库
// 订单数据的补全
model.setOrderTime(new Date());// 系统当前时间
model.setState(1); // 1:未付款 2:付款未发货 3:发货,没有确认收获 4:确认收获
// 总计是购物车中的总计
Cart cart = (Cart) ServletActionContext.getRequest().getSession()
.getAttribute("cart");
if (cart == null) {
addActionMessage("亲!您还没有购物,请前去购物");
return "msg";
}
model.setTotal(cart.getTotal());
// 设置订单中的订单项
// 订单项在购物车中
for (CartItem cartItem : cart.getCartItems()) {
// 订单项的信息从购物项获得的.
OrderItem orderItem = new OrderItem();
orderItem.setCount(cartItem.getCount());
orderItem.setSubtotal(cartItem.getSubtotal());
orderItem.setProduct(cartItem.getProduct());
orderItem.setOrder(model);
model.getOrderItems().add(orderItem);
}
// 设置订单关联的客户:
User user = (User) ServletActionContext.getRequest().getSession()
.getAttribute("user");
if(user==null){
addActionMessage("亲,您还未登录,请前去登录");
return "loginUI";
}
model.setUser(user);
orderService.save(model);
// 2.将订单数据显示在页面
return "saveSuccess";
}
1.补全订单表:
(1)补全下单时间:model.setOrderTime(new Date());// 系统当前时间
(2)补全订单状态(1:未付款 2:付款未发货 3:发货,没有确认收获 4:确认收获),初始状态都是1:model.setState(1);
(3)订单的总金额就是购物车的总金额:怎么获得购物车信息?因为之前购物车存入到session中 ,所以直接从session中获得购物车:
Cart cart = (Cart) ServletActionContext.getRequest().getSession()
.getAttribute("cart");
if (cart == null) {
addActionMessage("亲!您还没有购物,请前去购物");
return "msg";
}
//设置总计
model.setTotal(cart.getTotal());
(4)补全订单中的订单项(该订单项就是购物项),所以遍历购物车中的订单项项集合
for (CartItem cartItem : cart.getCartItems()) {
// 订单项的信息从购物项获得的.
OrderItem orderItem = new OrderItem();
orderItem.setCount(cartItem.getCount());
orderItem.setSubtotal(cartItem.getSubtotal());
orderItem.setProduct(cartItem.getProduct());
orderItem.setOrder(model);
//把订单项放入订单中
model.getOrderItems().add(orderItem);
}
(5)订单所属用户:要想购物必须登录
User user = (User) ServletActionContext.getRequest().getSession()
.getAttribute("user");
if(user==null){
addActionMessage("亲,您还未登录,请前去登录");
return "loginUI";
}
model.setUser(user);
未登录则先去登录
(6)保存订单到数据库
orderService.save(model);
return "saveSuccess";
这里重点提一下:
我们一点保存订单,同时也要把订单项进行保存,这就涉及到一个级联,设置订单配置文件的时候应该设置好级联,否则在你save订单的时候还得save订单项
<set name="orderItems" lazy="false" cascade="save-update">
以前曾用过级联删除,删除一个部门的时候同时删除这个部门的下级部门。用的是cascade="delete"
测试:
未登录添加购物车提交时会直接转到登录页面!ok
登录状态,提交订单,保存成功
订单表:
订单项表:
订单模块订单数据的显示
把订单对象现在在页面上,通过值栈进行显示。
(Order显示的对象就是模型驱动的使用的对象,就在栈顶,所以也不用把它再次放入值栈中)
<s:iterator value="model.orderItems" var="item">
<tr>
<td width="60"><input type="hidden" name="id" value="22" />
<img src="${ pageContext.request.contextPath }/<s:property value="#item.product.image" />" />
</td>
<td><a target="_blank"><s:property value="#item.product.pname" />
</a>
</td>
<td><s:property value="#item.product.shop_price" /></td>
<td class="quantity" width="60">
<input type="text"
name="count" value="1" maxlength="4" />
<div>
<span class="increase"> </span> <span class="decrease"> </span>
</div>
</td>
<td width="140"><span class="subtotal">
<s:property value="#item.subtotal" />
</span>
</td>
<td><a href="./cart_removeCart.action?pid=1" class="delete">删除</a>
</td>
</tr>
</s:iterator>
用户信息:
<p>
收货地址:<input name="addr" type="text" value="<s:property value="model.user.addr" />" style="width:350px" />
<br /> 收货人 :<input name="username" type="text"
value="<s:property value="model.user.name" />" style="width:150px" /> <br /> 联系方式:<input name="phone"
type="text" value="<s:property value="model.user.phone" />" style="width:150px" />
</p>
订单模块显示:
通过模型驱动的对象将数据传递到页面(值栈)
我的订单
根据用户id查询我的所有订单
<a href="${ pageContext.request.contextPath }/order_findMyOrders.do?
myid=<s:property value="#session.user.uid"/>&page=1">我的订单</a>
属性驱动获得uid
//接收page参数
private int page ;
//省略setter getter方法
findMyOrders方法:
// 通过用户id查询我的所有订单
public String findMyOrders() {
// 此用户id也可用从session中获取
User user = (User) ServletActionContext.getRequest().getSession().getAttribute("user");
long myid = user.getUid();
PageBean<Order> pageBean = orderService.queryAllOrdersByMyId(myid,page);
//保存到值栈
ActionContext.getContext().getValueStack().set("pageBean", pageBean);
return "findMyOrders";
}
service层:queryAllOrdersByMyId
/***
* 通过id
*
* @param myid
* @return
*/
PageBean<Order> queryAllOrdersByMyId(long myid, int page);
实现类:
package com.shopping.order.service.impl;
import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.shopping.base.BaseDaoImpl;
import com.shopping.order.entity.Order;
import com.shopping.order.service.OrderService;
import com.shopping.utils.PageBean;
@Transactional
@Service
public class OrderServiceImpl extends BaseDaoImpl<Order> implements
OrderService {
@Override
public PageBean<Order> queryAllOrdersByMyId(long myid, int page) {
PageBean<Order> pageBean = new PageBean<Order>();
// 每页显示的个数
int limit = 5;
pageBean.setLimit(limit);
// 当前页
pageBean.setPage(page);
// 查询的总个数
int totalCount = 0;
totalCount = findCounts(myid);
pageBean.setTotalCount(totalCount);
// 设置总页数
int totalPage = 0;
if (totalCount % limit == 0) {
totalPage = totalCount / limit;
} else {
totalPage = totalCount / limit + 1;
}
pageBean.setTotalPage(totalPage);
// 设置返回的商品集合
int begin = (page - 1) * limit;
List<Order> list = queryAllOrders(myid, begin, limit);
pageBean.setList(list);
return pageBean;
}
@SuppressWarnings("unchecked")
private List<Order> queryAllOrders(long myid, int begin, int limit) {
List<Order> oList = sessionFactory.getCurrentSession()
//按时间倒序排序
.createQuery("from Order o where o.user.uid=? order by orderTime desc")
.setParameter(0, myid)
.setFirstResult(begin)
.setMaxResults(limit)
.list();
if(oList!=null&&oList.size()>0){
return oList;
}
return null;
}
private int findCounts(long myid) {
int count = sessionFactory.getCurrentSession()
.createQuery("from Order o where o.user.uid=?")
.setParameter(0, myid)
.list().size();
if(count>0){
return count;
}
return 0;
}
}
JSP:
<tbody>
<s:iterator var="order" value="pageBean.list">
<tr>
<th colspan="5">订单编号:<s:property value="#order.oid" /> 订单金额:<font
color="red"><s:property value="#order.total" />
</font>
<font color="red">
<s:if test="#order.state == 1">
<a href="${ pageContext.request.contextPath }/order_findByOid.do?oid=<s:property value="#order.oid" />">付款</a>
</s:if>
<s:if test="#order.state == 2">
已付款
</s:if>
<s:if test="#order.state == 3">
<a href="${ pageContext.request.contextPath }/order_updateState.do?oid=<s:property value="#order.oid" />">确认收货</a>
</s:if>
<s:if test="#order.state == 4">
交易成功
</s:if>
</font>
</th>
</tr>
<tr>
<th>图片</th>
<th>商品</th>
<th>价格</th>
<th>数量</th>
<th>小计</th>
</tr>
<s:iterator var="orderItem" value="#order.orderItems">
<tr>
<td width="60"><img
src="${ pageContext.request.contextPath }/<s:property value="#orderItem.product.image"/>" />
</td>
<td><s:property value="#orderItem.product.pname" /></td>
<td><s:property value="#orderItem.product.shop_price" /></td>
<td class="quantity" width="60"><s:property
value="#orderItem.count" /></td>
<td width="140"><span class="subtotal">¥<s:property
value="#orderItem.subtotal" />
</span></td>
</tr>
</s:iterator>
</s:iterator>
<tr>
<th colspan="5">
<div class="pagination">
<span>第<s:property value="pageBean.page" />/<s:property
value="pageBean.totalPage" />页 </span>
<s:if test="pageBean.page != 1">
<a
href="${ pageContext.request.contextPath }/order_findMyOrders.do?page=1"
class="firstPage"> </a>
<a
href="${ pageContext.request.contextPath }/order_findMyOrders.do?page=<s:property value="pageBean.page-1"/>"
class="previousPage"> </a>
</s:if> <s:iterator var="i" begin="1" end="pageBean.totalPage">
<s:if test="pageBean.page != #i">
<a
href="${ pageContext.request.contextPath }/order_findMyOrders.do?page=<s:property value="#i"/>"><s:property
value="#i" />
</a>
</s:if>
<s:else>
<span class="currentPage"><s:property value="#i" />
</span>
</s:else>
</s:iterator> <s:if test="pageBean.page != pageBean.totalPage">
<a class="nextPage"
href="${ pageContext.request.contextPath }/order_findByUid.action?page=<s:property value="pageBean.page+1"/>"> </a>
<a class="lastPage"
href="${ pageContext.request.contextPath }/order_findByUid.action?page=<s:property value="pageBean.totalPage"/>"> </a>
</s:if>
</div>
</th>
</tr>
</tbody>
订单模块根据订单编号查询订单
什么意思类?就是点击上面的付款,通过订单id查询此订单。
1.点击“付款”跳转到付款界面
2.通过订单id查询此订单
// 根据订单的ID查询订单
public String findByOid() {
//model在模型驱动中,在栈顶
model = orderService.getById(model.getOid());
return "findByOidSuccess";
}
<!-- 订单模块 -->
<action name="order_*" method="{1}" class="orderAction">
<result name="saveSuccess">/WEB-INF/jsp/order.jsp</result>
<result name="loginUI" type="redirectAction">
<param name="actionName">user_loginUI</param>
</result>
<result name="msg" type="redirectAction">
<param name="actionName">index_shopping</param>
</result>
<result name="findMyOrders">/WEB-INF/jsp/myOrderList.jsp</result>
<result name="findByOidSuccess">/WEB-INF/jsp/order.jsp</result>
<result name="deleteMyOrderSuccess" type="redirectAction">order_findMyOrders</result>
</action>`这里写代码片`
OrderAction:
package com.shopping.order.action;
import java.util.Date;
import org.apache.struts2.ServletActionContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import com.opensymphony.xwork2.ActionContext;
import com.shopping.base.BaseAction;
import com.shopping.cart.entity.Cart;
import com.shopping.cart.entity.CartItem;
import com.shopping.order.entity.Order;
import com.shopping.order.entity.OrderItem;
import com.shopping.user.entity.User;
import com.shopping.utils.PageBean;
@SuppressWarnings("serial")
@Controller
@Scope("prototype")
public class OrderAction extends BaseAction<Order> {
// 接收page参数
private int page;
public String saveOrder() {
// System.out.println("order..");
// 1.保存数据到数据库
// 订单数据的补全
model.setOrderTime(new Date());// 系统当前时间
model.setState(1); // 1:未付款 2:付款未发货 3:发货,没有确认收获 4:确认收获
// 总计是购物车中的总计
Cart cart = (Cart) ServletActionContext.getRequest().getSession()
.getAttribute("cart");
if (cart == null) {
addActionMessage("亲!您还没有购物,请前去购物");
return "msg";
}
model.setTotal(cart.getTotal());
// 设置订单中的订单项
// 订单项在购物车中
for (CartItem cartItem : cart.getCartItems()) {
// 订单项的信息从购物项获得的.
OrderItem orderItem = new OrderItem();
orderItem.setCount(cartItem.getCount());
orderItem.setSubtotal(cartItem.getSubtotal());
orderItem.setProduct(cartItem.getProduct());
orderItem.setOrder(model);
// 把订单项放入订单中
model.getOrderItems().add(orderItem);
}
// 设置订单关联的客户:
User user = (User) ServletActionContext.getRequest().getSession()
.getAttribute("user");
if (user == null) {
this.addActionMessage("亲,您还未登录,请前去登录");
return "loginUI";
}
model.setUser(user);
orderService.save(model);
// 2.将订单数据显示在页面
return "saveSuccess";
}
// 通过用户id查询我的所有订单
public String findMyOrders() {
// 此用户id也可用从session中获取
User user = (User) ServletActionContext.getRequest().getSession()
.getAttribute("user");
long myid = user.getUid();
PageBean<Order> pageBean = orderService
.queryAllOrdersByMyId(myid, page);
// 保存到值栈
ActionContext.getContext().getValueStack().set("pageBean", pageBean);
return "findMyOrders";
}
// 根据订单的ID查询订单
public String findByOid() {
//model在模型驱动中,在栈顶
model = orderService.getById(model.getOid());
return "findByOidSuccess";
}
//删除订单
public String deleteMyOrder(){
orderService.delete(model.getOid());
return "deleteMyOrderSuccess";
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
}