Spring+SpringMVC+Mybatis实现增删改查--(四)SSM新增员工页面搭建
Spring+SpringMVC+Mybatis实现增删改查--(四)SSM新增员工页面搭建
新增员工:
1.在index.jsp页面点击“新增”弹出新增对话框
2.去数据库查询部门列表,显示在新增对话框中
3.用户输入数据并进行校验(校验这里分成了三种)
jQuery前端校验、ajax用户名的重复校验、重要数据(后端校验(JR303),唯一约束)
4完成保存。
REST风格的URI
规定URI:
/emp/{id} GET 查询
/emp POST保存员工
/emp/{id} PUT 修改员工
/emp/{id} DELETE删除员工
新增员工的具体步骤:
1.新增弹出对话框
(1)在bootstrap中JavaScript插件找到模态对话框,参考官网的代码
(2)弹出模态对话框的方式(官网给出了两种方式)
(3)具体的代码实现方式
<!--员工添加的模态框 -->
<div class="modal fade" id="empAddModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">员工添加</h4>
</div>
<div class="modal-body">
<!-- 表单输入框 -->
<form class="form-horizontal">
<div class="form-group">
<label for="empName_add_input" class="col-sm-2 control-label">empName</label>
<div class="col-sm-10">
<input type="text" name="empName" class="form-control" id="empName_add_input" placeholder="empName">
<span class="help-block"></span>
</div>
</div>
<div class="form-group">
<label for="email_add_input" class="col-sm-2 control-label">email</label>
<div class="col-sm-10">
<input type="text" name="email" class="form-control" id="email_add_input" placeholder="aaa@qq.com">
<span class="help-block"></span>
</div>
</div>
<!-- 性别 -->
<div class="form-group">
<label for="email_add_input" class="col-sm-2 control-label">gender</label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="gender" id="gender1_add_input" value="M" checked="checked"> 男
</label>
<label class="radio-inline">
<input type="radio" name="gender" id="gender2_add_input" value="F"> 女
</label>
</div>
</div>
<!-- 部门名 -->
<div class="form-group">
<label for="email_add_input" class="col-sm-2 control-label">deptName</label>
<div class="col-sm-4">
<!-- 部门提交部门id即可 -->
<select class="form-control" name="dId" id="dept_add_select">
</select>
</div>
</div>
</form>
<!-- -表单底部 -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary" id="emp_save_btn">保存</button>
</div>
</div>
</div>
</div>
2.获取部门的信息,显示在下拉列表中
(1)index.jsp发出ajax请求查出所有部门信息并显示在下拉列表中
//查出所有的部门信息并显示在下拉列表中
function getDepts(ele){
$(ele).empty();
$.ajax({
url:"${APP_PATH}/depts",
type:"GET",
success:function(result){
//{"code":0,"msg":"处理成功","
//data":{"depts":[{"deptId":1,"deptName":"开发部"},{"deptId":2,"deptName":"测试部"}]}}
//显示部门信息在下拉列表中
$.each(result.data.depts,function(){
var optionEle=$("<option></option>").append(this.deptName).attr("value",this.deptId);
optionEle.appendTo("#dept_add_select");
});
}
});
}
(2)DepartmentService.java的代码
package com.lcz.crud.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.lcz.crud.bean.Department;
import com.lcz.crud.dao.DepartmentMapper;
@Service
public class DepartmentService {
@Autowired
private DepartmentMapper departmentMapper;
public List<Department> getDepts() {
List<Department> list = departmentMapper.selectByExample(null);
return list;
}
}
(3)DepartmentController.java用来获取部门的信息
package com.lcz.crud.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.lcz.crud.bean.Department;
import com.lcz.crud.bean.Msg;
import com.lcz.crud.service.DepartmentService;
/**
* 处理和部门有关的请求
* @author LvChaoZhang
*
*/
@Controller
public class DepartmentController {
@Autowired
private DepartmentService departmentService;
/**
* 返回所有的部门信息
*/
@RequestMapping("/depts")
@ResponseBody
public Msg getDepts() {
//查出所有的部门信息
List<Department> list=departmentService.getDepts();
return Msg.success().add("depts", list);
}
}
3.数据校验
(1)jQuery前端校验新建对话框的用户名、密码
/校验表单数据的方法
function validate_add_form() {
//1.先拿到要校验的数据,使用正则表达式
var empName=$("#empName_add_input").val();
var regName=/(^[a-zA-Z0-9_-]{6,16}$)|(^[\u2E80-\u9FFF]{2,5})/;
if(!regName.test(empName)){
//alert("用户名可以是2-5位中文或者6-16位英文和数字的组合");
show_validate_msg("#empName_add_input","error","用户名可以是2-5位中文或者6-16位英文和数字的组合");
return false;
}else{
show_validate_msg("#empName_add_input","success","");
}
//2.校验邮箱信息
var email=$("#email_add_input").val();
var regEmail=/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/;
if (!regEmail.test(email)) {
//alert("邮箱格式不正确");
//清空这个元素之前的样式
show_validate_msg("#email_add_input","error","邮箱格式不正确");
return false;
}else{
show_validate_msg("#email_add_input","success","");
}
return true;
}
(2)ajax请求用户名是否重复
a.index.jsp发出ajax请求
//校验用户名是否可用
$("#empName_add_input").change(function(){
//发送ajax请求校验用户名是否可用
var empName=this.value;
$.ajax({
url:"${APP_PATH}/checkuser",
data:"empName="+empName,
type:"POST",
success:function(result){
if(result.code==0){
show_validate_msg("#empName_add_input","success","用户名可用");
$("#emp_save_btn").attr("ajax-va","success");
}else{
show_validate_msg("#empName_add_input","error",result.data.va_msg);
$("#emp_save_btn").attr("ajax-va","error");
}
}
});
});
b.EmployeeService.java中检验用户名是否可用的方法
/**
* 校验用户名是否可用
* @param empName
* @return true 可用 false不可用
*/
public boolean checkUser(String empName) {
EmployeeExample example=new EmployeeExample();
Criteria criteria = example.createCriteria();
criteria.andEmpNameEqualTo(empName);
long count=employeeMapper.countByExample(example);
return count==0;
}
c.EmployeeController.java中调用检查用户名
/**
* 检查用户名是否可用
* @param empName
* @return
*/
@ResponseBody
@RequestMapping("/checkuser")
public Msg checkUser(@RequestParam("empName")String empName) {
//先判断用户名是合法的表达式
String regex="(^[a-zA-Z0-9_-]{6,16}$)|(^[\\u2E80-\\u9FFF]{2,5})";
if(!empName.matches(regex)) {
return Msg.fail().add("va_msg", "用户名必须是6-16位数字和字母的组合或者2-5位中文");
}
//数据库用户名重复校验
boolean b=employeeService.checkUser(empName);
if(b) {
return Msg.success();
}else {
return Msg.fail().add("va_msg", "用户名不可用");
}
}
(3)后端数据JR303校验
a.pom.xml中导入hibernate-validator包
<!-- JSR303数据校验支持 tomcat7及以上的服务器直接导入即可
tomcat7以下的服务器,el表达式,额外的给服务器的lib包中替换新的el-->
<!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.7.Final</version>
</dependency>
b.Employee.java写入@Pattern
@Pattern(regexp="(^[a-zA-Z0-9_-]{6,16}$)|(^[\\u2E80-\\u9FFF]{2,5})",message="用户名必须是2-5位中文或者6-16位英文和数字的组合")
private String empName;
private String gender;
//@Email
@Pattern(regexp="^([a-z0-9_\\.-]+)@([\\da-z\\.-]+)\\.([a-z\\.]{2,6})$",message="邮箱格式不正确")
private String email;
c.保存按钮的事件
EmployeeService的保存方法
/**
* 员工保存
* 1.支持JSR303校验
* 导入hibernate validator
* @param employee
*/
public void saveEmp(Employee employee) {
employeeMapper.insertSelective(employee);
}
EmployeeController的保存方法外加校验
/**
* 员工保存
* @return
*/
@RequestMapping(value="/emp",method=RequestMethod.POST)
@ResponseBody
public Msg saveEmp(@Valid Employee employee,BindingResult result) {//因为表单中name中的值跟employee对象的值一样,所以自动封装
if(result.hasErrors()) {
//校验失败,返回失败,在模态框中显示校验失败的错误信息
Map<String, Object>map=new HashMap<String, Object>();
List<FieldError> errors = result.getFieldErrors();
for(FieldError fieldError:errors) {
System.out.println("错误的字段名"+fieldError.getField());
System.out.println("错误的信:"+fieldError.getDefaultMessage());
map.put(fieldError.getField(), fieldError.getDefaultMessage());
}
return Msg.fail().add("errorFields", map);
}else {
employeeService.saveEmp(employee);
return Msg.success();
}
}
4.保存按钮事件
正常保存之后会跳转到最后一页
给出这一节完整的index.jsp,功能是通过JavaScript的封装库jquery来实现功能的,功能上都有代码解释,可以参考
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!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>
<%
pageContext.setAttribute("APP_PATH", request.getContextPath());
%>
<!-- web路径:
不以/开始的相对路径,找资源,以当前资源的路径为基准,经常容易出问题。
以/开始的相对路径,找资源,以服务器的路径为标准(http://localhost:8080);需要加上项目名
http://localhost:3306/crud
-->
<script type="text/javascript" src="${APP_PATH }/static/js/jquery-3.3.1.min.js"></script>
<link href="${APP_PATH }/static/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet">
<script src="${APP_PATH }/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
</head>
<body>
<!--员工添加的模态框 -->
<div class="modal fade" id="empAddModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">员工添加</h4>
</div>
<div class="modal-body">
<!-- 表单输入框 -->
<form class="form-horizontal">
<div class="form-group">
<label for="empName_add_input" class="col-sm-2 control-label">empName</label>
<div class="col-sm-10">
<input type="text" name="empName" class="form-control" id="empName_add_input" placeholder="empName">
<span class="help-block"></span>
</div>
</div>
<div class="form-group">
<label for="email_add_input" class="col-sm-2 control-label">email</label>
<div class="col-sm-10">
<input type="text" name="email" class="form-control" id="email_add_input" placeholder="aaa@qq.com">
<span class="help-block"></span>
</div>
</div>
<!-- 性别 -->
<div class="form-group">
<label for="email_add_input" class="col-sm-2 control-label">gender</label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="gender" id="gender1_add_input" value="M" checked="checked"> 男
</label>
<label class="radio-inline">
<input type="radio" name="gender" id="gender2_add_input" value="F"> 女
</label>
</div>
</div>
<!-- 部门名 -->
<div class="form-group">
<label for="email_add_input" class="col-sm-2 control-label">deptName</label>
<div class="col-sm-4">
<!-- 部门提交部门id即可 -->
<select class="form-control" name="dId" id="dept_add_select">
</select>
</div>
</div>
</form>
<!-- -表单底部 -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary" id="emp_save_btn">保存</button>
</div>
</div>
</div>
</div>
<!-- 搭建显示页面 -->
<div class="container">
<!-- 标题 -->
<div class="row">
<div class="col-md-12">
<h1 >SSM-CRUD</h1>
</div>
</div>
<!-- 新增、删除按钮 -->
<div class="row">
<div class="col-md-4 col-md-offset-8">
<button class="btn btn-primary" id="emp_add_modal_btn">新增</button>
<button class="btn btn-danger">删除</button>
</div>
</div>
<br>
<!-- 显示表格数据 -->
<div class="row">
<div class="col-md-12">
<table class="table table-hover" id="emps_table">
<thead>
<tr>
<th>#</th>
<th>empName</th>
<th>gender</th>
<th>email</th>
<th>deptName</th>
<th>操作</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<!-- 显示分页信息 -->
<div class="row">
<!-- 分页文字信息 -->
<div class="col-md-6" id="page_info_area">
<!--当前页,总共页,总共记录数 -->
</div>
<!-- 分页条信息 -->
<div class="col-md-6" id="page_nav_area">
</div>
</div>
</div>
<script type="text/javascript">
var totalRecord;//总记录数
//1.页面加载完成之后,直接去发送一个ajax请求,要到分页数据
$(function () {
//去首页
to_page(1);
});
//跳转页码的功能
function to_page(pn){
$.ajax({
url:"${APP_PATH}/emps",
data:"pn="+pn,
type:"GET",
success:function(result){
//console.log(result);
//1、解析并显示员工数据
build_emps_table(result);
//2、解析并显示分页信息
build_page_info(result);
//3、解析显示分页条数据
build_page_nav(result);
}
});
}
//解析并显示员工数据
function build_emps_table(result){
//清空table表格
$("#emps_table tbody").empty();
var emps=result.data.pageInfo.list;//所有的员工数据
//遍历所有的员工数据
$.each(emps,function(index,item){
//alert(item.empName);
//构建表格
var empIdTd=$("<td></td>").append(item.empId);
var empNameTd=$("<td></td>").append(item.empName);
var genderTd=$("<td></td>").append(item.gender=='M'?"男":"女");
var emailTd=$("<td></td>").append(item.email);
var deptNameTd=$("<td></td>").append(item.department.deptName);
/**
<button class="btn btn-primary btn-sm edit_btn">
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
编辑
</button>
*/
var editBtn=$("<button></button>").addClass("btn btn-primary btn-sm edit_btn")
.append($("<span></span>").addClass("glyphicon glyphicon-pencil")).append("编辑");
var delBtn=$("<button></button>").addClass("btn btn-danger btn-sm delete_btn")
.append($("<span></span>").addClass("glyphicon glyphicon-trash")).append("删除");
var btnTd=$("<td></td>").append(editBtn).append(" ").append(delBtn);
//append方法执行完成以后还是返回原来的元素
$("<tr></tr>").append(empIdTd)
.append(empNameTd)
.append(genderTd)
.append(emailTd)
.append(deptNameTd)
.append(btnTd)
.appendTo("#emps_table tbody");
});
}
//解析显示分页信息的
function build_page_info(result){
//分页列表清空
$("#page_info_area").empty();
$("#page_info_area").append("当前"+result.data.pageInfo.pageNum+"页,总共"+result.data.pageInfo.pages+"页,总共"+result.data.pageInfo.total+"记录数");
totalRecord=result.data.pageInfo.total;//将总记录数保存到全局变量中
}
/**
<nav aria-label="Page navigation">
<ul class="pagination">
<li>
<a href="#" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
<li><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
<li><a href="#">4</a></li>
<li><a href="#">5</a></li>
<li>
<a href="#" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
*/
//解析并显示分页条,点击分页能去下一页..
function build_page_nav(result){
//page_nav_area
//清空列表
$("#page_nav_area").empty();
var ul=$("<ul></ul>").addClass("pagination");
//首页
var firstPageLi=$("<li></li>").append($("<a></a>").append("首页").attr("href","#"));
//前一页
var prePageLi = $("<li></li>").append($("<a></a>").append("«"));
//如果没有前页的话,首页和前页隐藏
if(result.data.pageInfo.hasPreviousPage == false){
firstPageLi.addClass("disabled");
prePageLi.addClass("disabled");
}else{
//为元素添加点击翻页的事件
//首页的点击事件
firstPageLi.click(function(){
to_page(1);
});
//前一页的点击事件
prePageLi.click(function(){
to_page(result.data.pageInfo.pageNum -1);
});
}
//后一页
var nextPageLi = $("<li></li>").append($("<a></a>").append("»"));
//末页
var lastPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href","#"));
//如果没有下一页的话,下一页的末页隐藏
if(result.data.pageInfo.hasNextPage == false){
nextPageLi.addClass("disabled");
lastPageLi.addClass("disabled");
}else{
//下一页的点击事件
nextPageLi.click(function(){
to_page(result.data.pageInfo.pageNum +1);
});
//末页的点击事件
lastPageLi.click(function(){
to_page(result.data.pageInfo.pages);
});
}
//添加首页和前一页
ul.append(firstPageLi).append(prePageLi);
//遍历给ul添加页码提示
$.each(result.data.pageInfo.navigatepageNums,function(index,item){
var numLi = $("<li></li>").append($("<a></a>").append(item));
//按钮加深颜色
if(result.data.pageInfo.pageNum==item){
numLi.addClass("active");
}
//页码的点击事件
numLi.click(function () {
to_page(item);
});
//遍历给ul添加页码提示
ul.append(numLi);
});
//添加下一页和末页的提示
ul.append(nextPageLi).append(lastPageLi);
//把ul加入到nav元素中
var navEle=$("<nav></nav>").append(ul);
//把nav元素放到div中
navEle.appendTo("#page_nav_area");
}
//表单重置方法清空表单样式及内容
function reset_form(ele){
$(ele)[0].reset();//清空表单内容
//清空表单样式
$(ele).find("*").removeClass("has-error has-success");
$(ele).find(".help-block").text("");
}
//点击新增按钮弹出新增对话框的点击事件
$("#emp_add_modal_btn").click(function () {
//清除表单数据(表单完整重置(表单的数据,表单的样式))
reset_form("#empAddModal form");
//发送ajax请求,查出部门信息,显示在下拉列表中
getDepts("#empAddModal select");
//弹出模态框
$("#empAddModal").modal({
backrop:"static"
});
});
//查出所有的部门信息并显示在下拉列表中
function getDepts(ele){
$(ele).empty();
$.ajax({
url:"${APP_PATH}/depts",
type:"GET",
success:function(result){
//{"code":0,"msg":"处理成功","
//data":{"depts":[{"deptId":1,"deptName":"开发部"},{"deptId":2,"deptName":"测试部"}]}}
//显示部门信息在下拉列表中
$.each(result.data.depts,function(){
var optionEle=$("<option></option>").append(this.deptName).attr("value",this.deptId);
optionEle.appendTo("#dept_add_select");
});
}
});
}
//校验表单数据的方法
function validate_add_form() {
//1.先拿到要校验的数据,使用正则表达式
var empName=$("#empName_add_input").val();
var regName=/(^[a-zA-Z0-9_-]{6,16}$)|(^[\u2E80-\u9FFF]{2,5})/;
if(!regName.test(empName)){
//alert("用户名可以是2-5位中文或者6-16位英文和数字的组合");
show_validate_msg("#empName_add_input","error","用户名可以是2-5位中文或者6-16位英文和数字的组合");
return false;
}else{
show_validate_msg("#empName_add_input","success","");
}
//2.校验邮箱信息
var email=$("#email_add_input").val();
var regEmail=/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/;
if (!regEmail.test(email)) {
//alert("邮箱格式不正确");
//清空这个元素之前的样式
show_validate_msg("#email_add_input","error","邮箱格式不正确");
return false;
}else{
show_validate_msg("#email_add_input","success","");
}
return true;
}
//表单的提示信息
function show_validate_msg(ele,status,msg){
//清除当前元素的校验状态
$(ele).parent().removeClass("has-success has-error");
$(ele).next("span").text("");
if("success"==status){
$(ele).parent().addClass("has-success");
$(ele).next("span").text(msg);
}else if ("error"==status) {
$(ele).parent().addClass("has-error");
$(ele).next("span").text(msg);
}
}
//校验用户名是否可用
$("#empName_add_input").change(function(){
//发送ajax请求校验用户名是否可用
var empName=this.value;
$.ajax({
url:"${APP_PATH}/checkuser",
data:"empName="+empName,
type:"POST",
success:function(result){
if(result.code==0){
show_validate_msg("#empName_add_input","success","用户名可用");
$("#emp_save_btn").attr("ajax-va","success");
}else{
show_validate_msg("#empName_add_input","error",result.data.va_msg);
$("#emp_save_btn").attr("ajax-va","error");
}
}
});
});
//新增对话框中的保存按钮事件,保存按钮
$("#emp_save_btn").click(function () {
//0.对要提交给服务器的表单数据进行校验
if(!validate_add_form()){
return false;
};
//0.判断之前的ajax用户名校验是否成功,如果成功才往下走
if($(this).attr("ajax-va")=="error"){
return;
}
//1.新增对话框中填写的表单信息提交给服务器进行保存
//2.发送ajax请求保存员工
//alert($("#empAddModal form").serialize());
$.ajax({
url:"${APP_PATH}/emp",
type:"POST",
data:$("#empAddModal form").serialize(),
success:function(result){
//alert(result.msg);
if (result.code==0) {
//员工保存成功之后,关闭模态框 ,来到最后一页显示刚才保存的数据
//1.关闭模态框
$("#empAddModal").modal('hide');
//2.来到最后一页,显示最后一页
to_page(totalRecord);
}else{
//显示失败信息
//console.log(result);
//有哪个字段的错误信息就显示哪个字段的
//{"code":1,"msg":"失败","data":{"errorFields":{"email":"邮箱格式不正确"}}}
if(undefined!=result.data.errorFields.email){
//显示邮箱错误信息
show_validate_msg("#email_add_input","error",result.data.errorFields.email);
}
if(undefined!=result.data.errorFields.empName){
//显示员工名字的错误信息
show_validate_msg("#empName_add_input","error",result.data.errorFields.empName);
}
}
}
});
});
</script>
</body>
</html>