![022cbf5d0fc6f5d3f72f54ad99b9dc19.png](https://i-blog.csdnimg.cn/blog_migrate/e1f98c15c97aff24462adc1cd690a0ab.jpeg)
2.4 学生信息添加
2.4.1 产品经理阶段
![ca386a06fd131e297255ab230173da0c.png](https://i-blog.csdnimg.cn/blog_migrate/397672dcbea38faab6c66cdc8b1bf647.jpeg)
完成考生信息的添加功能,要求添加考生信息的同时需要添加考试成绩信息;
2.4.2 项目经理阶段
项目需求分析:
两处难点 :
1) 所属地区 需要根据不同的地区展示不同的学校
2) 学生表数据和成绩表数据不是同一个表的数据,添加非常的有难度!
2.4.3 程序员阶段
页面代码
<%@ 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>
完成效果
![3662e11f0e9f4e28d533b272a8c76605.png](https://i-blog.csdnimg.cn/blog_migrate/8d5cd1b80935eb0381dba575165844a0.jpeg)
根据页面我们优先解决考生考区的选择问题,此处我们知道这里是想选择一个考区 然后根据不同的考区加载不同的学校,那么首选我么就要知道有多少个考区?那么怎么加载这些考区呢?
按步骤来 : 加载考区信息
SQL
-- 加载考区信息
select a_id aid,a_name aname from area;
![a3295da8fe82db5c7b03585051c0bbcd.png](https://i-blog.csdnimg.cn/blog_migrate/020da91c7bd7151b73db4547738f3c25.png)
创建实体类,将查询结果映射到程序中
实体类
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;
}
}
DAO层接口
/**
* 获取所有的地区信息
* @return
* @throws Exception
*/
public List<Area> findAllAreas()throws Exception;
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;
}
Service接口
/**
* 获取所有的地区信息
* @return
* @throws Exception
*/
public List<Area> findAllAreas() throws Exception;
Service实现类
@Override
public List<Area> findAllAreas() throws Exception {
return studentDAO.findAllAreas();
}
这样我们的区域信息就封装好了,那么这个区域怎么给到页面呢?
此处我们可以思考一下 考区应该是页面加载的时候从数据库加载出来放入这个select框的,后面的学校信息应该是前面的考区信息发生改变然后随着再加载学校信息;
并且我们不得不重视一个问题,这个信息的加载是页面部分内容加载,而不是全部内容,所以我们传统的请求与相应模式在这就用不了了,因为传统的请求与相应模式是要把当前
页面全部提交过去,这样就会给我们造成很大的困扰,因为页面其他信息我们都还没有填写就提交,这样很显然影响了用户体验,所以此处我们需要一个页面部分内容刷新技术;
那么有没有什么技术能够满足我们这个需求呢?当然有,那就是ajax技术!
ajax
Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。
Ajax = 异步 JavaScript 和 XML(标准通用标记语言的子集)。
Ajax 是一种用于创建快速动态网页的技术。
Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。
![bc333b4c68e3d7d14ec21727f2c65587.png](https://i-blog.csdnimg.cn/blog_migrate/f2bc8a66038ca67aa9cf0f33bbd7887e.png)
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请求
后端控制器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字符串返回呢?
项目中添加三个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数组完成页面数据的调用
效果 :
![9e3591b5e3c2645415f952398e862d43.png](https://i-blog.csdnimg.cn/blog_migrate/d6d85219658279e6676472be507fa5b3.png)
运用同样的道理根据地区ID加载学校信息
首先整理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;
}
}
DAO层接口
/**
* 根据区域ID获取学校信息
* @param id
* @return
* @throws Exception
*/
public List<School> findSchoolsByAreaID(Integer id)throws Exception;
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;
}
Service接口
/**
* 根据地区ID获取学校信息
* @param id
* @return
* @throws Exception
*/
public List<School> findSchoolsByAreaID(Integer id) throws Exception;
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);
});
}
效果:
![9703fa52767a4406439fb59e1bdbfb66.png](https://i-blog.csdnimg.cn/blog_migrate/ef3e2446485ebb6df4c867622a3dc22d.png)
到此第一个需求完事;
开始第二个需求:添加人员信息,因为人员信息页面已经接收的差不多了,所以直接发起请求添加即可
![d82ddc60fbc11d5b5759dbaf4e969d65.png](https://i-blog.csdnimg.cn/blog_migrate/d20b5e383601b70983592445a6a27d95.png)
但是需要注意的问题是,页面传输过来的是两张表的数据,一个是学生表的数据,一个成绩表的数据需要分开处理
首先构建Model层
DAO层接口
/**
* 添加学生信息
* @param student
* @return
* @throws Exception
*/
public int insertStudent(Student student)throws Exception;
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独特的数据添加技巧
Service接口
/**
* 添加学生信息
* @param student
* @return
* @throws Exception
*/
public int insertStudent(Student student) throws Exception;
Service层实现类
@Override
public int insertStudent(Student student) throws Exception {
return studentDAO.insertStudent(student);
}
到此Model层处理完成
接下来后端处理器开始工作
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;
}
}
此处需要注意对页面时间的处理
创建报错提示页面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>
测试添加
![ca9dbb4a83b2d405ce6fe927b79eb0b9.png](https://i-blog.csdnimg.cn/blog_migrate/45ac50b1cb5345bd54ad9cf3c5a6af54.jpeg)
![d7274553498db9085c4870093e0e5590.png](https://i-blog.csdnimg.cn/blog_migrate/d2a30169493a5ae8d53930c8aa2bd502.jpeg)
到此添加功能完成
版权声明:原创作品,允许转载,转载时务必以超链接的形式表明出处和作者信息。否则将追究法律责任。来自海牛学院-青牛