数据后台管理(三)订单管理
1.查询所有订单信息
1.1查看显示订单的前端页面需要哪些订单信息
根据下面的orders-list.jsp页面的部分代码可以知道订单的信息表中不仅需要订单的id,orderNum,orderTimeStr,orderStatusStr,还需要的产品的productName,productPrice。因此在查询订单的信息时需要将该订单的产品信息也要查询出来并封装到Orders类中。
1 <tbody> 2 3 4 <c:forEach items="${ordersList}" var="orders"> 5 6 <tr> 7 <td><input name="ids" type="checkbox"></td> 8 <td>${orders.id }</td> 9 <td>${orders.orderNum }</td> 10 <td>${orders.product.productName }</td> 11 <td>${orders.product.productPrice }</td> 12 <td>${orders.orderTimeStr }</td> 13 <td class="text-center">${orders.orderStatusStr }</td> 14 <td class="text-center"> 15 <button type="button" class="btn bg-olive btn-xs">订单</button> 16 <button type="button" class="btn bg-olive btn-xs" onclick="location.href='${pageContext.request.contextPath}/orders/findById.do?id=${orders.id}'">详情</button> 17 <button type="button" class="btn bg-olive btn-xs">编辑</button> 18 </td> 19 </tr> 20 </c:forEach> 21 </tbody>
1.2在domain包下新建Orders类
该类中不仅包含orders表中基本的字段信息,还新增了orderTimeStr,orderStatusStr,product,travellers,member。
由于Date类型的无法在前端页面正常显示因此新增了orderTimeStr类,在get方法中将orderTime转换成字符串形式。由于orders表中orderStatus只是0或1,而前端页面需要具体的订单状态“关闭”或“开启”,因此在get方法中将orderStatus的0或1转换成orderStatusStr的“关闭”或开启。product是根据orders表中的productId从product表中查出的,并将其封装到该类的product中。
1 package club.nipengfei.domain; 2 3 import club.nipengfei.utils.DateUtils; 4 5 import java.util.Date; 6 import java.util.List; 7 8 public class Orders { 9 private String id; 10 private String orderNum; 11 private Date orderTime; 12 private String orderTimeStr; 13 private int orderStatus; 14 private String orderStatusStr; 15 private int peopleCount; 16 private Product product; 17 private List<Traveller> travellers; 18 private Member member; 19 private Integer payType; 20 21 public String getOrderStatusStr() { 22 if (orderStatus == 0){ 23 orderStatusStr = "未支付"; 24 } 25 if (orderStatus == 1){ 26 orderStatusStr = "已支付"; 27 } 28 return orderStatusStr; 29 } 30 31 public void setOrderStatusStr(String orderStatusStr) { 32 this.orderStatusStr = orderStatusStr; 33 } 34 35 private String payTypeStr; 36 private String orderDesc; 37 38 public String getId() { 39 return id; 40 } 41 42 public void setId(String id) { 43 this.id = id; 44 } 45 46 public String getOrderNum() { 47 return orderNum; 48 } 49 50 public void setOrderNum(String orderNum) { 51 this.orderNum = orderNum; 52 } 53 54 public Date getOrderTime() { 55 return orderTime; 56 } 57 58 public void setOrderTime(Date orderTime) { 59 this.orderTime = orderTime; 60 } 61 62 public String getOrderTimeStr() { 63 if (orderTime != null){ 64 orderTimeStr = DateUtils.date2String(orderTime,"yyyy-MM-dd HH:mm"); 65 } 66 return orderTimeStr; 67 } 68 69 public void setOrderTimeStr(String orderTimeStr) { 70 this.orderTimeStr = orderTimeStr; 71 } 72 73 public int getOrderStatus() { 74 return orderStatus; 75 } 76 77 public void setOrderStatus(int orderStatus) { 78 this.orderStatus = orderStatus; 79 } 80 81 public int getPeopleCount() { 82 return peopleCount; 83 } 84 85 public void setPeopleCount(int peopleCount) { 86 this.peopleCount = peopleCount; 87 } 88 89 public Product getProduct() { 90 return product; 91 } 92 93 public void setProduct(Product product) { 94 this.product = product; 95 } 96 97 public List<Traveller> getTravellers() { 98 return travellers; 99 } 100 101 public void setTravellers(List<Traveller> travellers) { 102 this.travellers = travellers; 103 } 104 105 public Member getMember() { 106 return member; 107 } 108 109 public void setMember(Member member) { 110 this.member = member; 111 } 112 113 public Integer getPayType() { 114 return payType; 115 } 116 117 public void setPayType(Integer payType) { 118 this.payType = payType; 119 } 120 121 public String getPayTypeStr() { 122 if (payType != null){ 123 if (payType == 0){ 124 payTypeStr = "支付宝"; 125 }else if (payType == 1){ 126 payTypeStr = "微信"; 127 }else if (payType == 2){ 128 payTypeStr = "其它"; 129 } 130 } 131 return payTypeStr; 132 } 133 134 public void setPayTypeStr(String payTypeStr) { 135 this.payTypeStr = payTypeStr; 136 } 137 138 public String getOrderDesc() { 139 return orderDesc; 140 } 141 142 public void setOrderDesc(String orderDesc) { 143 this.orderDesc = orderDesc; 144 } 145 }
1.3在dao包下新建一个IOrdersDao接口,并写一个findAll方法
由于需要封装product类而orders表只有productId,因此需要另写一个方法IProductDao.findById根据productId查询出订单的product
1 package club.nipengfei.dao; 2 3 import club.nipengfei.domain.Product; 4 import org.apache.ibatis.annotations.Insert; 5 import org.apache.ibatis.annotations.Select; 6 7 import java.util.List; 8 9 public interface IProductDao { 10 /** 11 * 查询所有产品 12 * @return 13 */ 14 @Select("select * from product") 15 List<Product> findAll() throws Exception; 16 17 @Insert("insert into product (productNum,productName,cityName,departureTime,productPrice,productDesc,productStatus) values(#{productNum},#{productName},#{cityName},#{departureTime},#{productPrice},#{productDesc},#{productStatus})") 18 void save(Product product)throws Exception; 19 20 @Select("select * from product where id=#{id}") 21 Product findById(int id) throws Exception; 22 }
1 package club.nipengfei.dao; 2 3 import club.nipengfei.domain.Orders; 4 import club.nipengfei.domain.Product; 5 import org.apache.ibatis.annotations.One; 6 import org.apache.ibatis.annotations.Result; 7 import org.apache.ibatis.annotations.Results; 8 import org.apache.ibatis.annotations.Select; 9 10 import java.util.List; 11 12 public interface IOrdersDao { 13 14 @Select("select * from orders") 15 @Results({ 16 @Result(id = true,property = "id",column = "id"), 17 @Result(property = "orderNum",column = "orderNum"), 18 @Result(property = "orderTime",column = "orderTime"), 19 @Result(property = "orderStatus",column = "orderStatus"), 20 @Result(property = "peopleCount",column = "peopleCount"), 21 @Result(property = "payType",column = "payType"), 22 @Result(property = "orderDesc",column = "orderDesc"), 23 @Result(property = "product",column = "productId",javaType = Product.class,one = @One(select = "club.nipengfei.dao.IProductDao.findById")) 24 }) 25 List<Orders> findAll() throws Exception; 26 }
1.4在service.impl包下新建一个OrdersServiceImpl类,写一个findAll方法
1 package club.nipengfei.service.impl; 2 3 import club.nipengfei.dao.IOrdersDao; 4 import club.nipengfei.domain.Orders; 5 import club.nipengfei.service.IOrdersService; 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.stereotype.Service; 8 import org.springframework.transaction.annotation.Transactional; 9 10 import java.util.List; 11 12 @Service 13 @Transactional 14 public class OrdersServiceImpl implements IOrdersService { 15 16 @Autowired 17 private IOrdersDao ordersDao; 18 19 public List<Orders> findAll() throws Exception { 20 return ordersDao.findAll(); 21 } 22 }
1.5在controller包下新建一个OrdersController类,并写一个findAll方法
1 package club.nipengfei.controller; 2 3 import club.nipengfei.domain.Orders; 4 import club.nipengfei.service.impl.OrdersServiceImpl; 5 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.stereotype.Controller; 7 import org.springframework.web.bind.annotation.RequestMapping; 8 import org.springframework.web.servlet.ModelAndView; 9 10 import java.util.List; 11 12 @Controller 13 @RequestMapping("/orders") 14 public class OrdersController { 15 16 @Autowired 17 private OrdersServiceImpl ordersService; 18 19 @RequestMapping("/findAll.do") 20 public ModelAndView findAll() throws Exception { 21 ModelAndView mv = new ModelAndView(); 22 List<Orders> orders = ordersService.findAll(); 23 mv.addObject("ordersList",orders); 24 mv.setViewName("orders-list"); 25 return mv; 26 } 27 }
2.对订单信息进行分页查询
mybatis分页插件:PageHelper。它是国内非常优秀的一款开源的mybatis分页插件,它支持基本主流与常用的数据库,例如mysql、oracle、mariaDB、DB2、SQLite、Hsqldb等。
2.1引入PageHelper分页插件的坐标
1 <dependency> 2 <groupId>com.github.pagehelper</groupId> 3 <artifactId>pagehelper</artifactId> 4 <version>5.1.2</version> 5 </dependency>
2.2在MyBatis配置文件中配置PageHelper插件
在spring的核心配置文件applicationContext.xml中sqlSessionFactory中加入PageHelper插件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:aop="http://www.springframework.org/schema/aop" 6 xmlns:tx="http://www.springframework.org/schema/tx" 7 xsi:schemaLocation="http://www.springframework.org/schema/beans 8 http://www.springframework.org/schema/beans/spring-beans.xsd 9 http://www.springframework.org/schema/context 10 http://www.springframework.org/schema/context/spring-context.xsd 11 http://www.springframework.org/schema/aop 12 http://www.springframework.org/schema/aop/spring-aop.xsd 13 http://www.springframework.org/schema/tx 14 http://www.springframework.org/schema/tx/spring-tx.xsd"> 15 <!--开启注解扫描,希望处理service和dao,controller不需要Spring框架处理--> 16 <context:component-scan base-package="club.nipengfei"> 17 <!--配置哪些注解不扫描--> 18 <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> 19 </context:component-scan> 20 <!--Spring整合MyBatis框架--> 21 <!--配置连接池--> 22 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 23 <property name="driverClass" value="com.mysql.jdbc.Driver"/> 24 <property name="jdbcUrl" value="jdbc:mysql:///ssm1"/> 25 <property name="user" value="root"/> 26 <property name="password" value="npf123"/> 27 </bean> 28 <!--配置SqlSessionFactory工厂--> 29 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 30 <property name="dataSource" ref="dataSource"/> 31 <!-- 传入PageHelper的插件 --> 32 <property name="plugins"> 33 <array> 34 <!-- 传入插件的对象 --> 35 <bean class="com.github.pagehelper.PageInterceptor"> 36 <property name="properties"> 37 <props> 38 <prop key="helperDialect">mysql</prop> 39 <prop key="reasonable">true</prop> 40 </props> 41 </property> 42 </bean> 43 </array> 44 </property> 45 </bean> 46 <!--配置AccountDao接口所在包--> 47 <bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> 48 <property name="basePackage" value="club.nipengfei.dao"/> 49 </bean> 50 <!--配置Spring框架声明式事务管理--> 51 <!--配置事务管理器--> 52 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 53 <property name="dataSource" ref="dataSource" /> 54 </bean> 55 <!--配置事务通知--> 56 <tx:advice id="txAdvice" transaction-manager="transactionManager"> 57 <tx:attributes> 58 <tx:method name="find*" read-only="true"/> 59 <tx:method name="*" isolation="DEFAULT"/> 60 </tx:attributes> 61 </tx:advice> 62 <!--配置AOP增强--> 63 <aop:config> 64 <aop:advisor advice-ref="txAdvice" pointcut="execution(* club.nipengfei.service.impl.*ServiceImpl.*(..))"/> 65 </aop:config> 66 </beans>
2.3修改上面的OrdersServiceImpl类的findAll方法
1 package club.nipengfei.service.impl; 2 3 import club.nipengfei.dao.IOrdersDao; 4 import club.nipengfei.domain.Orders; 5 import club.nipengfei.service.IOrdersService; 6 import com.github.pagehelper.PageHelper; 7 import org.springframework.beans.factory.annotation.Autowired; 8 import org.springframework.stereotype.Service; 9 import org.springframework.transaction.annotation.Transactional; 10 11 import java.util.List; 12 13 @Service 14 @Transactional 15 public class OrdersServiceImpl implements IOrdersService { 16 17 @Autowired 18 private IOrdersDao ordersDao; 19 20 public List<Orders> findAll(int page, int size) throws Exception { 21 // pageNum是页码值,pageSize是每页显示条数 22 PageHelper.startPage(page,size); 23 return ordersDao.findAll(); 24 } 25 }
2.4修改上面的OrdersController类的findAll方法
该方法的返回值类型为ModelAndView,参数需要使用注解@RequestParam从前端页面接收page和size参数,并根据接收的参数调用service的findAll方法。
在该controller类的findAll方法中还需要将查询出的orders集合作为参数传递给PageInfo对象,将该对象传递给前端。
1 package club.nipengfei.controller; 2 3 import club.nipengfei.domain.Orders; 4 import club.nipengfei.service.impl.OrdersServiceImpl; 5 import com.github.pagehelper.PageInfo; 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.stereotype.Controller; 8 import org.springframework.web.bind.annotation.RequestMapping; 9 import org.springframework.web.bind.annotation.RequestParam; 10 import org.springframework.web.servlet.ModelAndView; 11 12 import java.util.List; 13 14 @Controller 15 @RequestMapping("/orders") 16 public class OrdersController { 17 18 @Autowired 19 private OrdersServiceImpl ordersService; 20 21 @RequestMapping("/findAll.do") 22 public ModelAndView findAll(@RequestParam(name = "page",required = true,defaultValue = "1") int page,@RequestParam(name = "size",required = true,defaultValue = "3") int size) throws Exception { 23 ModelAndView mv = new ModelAndView(); 24 List<Orders> orders = ordersService.findAll(page, size); 25 PageInfo pageInfo = new PageInfo(orders); 26 mv.addObject("pageInfo",pageInfo); 27 mv.setViewName("orders-page-list"); 28 return mv; 29 } 30 }
2.5前端分页展示
1 <div class="box-footer"> 2 <div class="pull-left"> 3 <div class="form-group form-inline"> 4 总共2 页,共14 条数据。 每页 5 <select class="form-control" id="changePageSize" onchange="changePageSize()"> 6 <option>1</option> 7 <option>2</option> 8 <option>3</option> 9 <option>4</option> 10 <option>5</option> 11 </select> 条 12 </div> 13 </div> 14 15 <div class="box-tools pull-right"> 16 <ul class="pagination"> 17 <li> 18 <a href="${pageContext.request.contextPath}/orders/findAll.do?page=1&size=${pageInfo.pageSize}" aria-label="Previous">首页</a> 19 </li> 20 <li><a href="${pageContext.request.contextPath}/orders/findAll.do?page=${pageInfo.pageNum-1}&size=${pageInfo.pageSize}">上一页</a></li> 21 <c:forEach begin="1" end="${pageInfo.pages}" var="pageNum"> 22 <li><a href="${pageContext.request.contextPath}/orders/findAll.do?page=${pageNum}&size=${pageInfo.pageSize}">${pageNum}</a></li> 23 </c:forEach> 24 25 <li><a href="${pageContext.request.contextPath}/orders/findAll.do?page=${pageInfo.pageNum+1}&size=${pageInfo.pageSize}">下一页</a></li> 26 <li> 27 <a href="${pageContext.request.contextPath}/orders/findAll.do?page=${pageInfo.pages}&size=${pageInfo.pageSize}" aria-label="Next">尾页</a> 28 </li> 29 </ul> 30 </div> 31 32 </div>
2.6最终显示效果
3.订单详情展示
点击订单展示页面的详情按钮时,显示该订单的详情。
3.1确定orders类中需要封装的订单信息
根据订单详情的前端页面,可以知道orders类中不仅需要封装订单信息,还需要订单中的产品信息,订单的游客信息,订单的联系人信息。
3.2使用MyBatis注解从表中查出相应信息,封装到orders类中
由于需要封装的对象有 Product,List<Traveller>和Member,而这些无法从orders表中直接查询需要另写sql语句。其中查询Product类在第一部分的查询所有订单信息中已经说过。
查询List<Traveller>涉及到中间表,三张表结构如下所示:
1 package club.nipengfei.dao; 2 3 import club.nipengfei.domain.Traveller; 4 import org.apache.ibatis.annotations.Select; 5 6 import java.util.List; 7 8 public interface ITravellerDao { 9 10 @Select("SELECT * FROM traveller WHERE id IN (SELECT travellerId FROM order_traveller WHERE orderId=#{id})") 11 List<Traveller> findByOrdersId(int id) throws Exception; 12 }
查询Member和查询Product思路一样,需要在IMemberDao接口写一个findById方法
1 package club.nipengfei.dao; 2 3 import club.nipengfei.domain.Member; 4 import org.apache.ibatis.annotations.Select; 5 6 import java.util.List; 7 8 public interface IMemberDao { 9 10 @Select("select * from member where id=#{memberId}") 11 Member findById(int memberId) throws Exception; 12 }
1 package club.nipengfei.dao; 2 3 import club.nipengfei.domain.Member; 4 import club.nipengfei.domain.Orders; 5 import club.nipengfei.domain.Product; 6 import org.apache.ibatis.annotations.*; 7 8 import java.util.List; 9 10 public interface IOrdersDao { 11 12 @Select("select * from orders") 13 @Results({ 14 @Result(id = true,property = "id",column = "id"), 15 @Result(property = "orderNum",column = "orderNum"), 16 @Result(property = "orderTime",column = "orderTime"), 17 @Result(property = "orderStatus",column = "orderStatus"), 18 @Result(property = "peopleCount",column = "peopleCount"), 19 @Result(property = "payType",column = "payType"), 20 @Result(property = "orderDesc",column = "orderDesc"), 21 @Result(property = "product",column = "productId",javaType = Product.class,one = @One(select = "club.nipengfei.dao.IProductDao.findById")) 22 }) 23 List<Orders> findAll() throws Exception; 24 25 @Select("select * from orders where id=#{ordersId}") 26 @Results({ 27 @Result(id = true,property = "id",column = "id"), 28 @Result(property = "orderNum",column = "orderNum"), 29 @Result(property = "orderTimeStr",column = "orderTimeStr"), 30 @Result(property = "product",column = "productId",javaType = Product.class,one = @One(select = "club.nipengfei.dao.IProductDao.findById")), 31 @Result(property = "peopleCount",column = "peopleCount"), 32 @Result(property = "orderDesc",column = "orderDesc"), 33 @Result(property = "travellers",column = "id",javaType = java.util.List.class, many = @Many(select = "club.nipengfei.dao.ITravellerDao.findByOrdersId")), 34 @Result(property = "member",column = "memberId",javaType = Member.class,one = @One(select = "club.nipengfei.dao.IMemberDao.findById")), 35 @Result(property = "payType",column = "payType") 36 }) 37 Orders findById(int ordersId); 38 }
3.3在OrdersServiceImpl类下写一个findById方法传入参数id
1 package club.nipengfei.service.impl; 2 3 import club.nipengfei.dao.IOrdersDao; 4 import club.nipengfei.domain.Orders; 5 import club.nipengfei.service.IOrdersService; 6 import com.github.pagehelper.PageHelper; 7 import org.springframework.beans.factory.annotation.Autowired; 8 import org.springframework.stereotype.Service; 9 import org.springframework.transaction.annotation.Transactional; 10 11 import java.util.List; 12 13 @Service 14 @Transactional 15 public class OrdersServiceImpl implements IOrdersService { 16 17 @Autowired 18 private IOrdersDao ordersDao; 19 20 public List<Orders> findAll(int page, int size) throws Exception { 21 // pageNum是页码值,pageSize是每页显示条数 22 PageHelper.startPage(page,size); 23 return ordersDao.findAll(); 24 } 25 26 /** 27 * 查看订单详情 28 * @param id 29 * @return 30 * @throws Exception 31 */ 32 public Orders findById(int id) throws Exception { 33 return ordersDao.findById(id); 34 } 35 }
3.4在OrdersController类下写一个findById方法
该方法的参数需要用注解@RequestParam从前端接收参数。查看点击订单详情的路径,在该方法的上加上注解@RequestMapping("/findById.do")
1 package club.nipengfei.controller; 2 3 import club.nipengfei.domain.Orders; 4 import club.nipengfei.service.impl.OrdersServiceImpl; 5 import com.github.pagehelper.PageInfo; 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.stereotype.Controller; 8 import org.springframework.web.bind.annotation.RequestMapping; 9 import org.springframework.web.bind.annotation.RequestParam; 10 import org.springframework.web.servlet.ModelAndView; 11 12 import java.util.List; 13 14 @Controller 15 @RequestMapping("/orders") 16 public class OrdersController { 17 18 @Autowired 19 private OrdersServiceImpl ordersService; 20 21 @RequestMapping("/findAll.do") 22 public ModelAndView findAll(@RequestParam(name = "page",required = true,defaultValue = "1") int page,@RequestParam(name = "size",required = true,defaultValue = "3") int size) throws Exception { 23 ModelAndView mv = new ModelAndView(); 24 List<Orders> orders = ordersService.findAll(page, size); 25 PageInfo pageInfo = new PageInfo(orders); 26 mv.addObject("pageInfo",pageInfo); 27 mv.setViewName("orders-page-list"); 28 return mv; 29 } 30 31 @RequestMapping("/findById.do") 32 public ModelAndView findById(@RequestParam(name = "id", required = true) int ordersId) throws Exception { 33 ModelAndView mv = new ModelAndView(); 34 Orders orders = ordersService.findById(ordersId); 35 mv.addObject("orders",orders); 36 mv.setViewName("orders-show"); 37 return mv; 38 } 39 }