问题引入:
根据SpringMvc学习3之ssm整合1的内容进行展示。
我们发现数据库中的details,也就是这里商品的描述没有显示出来。而且生产日期返回的日期类型也不符合我们平时阅读。所以这里主要结局这两个问题。
一、解决商品的描述没有返回值的问题。
通过检查数据库,我们发现数据库中的details字段为text类型,然后在逆向生成的实体类是String类型,所以我们在数据库中将details字段改为varchar类型。
-
我们通过controller层知道,调用的是service层的itemService的list方法。
-
然后通过这个方法找到IntemService的list方法
-
接下来去查看该类的实现类的list方法,找到调用了itemMapper的selectByExample方法
-
最后就通过该方法找到对应的接口类,在去找到接口类对应的ItemsMapper.xml配置方法。
-
上面我们通过这里的sql语句找到了返回结果,然后继续找到返回结果中的实体类与数据库的映射中没有details
-
我们在这里添加details的实力类数据的映射
-
初次之外,在selectByExamplesql语句中还有一个include,以里面的refid的内容继续查找。
-
我们发现这里,少了一个参数,没有details,所以在后面添加一个即可
二、开发editItem.jsp用来让itemList.jsp跳转到该页面。
1.editItem.jsp内容为:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form id="item" action="${pageContext.request.contextPath}/updateitem" method="post">
<table border="1px" width="100%">
<tr>
<td>商品名称</td>
<td><input type="text" name="name" value="${item.name}"></td>
</tr>
<tr>
<td>商品价格</td>
<td><input type="text" name="price" value="${item.price}"></td>
</tr>
<tr>
<td>生产日期</td>
<td><input type="text" name="createtime" value="<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH-mm-ss"/> "></td>
</tr>
<tr>
<td>商品名称</td>
<td><input type="text" name="detail" value="${item.detail}"></td>
</tr>
<tr >
<td colspan="2" align="center"><input type="submit" value="提交"></td>
</tr>
</table>
</form>
</body>
</html>
- 用户通过点击itemList.jsp的点我,然后进入controller层注解为@RequestingMapping(“itemEdit”)对应的方法内,进行数据的获取,最后将数据渲染到上面的editItem.jsp中。
- 上面的内容中,创建了一个表单,并且表单的每一个控件都对应的value。这里的值是通过访问数据库返回到这里的值,并且还可以在当前页面对显示的值进行修改,如果想要保存到数据库可以点击提价按钮,最后使用post提交方式提交到后台控制层为 @RequestMapping("/updateitem")注解的函数。
2.上面提及的控制层@RequestMapping("/itemEdit")注解的方法代码如下
@RequestMapping("/itemEdit")
public String itemEdit(HttpServletRequest request, Model model){
id = request.getParameter("id");
Items items=itemService.findItemByID(Integer.valueOf(id));
model.addAttribute("item",items); //把items给editItem.jsp的item
return "editItem.jsp";
}
- 此方法返回值类型是string,方法里面传递了两个参数,类型分别为HttpServletRequest和Model。通过request.getParameter(“id”)获取前台超链接返回过来id的值。在itemService定义抽象方法findItemByID()。然后在itemServiceImpl实现类中写关于通过id查询一条数据的方法。
public Items findItemByID(Integer id) {
Items items = itemsMapper.selectByPrimaryKey(id);
return items;
}
上面就是itemServiceImpl中的fingItemByID(),在这里传递了一个整型参数,通过itemsMapper.selectByPrimaryKey(id)返回一条数据。最终将数据传递到controller层的调用处。
- 在控制层通过service将查询数据库的结果放回到这里,然后利用model.addAttribute(“item”,items)将返回的参数传递到model中,并且重命名为item。这样在return的editItem.jsp页面中使用item就和这里的model.addAttribute(“item”,items)对应上。从而就能使用items的值。
三、继续开发editItem.jsp中的点击按钮使用post方法提交到后台进行更新的操作。
1. 从上图我们可以知道,点击按钮就会提交到后台显示@RequestMapping("/updateitem")注解的方法,方法内容如下:
@RequestMapping("/updateitem")
public String update(Items items){
items.setId(Integer.valueOf(id));
itemService.update(items);
return "success";
}
从上面看,我们可以知道,需要先把前台的item的值传递到这里的items中,这里是自动传递的不需要我们自己赋值。
2.我们先在service实现类的地方创建一个udpate方法
public void update(Items items) {
itemsMapper.updateByPrimaryKey(items);
}
这里直接调用的是itemsMapper.updateByPrimaryKey()方法,参数传递的是items类型的值。
注:上面的步骤虽然大致没有错误,但是我们忽略了一点就是在修改页面中,我们点击按钮然后返回后台进行保存,但是表单的内容里面没有id,所以在更新的时候不能通过比对id进行更新,最终由于没有关键字值的更新,肯定不能更行成功。在这里我们要做的是,表单提交后,只能将表单的内容传递给后台的方法入口参数中。然而id在前面的参数中已经获取到,所以这里可以将id定义成了全局变量。然后我们将没有id的item对象使用item.setId()就可以给items的id赋值。最后在使用 itemService.update(items)更新即可。最终使用 return "success"返回到success.jsp页面。
四、解决日期格式问题
1.在editItem.jsp页面的日期那一部分使用以下内容
<tr>
<td>生产日期</td>
<td><input type="text" name="createtime" value="<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH-mm-ss"/> "></td>
</tr>
这里使用<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH-mm-ss">
使用格式化日期,然后后面根据yyyy-MM-dd HH-mm-ss输出时间。
注:以上配置只能让时间再编辑页面进行按照格是显示,但是如果修改提交的话,这里不能够对它就行修改,我们再输入框中输入的是text也就是string类型的值,数据库的内容是date类型的,所以无法提交,具体解决方案如下:
2. 再SpringMvc.xml配置文件中,进行日期转换问题的解决。
<mvc:annotation-driven conversion-service="conversionService"/> <!--使用了RequestMapping注解-->
<!--搞定日期的转换问题-->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.pp.controller.converter.CustomGlobalStrToDateConvter"/>
</set>
</property>
</bean>
最上面 <mvc:annotation-driven是controller层中使用 @RequestMapping()注解的一个定义,只有再这里定义才能够使用注解 @RequestMapping(),conversion-service填写conversionService。<bean>
的id填写conversion-service的值,class填写spring下面的处理日期格式的一个类的路径。下面进行依赖注入, <property>
的name为converters,然后使用set方法注入,class的路径填写具体的类路径。
2.根据上面的配置我们知道需要再com.pp.controller下面创建了一个converter包,然后创建一个 CustomGlobalStrToDateConvter类
package com.pp.controller.converter;
import org.springframework.core.convert.converter.Converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
//将string转成Date
public class CustomGlobalStrToDateConvter implements Converter<String,Date> {
public Date convert(String s) {
Date date = null;
try {
date = new SimpleDateFormat("yyy-MM-dd hh:mm:ss").parse(s);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
}
这里的类CustomGlobalStrToDateConvter 需要继承和实现Converter的方法convert(String s)方法,再方法里面,new了一个SimpleDateFormat(“yyy-MM-dd hh:mm:ss”).parse(s),返回值为date,最后将其返回。
总结
本次内容讲解了以下内容:
- 数据库中的表的属性是text,然而和数据库映射的时候找不到text和java对应的是什么类型,所以逆向工程中没有将其属性查找出来。
- 页面的跳转以及传递值,页面跳转即从一个页面跳转到另一个页面,我们是通过这个页面通过 @RequestMapping()传递到后台,再该注解下的方法下,进行数据处理,当然service负责将mapper和pojo以及数据库之间进行连接和使用。所以控制层只负责调用service层即可,最后再发送到我们的前台页面进行页面的渲染。
- 日期格式问题主要是因为数据库中使用的类型是Date而表单中日期的输入框是text也就是String类型,所以这里需要String和Date类型的转换。在这里Date一般默认输出的是标准格式,所以我们需要将其转换成我们平时习惯使用的格式。
源码地址:https://gitee.com/yangforever/project-learning/tree/master/demo/SpringMvc/springmvcday2