数据后台管理(二)产品管理
1.查询所有产品信息
从数据库ssm1中product表中查出所有的产品信息,并在页面中展示。
1.1在domain包下新建一个product类用于封装产品信息
由于数据库中的departureTime是Date类型,productStatus只是0或1,为了将这两个数据也展示在页面上在product类中需要新加两个String类型的成员变量departureTimeStr和productStatusStr,将原先的两个变量封装成String类型。
1 package club.nipengfei.domain; 2 3 import club.nipengfei.utils.DateUtils; 4 5 import java.util.Date; 6 7 public class Product { 8 private String id; // 主键 9 private String productNum; // 编号 唯一 10 private String productName; // 名称 11 private String cityName; // 出发城市 12 private Date departureTime; // 出发时间 13 private String departureTimeStr; 14 private double productPrice; // 产品价格 15 private String productDesc; // 产品描述 16 private Integer productStatus; // 状态 0 关闭 1 开启 17 private String productStatusStr; 18 19 public String getId() { 20 return id; 21 } 22 23 public void setId(String id) { 24 this.id = id; 25 } 26 27 public String getProductNum() { 28 return productNum; 29 } 30 31 public void setProductNum(String productNum) { 32 this.productNum = productNum; 33 } 34 35 public String getProductName() { 36 return productName; 37 } 38 39 public void setProductName(String productName) { 40 this.productName = productName; 41 } 42 43 public String getCityName() { 44 return cityName; 45 } 46 47 public void setCityName(String cityName) { 48 this.cityName = cityName; 49 } 50 51 public Date getDepartureTime() { 52 return departureTime; 53 } 54 55 public void setDepartureTime(Date departureTime) { 56 this.departureTime = departureTime; 57 } 58 59 public String getDepartureTimeStr() { 60 if (departureTime != null){ 61 departureTimeStr = DateUtils.date2String(departureTime,"yyyy-MM-dd HH:mm:ss"); 62 } 63 return departureTimeStr; 64 } 65 66 public void setDepartureTimeStr(String departureTimeStr) { 67 this.departureTimeStr = departureTimeStr; 68 } 69 70 public double getProductPrice() { 71 return productPrice; 72 } 73 74 public void setProductPrice(double productPrice) { 75 this.productPrice = productPrice; 76 } 77 78 public String getProductDesc() { 79 return productDesc; 80 } 81 82 public void setProductDesc(String productDesc) { 83 this.productDesc = productDesc; 84 } 85 86 public Integer getProductStatus() { 87 return productStatus; 88 } 89 90 public void setProductStatus(Integer productStatus) { 91 this.productStatus = productStatus; 92 } 93 94 public String getProductStatusStr() { 95 if (productStatus == 0){ 96 productStatusStr="关闭"; 97 }else if (productStatus == 1){ 98 productStatusStr="开启"; 99 } 100 return productStatusStr; 101 } 102 103 public void setProductStatusStr(String productStatusStr) { 104 this.productStatusStr = productStatusStr; 105 } 106 }
1 package club.nipengfei.utils; 2 3 import java.text.SimpleDateFormat; 4 import java.util.Date; 5 6 public class DateUtils { 7 8 /** 9 * 将date转换成patt的字符串形式 10 * @param date 11 * @param patt 12 * @return 13 */ 14 public static String date2String(Date date,String patt){ 15 SimpleDateFormat sdf = new SimpleDateFormat(patt); 16 String format = sdf.format(date); 17 return format; 18 } 19 }
1.2在dao包下新建一个IProductDao接口,写一个findAll方法并通过@Select注解写入查询数据的sql语句
1 package club.nipengfei.dao; 2 3 import club.nipengfei.domain.Product; 4 import org.apache.ibatis.annotations.Select; 5 6 import java.util.List; 7 8 public interface IProductDao { 9 /** 10 * 查询所有产品 11 * @return 12 */ 13 @Select("select * from product") 14 List<Product> findAll() throws Exception; 15 }
1.3在service包下新建一个IProductService接口,并在impl包下新建一个ProductServiceImpl实现IProductService接口
1 package club.nipengfei.service.impl; 2 3 import club.nipengfei.dao.IProductDao; 4 import club.nipengfei.domain.Product; 5 import club.nipengfei.service.IProductService; 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 ProductServiceImpl implements IProductService{ 15 16 @Autowired 17 private IProductDao productDao; 18 19 public List<Product> findAll() throws Exception { 20 return productDao.findAll(); 21 } 22 }
1.4在controller包下新建一个ProductController类,写一个findAll方法
由于该方法是从数据库中查询产品信息,返回给前端product-list.jsp页面,因此返回值类型是ModelAndView。将查询的信息product列表添加到ModelAndView类生成的对象中,其中对象的参数attributeName需要与前端页面一致。
1 package club.nipengfei.controller; 2 3 import club.nipengfei.domain.Product; 4 import club.nipengfei.service.impl.ProductServiceImpl; 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("/product") 14 public class ProductController { 15 16 @Autowired 17 private ProductServiceImpl productService; 18 19 @RequestMapping("/findAll.do") 20 public ModelAndView findAll() throws Exception { 21 ModelAndView mv = new ModelAndView(); 22 List<Product> ps = productService.findAll(); 23 mv.addObject("productList",ps); 24 mv.setViewName("product-list"); 25 return mv; 26 } 27 }
1.5前端页面显示(部分)
1 <c:forEach items="${productList}" var="product"> 2 3 <tr> 4 <td><input name="ids" type="checkbox"></td> 5 <td>${product.id }</td> 6 <td>${product.productNum }</td> 7 <td>${product.productName }</td> 8 <td>${product.cityName }</td> 9 <td>${product.departureTimeStr }</td> 10 <td class="text-center">${product.productPrice }</td> 11 <td>${product.productDesc }</td> 12 <td class="text-center">${product.productStatusStr }</td> 13 <td class="text-center"> 14 <button type="button" class="btn bg-olive btn-xs">订单</button> 15 <button type="button" class="btn bg-olive btn-xs">详情</button> 16 <button type="button" class="btn bg-olive btn-xs">编辑</button> 17 </td> 18 </tr> 19 </c:forEach>
1.6出现的问题:报500错误
当运行该项目时发现报500错误,查询发现该错误是服务器内部错误,于是我在pages包下新建一个hello.jsp页面,将index.jsp页面中的跳转改为pages/hello.jsp发现能够正常访问,后来发现错误原因是在main.jsp页面中引入了aside.jsp,而该页面中有使用spring-security的标签,而我的pom.xml中的坐标是ssm框架整合用到的一些基本坐标没有有关spring-security的坐标,于是我在pom.xml中引入了这部分的坐标发现能够正常访问。
2.保存产品信息
将前端页面product-add.jsp页面填写的产品信息保存到数据库中,并将保存好后的产品信息展示
2.1在IProduceDao接口中写一个save方法,并通过@Insert注解写入插入数据的sql语句
由于是一个保存数据的方法,因此需要给save方法传入一个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 }
2.2在ProductServiceImpl类中写一个save方法
1 package club.nipengfei.service.impl; 2 3 import club.nipengfei.dao.IProductDao; 4 import club.nipengfei.domain.Product; 5 import club.nipengfei.service.IProductService; 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 ProductServiceImpl implements IProductService{ 15 16 @Autowired 17 private IProductDao productDao; 18 19 public List<Product> findAll() throws Exception { 20 return productDao.findAll(); 21 } 22 23 public void save(Product product) throws Exception { 24 productDao.save(product); 25 } 26 }
2.3在ProductController类中写一个save方法
由于当我们点击保存按钮提交表单信息后,需要重新从数据库中查询产品信息展示在product-list.jsp页面中,因此该方法的返回值类型是String,值为"redirect:findAll.do"
1 package club.nipengfei.controller; 2 3 import club.nipengfei.domain.Product; 4 import club.nipengfei.service.impl.ProductServiceImpl; 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("/product") 14 public class ProductController { 15 16 @Autowired 17 private ProductServiceImpl productService; 18 19 @RequestMapping("/findAll.do") 20 public ModelAndView findAll() throws Exception { 21 ModelAndView mv = new ModelAndView(); 22 List<Product> ps = productService.findAll(); 23 mv.addObject("productList",ps); 24 mv.setViewName("product-list"); 25 return mv; 26 } 27 28 @RequestMapping("/save.do") 29 public String save(Product product) throws Exception { 30 productService.save(product); 31 return "redirect:findAll.do"; 32 } 33 }
2.4出现的问题:报400错误
当运行该项目时没有报错,但是当填好表单信息提交时出现http400的错误,该错误的出现表示请求无效,传递给后台的数据有问题。
查看IDEA控制台的错误信息:
说明在封装product时出现错误,表单提交的是String类型的日期数据,但是product中departureTime是Date类型,需要将String类型的转换成Date类型。
可以直接在product类中的departureTime属性加上注解@DateTimeFormat(pattern="yyyy-MM-dd HH:mm"),给注解使接收到的pattern类型的字符串转换成Date类型。参考:https://blog.csdn.net/java_zhangshuai/article/details/95951400