ssm框架整合入门系列——新增-员工的添加
新增-员工的添加
新增-逻辑
- 在index.jsp页面点击“新增”
- 弹出新增对话框
- 去数据库查询部门列表,显示在对话框中
- 用户输入数据,并进行校验
jquery前端校验,ajax用户名重复校验,重要数据(后端校验(JSR303),唯一约束) - 完成保存
URI:
- /emp/{id} GET 查询员工
- /emp POST 保存员工
- /emp/{id} PUT 修改员工
- /emp/{id} DELETE 删除员工
在controller新增DepartmentController.java
package com.liantao.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.liantao.crud.bean.Department;
import com.liantao.crud.bean.Msg;
import com.liantao.crud.service.DepartmentService;
/**
* 处理和部门有关的请求
* @author liantao.me
*
*/
@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);
}
}
在service 新增DepartmentService.java
package com.liantao.crud.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.liantao.crud.bean.Department;
import com.liantao.crud.dao.DepartmentMapper;
@Service
public class DepartmentService {
@Autowired
private DepartmentMapper departmentMapper;
public List<Department> getDepts() {
// TODO Auto-generated method stub
List<Department> list = departmentMapper.selectByExample(null);
return list;
}
}
修改EmployeeController.java,(添加JSR303校验,添加判断新增的用户名是否可用的方法)
pom.xml
添加:
<!-- JSR303数据校验支持 -->
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.1.Final</version>
</dependency>
- EmployeeController.java 修改
package com.liantao.crud.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.liantao.crud.bean.Employee;
import com.liantao.crud.bean.Msg;
import com.liantao.crud.service.EmployeeService;
/**
* 处理员工的crud请求
* @author liantao.me
*
*/
@Controller
public class EmployeeController {
@Autowired
EmployeeService employeeService;
/**
* 检查用户名是否可用
* @param empName
* @return
*/
@ResponseBody
@RequestMapping("/checkuser")
public Msg checkuser(@RequestParam("empName")String empName){
//先判断用户名是否是合法的表达式
String regx = "(^[a-zA-Z0-9_-]{6,16}$)|(^[\u2E80-\u9FFF]{2,5})";
if(!empName.matches(regx)){
return Msg.fail().add("va_msg", "java:用户名为2-5位中文或者6-16位英文和数字的组合");
}
//数据库用户名重复校验
boolean b = employeeService.checkUser(empName);
if(b){
return Msg.success(); //code 100
}else
{
return Msg.fail().add("va_msg", "用户名不可用"); //code 200
}
}
/**
* 员工保存
* 1.支持JSR303校验
* 2.导入Hibernate-Validator
*
*
* @return
*/
@RequestMapping(value="/emp",method=RequestMethod.POST)
@ResponseBody
public Msg saveEmp(@Valid Employee employee, BindingResult result){
if(result.hasErrors()){
//校验失败,应该返回失败,在模态框中显示校验失败的信息
Map<String, Object> map = new HashMap<>();
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("errFields", map);
}else{
employeeService.saveEmp(employee);
return Msg.success();
}
}
/**
* 需导入jackson包
* @param pn
* @return
*/
@RequestMapping("/emps")
@ResponseBody
public Msg getEmpsWithJson(@RequestParam(value="pn",defaultValue="1")Integer pn){
//引入PageHelper分页插件
//查询之前需要调用,,传入页码,以及每页的大小
PageHelper.startPage(pn,5);
//startPage后面紧跟的是这个查询就是一个分页查询
List<Employee> emps = employeeService.getAll();
//使用pageInfo包装查询后的结果,只需要将Pageinfo交给页面就行了
//封装了详细的分页信息,包括我们查出来的数据,传入连续显示的数据
PageInfo page = new PageInfo(emps,5);
return Msg.success().add("pageInfo",page);
}
/*
* 查询员工数据(分页查询)
* @return
*/
//@RequestMapping("/emps")
public String getEmps(@RequestParam(value="pn",defaultValue="1")Integer pn,Model model){
//引入PageHelper分页插件
//查询之前需要调用,,传入页码,以及每页的大小
PageHelper.startPage(pn,5);
//startPage后面紧跟的是这个查询就是一个分页查询
List<Employee> emps = employeeService.getAll();
//使用pageInfo包装查询后的结果,只需要将Pageinfo交给页面就行了
//封装了详细的分页信息,包括我们查出来的数据,传入连续显示的数据
PageInfo page = new PageInfo(emps,5);
model.addAttribute("pageInfo",page);
return "list";
}
}
EmployeeService的修改(添加了员工保存,和用户名检测的方法):
package com.liantao.crud.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;
import com.github.pagehelper.PageHelper;
import com.liantao.crud.bean.Employee;
import com.liantao.crud.bean.EmployeeExample;
import com.liantao.crud.bean.EmployeeExample.Criteria;
import com.liantao.crud.dao.EmployeeMapper;
@Service
public class EmployeeService {
@Autowired
EmployeeMapper employeeMapper;
/**
* 查询所有员工数据(分页查询)
* @return
*/
public List<Employee> getAll() {
// TODO Auto-generated method stub
return employeeMapper.selectByExampleWithDept(null);
}
/**
* 员工保存
* @param employee
*/
public void saveEmp(Employee employee) {
// TODO Auto-generated method stub
employeeMapper.insertSelective(employee);
}
/**
* 检验用户名是否可用
* @param empName
* @return true.代表当前姓名可用,否则false 不可用
*/
public boolean checkUser(String empName) {
// TODO Auto-generated method stub
EmployeeExample example = new EmployeeExample();
Criteria criteria = example.createCriteria();
criteria.andEmpNameEqualTo(empName);
long count = employeeMapper.countByExample(example);
return count == 0;
}
}
修改Employee.java (给相关字段加了注解)
package com.liantao.crud.bean;
import javax.validation.constraints.Pattern;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;
public class Employee {
private Integer empId;
@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;
private Integer dId;
//希望查询员工的同时部门信息也是查询好的
private Department department;
public Employee() {
super();
// TODO Auto-generated constructor stub
}
public Employee(Integer empId, String empName, String gender, String email, Integer dId) {
super();
this.empId = empId;
this.empName = empName;
this.gender = gender;
this.email = email;
this.dId = dId;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
public Integer getEmpId() {
return empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName == null ? null : empName.trim();
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender == null ? null : gender.trim();
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email == null ? null : email.trim();
}
public Integer getdId() {
return dId;
}
public void setdId(Integer dId) {
this.dId = dId;
}
}
完成index.jsp的jsp修改 (主要是jq,ajax对表单数据显示、验证的逻辑处理)
<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>员工列表</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
<!-- 引入jquery -->
<script type="text/javascript" src="${path}/ssm-crud/static/js/jquery-1.12.4.js"></script>
<!-- 引入css、js -->
<link href="${path}/ssm-crud/static/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet">
<script src="${path}/ssm-crud/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 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 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="xanwidtf@foxmail.com">
<span class="help-block"></span>
</div>
</div>
<div class="form-group">
<label 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="true"> 男
</label>
<label class="radio-inline">
<input type="radio" name="gender" id="gender2_add_input" value="F"> 女
</label>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">deptName</label>
<div class="col-sm-4">
<!-- 提交部门id即可 -->
<select class="form-control" name="dId">
</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>
<!-- 显示表格数据 -->
<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:"${path}/ssm-crud/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.extend.pageInfo.list;
$.each(emps,function(index,item){
//alert(item.empName);
var emIdTd = $("<td></td>").append(item.empId);
var empNameTd = $("<td></td>").append(item.empName);
var genderTd = $("<td></td>").append(item.gender=='M'?'男':'女');
var mailTd = $("<td></td>").append(item.email);
var deptNameTd = $("<td></td>").append(item.department.deptName);
/**
<button class="btn btn-primary btn-sm">
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
编辑
</button>
**/
var editBtn = $("<button></button>").addClass("btn btn-primary btn-sm")
.append($("<span></span>").addClass("glyphicon glyphicon-pencil")).append("编辑");
var delBtn = $("<button></button>").addClass("btn btn-danger btn-sm")
.append($("<span></span>").addClass("glyphicon glyphicon-trash")).append("删除");
var btnTd = $("<td></td>").append(editBtn).append(" ").append(delBtn);
//append方法执行完成以后还是返回原来的元素
$("<tr></tr>").append(emIdTd)
.append(empNameTd)
.append(genderTd)
.append(mailTd)
.append(deptNameTd)
.append(btnTd)
.appendTo("#emps_table tbody");
});
}
//解析显示分页信息
function build_page_info(result){
//清空table表格
$("#page_info_area").empty();
$("#page_info_area").append("当前"+result.extend.pageInfo.pageNum+"页,总"+
result.extend.pageInfo.pages+"页,总"+
result.extend.pageInfo.total+"条记录");
totalRecord = result.extend.pageInfo.total;
}
//解析显示分页条,点击分页要能去下一页
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.extend.pageInfo.hasPreviousPage == false){
firstPageLi.addClass("disabled");
prePageLi.addClass("disabled");
}else{
//为元素添加点击翻页
firstPageLi.click(function(){
to_page(1);
})
prePageLi.click(function(){
to_page(result.extend.pageInfo.pageNum-1);
})
}
var nextPageLi = $("<li></li>").append($("<a></a>").append("»"));
var laststPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href","#"));
if(result.extend.pageInfo.hasNextPage == false){
nextPageLi.addClass("disabled");
laststPageLi.addClass("disabled");
}else{
//为元素添加点击翻页
nextPageLi.click(function(){
to_page(result.extend.pageInfo.pageNum+1);
})
laststPageLi.click(function(){
to_page(result.extend.pageInfo.pages);
})
}
//添加首页和前一页的显示
ul.append(firstPageLi).append(prePageLi);
//1,2,..5遍历给ul中添加页码提示
$.each(result.extend.pageInfo.navigatepageNums,function(index,item){
var numLi = $("<li></li>").append($("<a></a>").append(item));
if(result.extend.pageInfo.pageNum == item){
numLi.addClass("active");
}
numLi.click(function(){
to_page(item);
})
ul.append(numLi);
})
//添加下一页和末页的提示
ul.append(nextPageLi).append(laststPageLi);
//把ul加入到nav
var navEle = $("<nav></nav>").append(ul);
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").modal({
backdrop:"static"
});
});
//查出所有的部门信息并显示在下拉列表中
function getDepts(){
$.ajax({
url:"${path}/ssm-crud/depts",
type:"GET",
success:function(result){
//{"code":100,"msg":"处理成功",
//"extend":{"depts":[{"deptId":1,"deptName":"开发部"},{"deptId":2,"deptName":"测试部"}]}}
//console.log(result);
//显示部门信息在下拉列表中
//$("#empAddModal select").append("");
$.each(result.extend.depts,function(){
var optionEle = $("<option></option>").append(this.deptName).attr("value",this.deptId);
optionEle.appendTo("#empAddModal 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 eamil = $("#email_add_input").val();
var regEmail = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/;
if(!regEmail.test(eamil)){
//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);
}
}
//ajax校验用户名是否可用
$("#empName_add_input").change(function(){
//发送ajax请求校验用户名是否可用
var empName = this.value;
$.ajax({
url:"${path}/ssm-crud/checkuser",
data:"empName="+empName,
type:"POST",
success:function(result){
if(result.code=="100"){
show_validate_msg("#empName_add_input","success","用户名可用");
$("#emp_save_btn").attr("ajax-va","success");
}else{
show_validate_msg("#empName_add_input","error",result.extend.va_msg);
$("#emp_save_btn").attr("ajax-va","error");
}
}
});
});
//点击保存,保存员工
$("#emp_save_btn").click(function(){
//1.模态框中填写的表单数据提交给服务器进行保存
//先对要提交给服务器的数据进行校验
if(!validate_add_form()){
return false;
}
//1.判断之前的ajax用户名是否成功,如果失败,阻止保存操作
if($(this).attr("ajax-va")=="error"){
return false;
}
//2.发送ajax请求保存员工
$.ajax({
url:"${path}/ssm-crud/emp",
type:"POST",
data:$("#empAddModal form").serialize(),
success:function(result){
//alert(result.msg); //弹出提示框
if(result.code == 100){
//员工保存成功,
//1.关闭模态框
$("#empAddModal").modal("hide")
//2.来到最后一页,显示刚才保存的数据
//发送ajax请求显示最后一页数据即可
to_page(totalRecord);
}else{
//显示失败信息
//console.log(result);
//有哪个字段的错误信息就显示哪个字段信息
if(undefined != result.extend.errorFields.email){
//显示邮箱错误信息系
show_validate_msg("#email_add_input","error",result.extend.errorFields.email);
}
if(undefined != result.extend.errorFields.empName){
//显示员工名字错误信息
show_validate_msg("#empName_add_input","error",result.extend.errorFields.empName);
}
}
}
});
});
</script>
</body>
</html>
END