文章目录
2.3 学生信息展示升级
2.3.1 产品经理阶段
需求变更,要求首页数据展示可以展示学生的考试成绩信息
2.3.2 项目经理阶段
矛盾的产生 : 工作中面对这样的需求更改一般都是很让人气愤的,因为写好的功能很难再进行修改了(主要是因为懒),所以这个时候很容易与产品经理发生矛盾,不过没关系
作为项目经理一封邮件发给程序员就搞定了,美滋滋;
问题解决 : 每个学生有 数学成绩 语文成绩 英语成绩 综合成绩 现在要把这些成绩在首页展示,这里的技术问题就是怎么能够保存每个学生的这么多成绩?
如果创建一个成绩表的实体类,然后按照学生ID查询这些成绩,然后再用List封装到学生对象中,这样就可以展示学生的成绩信息了;
2.3.3 程序员阶段
需求解决 : 一个原则 以最小的改动完成需求实现
分析 : 根据项目经理的分析,可以按照学生ID查询考试成绩,然后把考试成绩封装集合在与每个考生信息封装成一个考生对象在前台展示
2.3.4 实现过程
2.3.4.1 创建视图 stu_v2
实现 :
首先创建一个视图 把 考试成绩与考试科目信息结合起来
-- 创建 考试成绩与考试科目视图
create view stu_v2 as
select su.su_id suid,su.su_name suname,r.s_id sid,r.r_score score
from result r inner join `subject` su on r.su_id = su.su_id;
-- 根据学生ID查询想要的数据
select suname,score from stu_v2 where sid = 1;
根据查询结果封装数据
2.3.4.2 编写实体类接收查询结果 StudentScore.java
编写实体类接收查询结果
package com.hnxy.entity;
/**
* 考试成绩表
* @author sysmaster
*/
public class StudentScore {
// 私有方法
private String suname; // 考试科目
private Integer score; // 分数
// 对外方法
public Integer getScore() {
return score;
}
public String getSuname() {
return suname;
}
public void setSuname(String suname) {
this.suname = suname;
}
public void setScore(Integer score) {
this.score = score;
}
}
思考,数据有了 实体类也有了,怎么封装数据呢?
此处大家需要注意我们查询的考试成绩是按每个学生的ID查询的,而我们的程序中哪块能给我提供这个ID呢? DAO里!
就是这段代码
这获取的是所有学生的ID,此时我们如果把这个集合遍历一下然后每个学生ID然后根据学生ID获取他们的成绩再重新封装起来,不就可以了么,那么
怎么封装呢?
其实很简单,如果一个考生有一个成绩我们可以在学生类中创建一个考试结果类的对象表示一个学生有一个考试成绩
如果一个学生有多个考试成绩我们就可以在学生类中创建一个考试成绩类的list集合来保存这些考试成绩
2.3.4.3 修改学生类 Student.java
package com.hnxy.entity;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* 学生表实体类
* @author sysmaster
*/
public class Student {
// 私有属性
private Integer aid; // 地区ID
private String aname; // 地区名称
private Integer scid; // 学校ID
private String scname; // 学校名称
private Integer sid; // 学生ID
private String sname; // 学生名称
private Integer sex; // 性别 0 女 1 男
private Date birthday; // 生日
private String examnum; // 准考证号
// 创建成绩表的List集合
private Map<String,Integer> scores = new HashMap<String,Integer>();
// 对外方法
public Integer getAid() {
return aid;
}
public Map<String, Integer> getScores() {
return scores;
}
public void setScores(Map<String, Integer> scores) {
this.scores = scores;
}
public void setAid(Integer aid) {
this.aid = aid;
}
public String getAname() {
return aname;
}
public void setAname(String aname) {
this.aname = aname;
}
public Integer getScid() {
return scid;
}
public void setScid(Integer scid) {
this.scid = scid;
}
public String getScname() {
return scname;
}
public void setScname(String scname) {
this.scname = scname;
}
public Integer getSid() {
return sid;
}
public void setSid(Integer sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getExamnum() {
return examnum;
}
public void setExamnum(String examnum) {
this.examnum = examnum;
}
}
2.3.4.4 修改DAOImpl类
@Override
public List<Student> findStudentsByPage(Integer start, Integer size) throws Exception {
// 创建方法的返回值
List<Student> list = new ArrayList<Student>();
// 编写SQL语句
String sql = "select * from stu_v1 limit ?,?";
// 占位符赋值
Object[] params = {start,size};
// 执行
list = qr.query(sql, new BeanListHandler<Student>(Student.class),params);
// 遍历重新封装数据
for (Student s : list) {
// 创建SQL语句
sql = "select suname,score from stu_v2 where sid = " + s.getSid();
// 执行
List<StudentScore> scores = qr.query(sql,new BeanListHandler<StudentScore>(StudentScore.class));
// 解析
for (StudentScore ss : scores) {
// 保存学生成绩
s.getScores().put(ss.getSuname(), ss.getScore());
}
}
// 返回
return list;
}
此处就相当是把学生信息拿出来又重新封装了一遍
最后修改页面展示
2.3.4.5 修改页面展示
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>学生信息管理与分析系统</title>
<!-- 引入CSS -->
<link rel="stylesheet" href="css/bootstrap.min.css">
<!-- 引入JS -->
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.9.1.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/bootstrap.min.js"></script>
<script type="text/javascript">
// 分页查询
function goPage(pageIndex){
window.location.href = "${pageContext.request.contextPath}/findStudentsByPage?pi="+pageIndex;
}
// 准备更新
function goUpdate(id){
window.location.href = "${pageContext.request.contextPath}/findStudentByID?id="+id;
}
// 删除
function goDelete(id){
var con = window.confirm("确定删除此条数据么?");
if(con){
window.location.href = "${pageContext.request.contextPath}/deleteStudentByID?id="+id;
}
}
// 返回首页
function goIndex(){
window.location.href = "${pageContext.request.contextPath}/index.jsp";
}
// 返回首页
function goAdd(){
window.location.href = "${pageContext.request.contextPath}/student_add.jsp";
}
</script>
</head>
<body>
<div>
<div class="page-header">
<h1>学生信息展示</h1>
<button type="button" class="btn btn-primary" onclick="goIndex();">
<span class="glyphicon glyphicon-arrow-left"></span> 返回上一页
</button>
<button type="button" class="btn btn-primary" onclick="goAdd();">
<span class="glyphicon glyphicon-plus"></span> 添加学生信息
</button>
</div>
<table class="table table-hover">
<tr class="active">
<th colspan="12">
一共查询出数据${totalCount}条,每页展示${pageSize}条,一共分${totalPage}页,当前为第${pageIndex}页
</th>
</tr>
<tr class="info">
<th>考生编号</th>
<th>所属考区</th>
<th>所属学校</th>
<th>考生姓名</th>
<th>考生性别</th>
<th>出生日期</th>
<th>准考证号</th>
<th>语文成绩</th>
<th>数学成绩</th>
<th>英语成绩</th>
<th>综合成绩</th>
<th>操作</th>
</tr>
<c:forEach var="s" items="${students}">
<tr>
<td>${s.sid}</td>
<td>${s.aname}</td>
<td>${s.scname}</td>
<td>${s.sname}</td>
<td>
<c:if test="${s.sex == 0}">女</c:if>
<c:if test="${s.sex == 1}">男</c:if>
</td>
<td>
<fmt:formatDate value="${s.birthday}" pattern="yyyy年MM月dd日"/>
</td>
<td>
${s.examnum}
</td>
<td>
${s.scores['语文']}
</td>
<td>
${s.scores['数学']}
</td>
<td>
${s.scores['英语']}
</td>
<td>
${s.scores['综合']}
</td>
<th>
<button type="button" class="btn btn-warning" onclick="goUpdate(${s.sid});">
<span class="glyphicon glyphicon-edit"></span> 修改
</button>
<button type="button" class="btn btn-danger" onclick="goDelete(${s.sid});">
<span class="glyphicon glyphicon-minus"></span> 删除
</button>
</th>
</tr>
</c:forEach>
<tr>
<th colspan="12" style="text-align: center;">
<button type="button" class="btn btn-primary" onclick="goPage(1);" style="text-shadow: black 5px 3px 3px;">
<span class="glyphicon glyphicon-fast-backward"></span> 首页
</button>
<c:choose>
<c:when test="${pageIndex > 1}">
<button type="button" class="btn btn-primary" onclick="goPage(${pageIndex-1});" style="text-shadow: black 5px 3px 3px;">
<span class="glyphicon glyphicon-backward"></span> 上一页
</button>
</c:when>
<c:otherwise>
<button type="button" class="btn btn-primary" disabled="disabled" style="text-shadow: black 5px 3px 3px;">
<span class="glyphicon glyphicon-backward"></span> 上一页
</button>
</c:otherwise>
</c:choose>
<c:choose>
<c:when test="${totalPage > pageIndex}">
<button type="button" class="btn btn-primary" onclick="goPage(${pageIndex+1});" style="text-shadow: black 5px 3px 3px;">
<span class="glyphicon glyphicon-forward"></span> 下一页
</button>
</c:when>
<c:otherwise>
<button type="button" class="btn btn-primary" disabled="disabled" style="text-shadow: black 5px 3px 3px;">
<span class="glyphicon glyphicon-forward"></span> 下一页
</button>
</c:otherwise>
</c:choose>
<button type="button" class="btn btn-primary" onclick="goPage(${totalPage});" style="text-shadow: black 5px 3px 3px;">
<span class="glyphicon glyphicon-fast-forward"></span> 末页
</button>
</th>
</tr>
</table>
</div>
</body>
</html>
效果展示
2.4 学生信息添加
2.4.1 产品经理阶段
完成考生信息的添加功能,要求添加考生信息的同时需要添加考试成绩信息;
2.4.2 项目经理阶段
项目需求分析:
两处难点 :
1) 所属地区 需要根据不同的地区展示不同的学校
2) 学生表数据和成绩表数据不是同一个表的数据,添加非常的有难度!
2.4.3 程序员阶段
因为这个添加不简单,所以这把我们现在页面做出来
2.4.4 过程实现
2.4.4.1 页面代码
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>学生信息管理与分析系统</title>
<!-- 引入CSS -->
<link rel="stylesheet" href="css/bootstrap.min.css">
<!-- 引入JS -->
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.9.1.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/bootstrap.min.js"></script>
</head>
<body>
<div>
<div class="page-header">
<h1>添加考生信息</h1>
</div>
<form action="${pageContext.request.contextPath}/insertStudent" method="post">
<table class="table table-hover">
<tr>
<th style="text-align: right;">考生姓名 :</th>
<td>
<input type="text" name="sname" class="form-control" required="required" placeholder="请输入考生姓名...." />
</td>
<th style="text-align: right;">考生性别 :</th>
<td>
<select name="sex" required="required" class="form-control">
<option value="">---请选择---</option>
<option value="1">男</option>
<option value="0">女</option>
</select>
</td>
<th style="text-align: right;">出生日期 :</th>
<td>
<input type="date" name="birthday" class="form-control" required="required" />
</td>
</tr>
<tr>
<th style="text-align: right;">准考证号 :</th>
<td>
<input type="text" name="examnum" class="form-control" required="required" placeholder="请输入准考证号...." />
</td>
<th style="text-align: right;">考生考区 :</th>
<td>
<div class="form-inline">
<select class="form-control" id="areaSelect" required="required" onchange="loadSchools();">
</select>
<select class="form-control" id="scSelect" name="scid" required="required">
</select>
</div>
</td>
<th style="text-align: right;">语文成绩 :</th>
<td>
<input type="text" name="scores['语文']" class="form-control" required="required" placeholder="请输入语文成绩...." />
</td>
</tr>
<tr>
<th style="text-align: right;">数学成绩 :</th>
<td>
<input type="text" name="scores['数学']" class="form-control" required="required" placeholder="请输入数学成绩...." />
</td>
<th style="text-align: right;">英语成绩 :</th>
<td>
<input type="text" name="scores['英语']" class="form-control" required="required" placeholder="请输入英语成绩...." />
</td>
<th style="text-align: right;">综合成绩 :</th>
<td>
<input type="text" name="scores['综合']" class="form-control" required="required" placeholder="请输入综合成绩...." />
</td>
</tr>
<tr>
<th colspan="6" style="text-align: center;">
<button type="submit" class="btn btn-success">
<span class="glyphicon glyphicon-ok"></span> 确定
</button>
<button type="reset" class="btn btn-danger" onclick="javascript:history.go(-1);">
<span class="glyphicon glyphicon-remove"></span> 取消
</button>
</th>
</tr>
</table>
</form>
</div>
</body>
</html>
完成效果
根据页面我们优先解决考生考区的选择问题,此处我们知道这里是想选择一个考区 然后根据不同的考区加载不同的学校,那么首选我么就要知道有多少个考区?那么怎么加载这些考区呢?
按步骤来 : 加载考区信息
2.4.4.2 加载考区信息
2.4.4.2.1SQL
SQL
-- 加载考区信息
select a_id aid,a_name aname from area;
创建实体类,将查询结果映射到程序中
2.4.4.2.2 实体类
package com.hnxy.entity;
/**
* 地区表实体类
* @author sysmaster
*
*/
public class Area {
private Integer aid; // 主键ID
private String aname; // 区域名称
public Integer getAid() {
return aid;
}
public void setAid(Integer aid) {
this.aid = aid;
}
public String getAname() {
return aname;
}
public void setAname(String aname) {
this.aname = aname;
}
}
2.4.4.2.3 DAO层接口
/**
* 获取所有的地区信息
* @return
* @throws Exception
*/
public List<Area> findAllAreas()throws Exception;
2.4.4.2.4 DAO层实现类
@Override
public List<Area> findAllAreas() throws Exception {
// 创建方法的返回值
List<Area> list = null;
// 编写SQL语句
String sql = "select a_id aid,a_name aname from area";
// 执行
list = qr.query(sql, new BeanListHandler<Area>(Area.class));
// 返回
return list;
}
2.4.4.2.5 Service接口
/**
* 获取所有的地区信息
* @return
* @throws Exception
*/
public List<Area> findAllAreas() throws Exception;
2.4.4.2.6 ervice实现类
@Override
public List<Area> findAllAreas() throws Exception {
return studentDAO.findAllAreas();
}
这样我们的区域信息就封装好了,那么这个区域怎么给到页面呢?
此处我们可以思考一下 考区应该是页面加载的时候从数据库加载出来放入这个select框的,后面的学校信息应该是前面的考区信息发生改变然后随着再加载学校信息;
并且我们不得不重视一个问题,这个信息的加载是页面部分内容加载,而不是全部内容,所以我们传统的请求与相应模式在这就用不了了,因为传统的请求与相应模式是要把当前
页面全部提交过去,这样就会给我们造成很大的困扰,因为页面其他信息我们都还没有填写就提交,这样很显然影响了用户体验,所以此处我们需要一个页面部分内容刷新技术;
那么有没有什么技术能够满足我们这个需求呢?当然有,那就是ajax技术!
2.4.4.2.7 动态网页刷新技术 ajax
Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。
Ajax = 异步 JavaScript 和 XML(标准通用标记语言的子集)。
Ajax 是一种用于创建快速动态网页的技术。
Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。
ajax 其实非常的实用,它把我们的request请求从以前 请求 -->相应 的过程变成了页面的一个普通JS,这样解决了页面请求服务器的时候由于提交而导致的页面跳转,从而大大的提升了用户的体验度,被广大网站所采用
解决方案 :
在页面编写相应的ajax方法向服务器发起请求
<script type="text/javascript">
// 页面加载的时候需要执行的方法
$(document).ready(function(){
// 加载区域信息
loadAreaInfo();
});
// 加载区域信息方法
function loadAreaInfo(){
// 获取区域的select
var area = $("#areaSelect");
// 创建内容
var selectstr = "<option value=''>---请选择---</option>";
// 像服务器发起请求
// $.post(请求地址,请求参数(可选),回调函数);
// 回调函数 就是服务端处理完数据调用这个返回把返回值给到$.post()方法
$.post("${pageContext.request.contextPath}/findAllAreas",function(data){
// 处理返回值
});
}
</script>
根据页面请求,处理findAllAreas请求
2.4.4.2.8 后端控制器StudentViewAction
@RequestMapping("/findAllAreas")
public @ResponseBody List<Area> findAllAreas()throws Exception{
return studentService.findAllAreas();
}
此处注意这个方法的写法,加了一个
@ResponseBody 这个注解的作用是把返回值当做普通字符串返回给页面,
为啥要把list编程普通字符串给页面呢?
此处大家不要忘记,这次的request请求是我们通过JS发起的,JS中是没有list集合的处理方法的而有的是JSON数组,并且我们的HTTP请求只能传输字符流
所以此处我们设置返回的类型是字符串类型,但是这只是一个普通的字符串JS获取到之后处理起来依然很麻烦,所以我们把这个转换为JSON字符串页面就好处理了,
那么此处怎么把List集合转JSON字符串返回呢?
2.4.4.2.9 prom.xml
项目中添加三个jar包
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
添加这三个JAR之后Spring的@responsebody注解就会把我们要返回的对象转成json对象,
如果是返回单个对象就是JSON对象,如果返回的是list集合,
那么页面接收到的就是JSON数组页面处理返回值
// 加载区域信息方法
function loadAreaInfo(){
// 获取区域的select
var area = $("#areaSelect");
// 创建内容
var selectstr = "<option value=''>---请选择---</option>";
// 像服务器发起请求
// $.post(请求地址,请求参数(可选),回调函数);
// 回调函数 就是服务端处理完数据调用这个返回把返回值给到$.post()方法
$.post("${pageContext.request.contextPath}/findAllAreas",function(data){
// 处理返回值
for(var i = 0;i<data.length;i++){
selectstr+="<option value='"+data[i].aid+"'>"+data[i].aname+"</option>"
}
// 将拼接好的数据放入select
area.html(selectstr);
});
}
小结 :
后端控制器返回的JSON数组被$.post函数的回调函数接收到,所以此处我们可以正常解析这个JSON数组完成页面数据的调用
效果 :
运用同样的道理
2.4.4.3 根据地区ID加载学校信息
2.4.4.3.1 首先整理SQL语句
-- 通过区域id加载该区域的所有学校信息
select sc_id scid,sc_name scname from school where a_id = 1;
根据SQL结果整理实体类
package com.hnxy.entity;
/**
* 学校信息表
* @author sysmaster
*
*/
public class School {
// 私有属性
private Integer scid; // 学校ID
private String scname; // 学校名称
// 共有方法
public Integer getScid() {
return scid;
}
public void setScid(Integer scid) {
this.scid = scid;
}
public String getScname() {
return scname;
}
public void setScname(String scname) {
this.scname = scname;
}
}
2.4.4.3.2 DAO层接口
/**
* 根据区域ID获取学校信息
* @param id
* @return
* @throws Exception
*/
public List<School> findSchoolsByAreaID(Integer id)throws Exception;
2.4.4.3.3 DAO层实现类
@Override
public List<School> findSchoolsByAreaID(Integer id) throws Exception {
// 创建方法的返回值
List<School> list = null;
// 编写SQL语句
String sql = "select sc_id scid,sc_name scname from school where a_id = ?";
// 占位符赋值
Object[] params = {id};
// 执行
list = qr.query(sql, new BeanListHandler<School>(School.class),params);
// 返回
return list;
}
2.4.4.3.4 Service接口
/**
* 根据地区ID获取学校信息
* @param id
* @return
* @throws Exception
*/
public List<School> findSchoolsByAreaID(Integer id) throws Exception;
2.4.4.3.5 Service实现类
@Override
public List<School> findSchoolsByAreaID(Integer id) throws Exception {
return studentDAO.findSchoolsByAreaID(id);
}
到此模型层封装完毕
整理页面需求:
在区域的selcet标签上添加onchange事件,这个事件是当select的值发生改变的时候执行这个方法
<select id="areaSelect" required="required" onchange="loadSchools();">
</select>
编写这个方法
function loadSchools(){
// 获取学校的secelt
var scselect = $("#scSelect");
// 创建select内容
var selectstr = "<option value=''>---请选择---</option>";
// 发起请求
$.post("${pageContext.request.contextPath}/findSchoolsByAreaID",{aid:$("#areaSelect").val()},function(data){
});
}
此处向服务端发起了请求 并且把参数aid传给了服务器,那么服务器开始处理这个请求
后端控制器
@RequestMapping("/findSchoolsByAreaID")
public List<School> findSchoolsByAreaID(Integer aid)throws Exception{
return studentService.findSchoolsByAreaID(aid);
}
页面解析数据
function loadSchools(){
// 获取学校的secelt
var scselect = $("#scSelect");
// 创建select内容
var selectstr = "<option value=''>---请选择---</option>";
// 发起请求
$.post("${pageContext.request.contextPath}/findSchoolsByAreaID,{aid:$("#areaSelect").val()},function(data){
// 处理返回值
for(var i = 0;i<data.length;i++){
selectstr+="<option value='"+data[i].scid+"'>"+data[i].scname+"</option>"
}
// 将拼接好的数据放入select
scselect.html(selectstr);
});
}
效果:
到此第一个需求完事;
开始第二个需求:添加人员信息,
2.4.4.3 添加人员信息
因为人员信息页面已经接收的差不多了,所以直接发起请求添加即可
但是需要注意的问题是,页面传输过来的是两张表的数据,一个是学生表的数据,一个成绩表的数据需要分开处理
首先构建Model层
2.4.4.3.1 DAO层接口
/**
* 添加学生信息
* @param student
* @return
* @throws Exception
*/
public int insertStudent(Student student)throws Exception;
2.4.4.3.2 DAO层实现类
@Override
public int insertStudent(Student student) throws Exception {
// 创建方法的返回值
int count = 0;
// 获取数据库连接
DataSource dataSource = qr.getDataSource();
Connection conn = dataSource.getConnection();
// 设定手动提交
conn.setAutoCommit(false);
try {
// 添加学生信息 添加学生的考试信息
// 编写SQL语句
String sql = "insert into student values (null,?,?,?,?,?)";
// 占位符赋值
Object[] params = { student.getSname(), student.getSex(), student.getBirthday(), student.getExamnum(),
student.getScid() };
// 执行
count = qr.update(conn,sql, params);
// 怎么获取刚才添加的这个数据的主键ID呢 mysql的存储过程 数据库方法 线程问题
sql = "select last_insert_id()";
Number id = qr.query(conn,sql, new ScalarHandler<Number>(1));
// 学生ID有了 添加成绩 也有了
// 四门考试成绩的一次性添加
sql = "insert into result values (null,1,?,?),(null,2,?,?),(null,3,?,?),(null,4,?,?)";
// 占位符赋值
Object[] p1 = { id, student.getScores().get("语文"), id, student.getScores().get("数学"), id,
student.getScores().get("英语"), id, student.getScores().get("综合") };
// 执行
count = qr.update(conn,sql, p1);
// 提交
conn.commit();
} catch (Exception e) {
conn.close();
e.printStackTrace();
}finally{
// 关闭数据库连接
conn.close();
}
// 返回
return count;
}
此处注意SQL的语句执行时候的连续执行,其中select last_insert_id() 是查询刚才添加数据的主键ID
insert into result values (null,1,?,?),(null,2,?,?),(null,3,?,?),(null,4,?,?) 这条SQL语句一次性能往result表中添加4条数据,属于MySql独特的数据添加技巧
2.4.4.3.3 Service接口
/**
* 添加学生信息
* @param student
* @return
* @throws Exception
*/
public int insertStudent(Student student) throws Exception;
2.4.4.3.4 Service层实现类
@Override
public int insertStudent(Student student) throws Exception {
return studentDAO.insertStudent(student);
}
到此Model层处理完成
接下来后端处理器开始工作
2.4.4.3.5 后端处理器StudentOperateAction.xml
StudentOperateAction
package com.hnxy.web;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.hnxy.entity.Student;
import com.hnxy.service.StudentService;
/**
* 学生信息 添加 更新 删除 控制器
* @author sysmaster
*
*/
@Controller
public class StudentOperateAction {
// 创建service层对象
@Autowired
private StudentService studentService;
@InitBinder
public void initDate(WebDataBinder binder){
binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
}
@RequestMapping("/insertStudent")
public ModelAndView insertStudent(Student student)throws Exception{
// 创建方法的返回值
ModelAndView mv = new ModelAndView();
// 执行添加
int count = studentService.insertStudent(student);
// 判断
if(count > 0){
// 重定向到查询页面
mv.setViewName("redirect:/findStudentsByPage");
}else{
mv.addObject("errmsg", "很遗憾添加失败");
// 转发到报错页面
mv.setViewName("forward:/error.jsp");
}
// 返回
return mv;
}
}
此处需要注意对页面时间的处理
2.4.5 测试添加
到此添加功能完成
2.5 创建报错提示页面error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>学生信息管理与分析系统</title>
<!-- 引入CSS -->
<link rel="stylesheet" href="css/bootstrap.min.css">
<!-- 引入JS -->
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.9.1.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/bootstrap.min.js"></script>
<script type="text/javascript">
// 分页查询
function goIndex(){
window.location.href = "${pageContext.request.contextPath}/index.jsp";
}
</script>
</head>
<body>
<div class="jumbotron">
<div class="container">
<h1 style="color: red;">错误!${errmsg}</h1>
<p>
<button type="button" class="btn btn-primary btn-lg" onclick="goIndex();">
<span class="glyphicon glyphicon-user"></span> 返回首页
</button>
</p>
</div>
</div>
</body>
</html>