*新增邏輯
1、 index.jsp頁面點擊新增
2、 彈出對話框
3、 去數據庫查詢部門列表(因爲部門列表是數據庫裏面的)
4、 用戶輸入數據,完成表格
我們首先寫下部門的Controller和Service
1)DepartmentService.java
package com.atguigu.crud.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.atguigu.crud.bean.Department;
import com.atguigu.crud.dao.DepartmentMapper;
@Service
public class DepartmentService {
@Autowired
private DepartmentMapper departmentMapper;
public List<Department> getDepts() {
// 返回所有查到的部門
List<Department> list=departmentMapper.selectByExample(null);
return list;
}
}
2)DepartmentController.java
package com.atguigu.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.atguigu.crud.bean.Department;
import com.atguigu.crud.bean.Msg;
import com.atguigu.crud.service.DepartmentService;
//處理和部門有關的請求
@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)EmployeeController.java添加內容
//用於保存員工
/*
* 1、要支持JSR303校驗,需要導入Hibernate-Validator的依賴
* 2、要使用,需要添加@Valid表示要校驗Employee(該類中已經添加要求)
* 還要添加BindingResult來封裝校驗結果
*/
@RequestMapping(value="/emp",method=RequestMethod.POST)
@ResponseBody
public Msg saveEmp(@Valid Employee employee,BindingResult result){
if(result.hasErrors()){
//校驗失敗,需要返回失敗,在模態框中顯示校驗失敗的錯誤信息,遍歷錯誤信息
//封裝個map,用於返回錯誤信息
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("errorFields", map);
}else{
employeeService.saveEmp(employee);
return Msg.success();
}
}
//檢查是否員工重複,輸入的用戶名是否可用
@ResponseBody
@RequestMapping("/checkuser")
public Msg checkuser(@RequestParam("empName")String empName){
//先判斷用戶名是否合法的表達式
String regx="(^[a-zA-Z0-9_-]{4,16}$)|(^[\u2E80-\u9FFF]{2,5})";
if(!empName.matches(regx)){
return Msg.fail().add("va_msg", "用戶名必須是4-16數字字母組合,或者2-5位中文(後臺校驗)");
}
//數據庫用戶名重複校驗
boolean b=employeeService.checkUser(empName);
if(b){
return Msg.success();
}else{
return Msg.fail().add("va_msg", "用戶名已存在(後臺校驗)");
}
}
4)EmployeeService.java添加內容
//員工保存
public void saveEmp(Employee employee) {
// TODO Auto-generated method stub
employeeMapper.insertSelective(employee);
}
//檢驗用戶名是否可用
//如果沒有這條記錄,則等於0,則返回true,即當前姓名可用
public boolean checkUser(String empName) {
// TODO Auto-generated method stub
EmployeeExample example=new EmployeeExample();
Criteria criteria= example.createCriteria();
criteria.andEmpNameEqualTo(empName);
//countByExample是自動生成的方法,如果有這條記錄,就返回大於0,否則返回0
long count=employeeMapper.countByExample(example);
return count==0;
}
5)Employee.java中添加JSR303用於後臺校驗輸入是否正確(如果還沒引入所需jar包,請看第六步引入所依賴的包)
只需要在email上添加@Email(message="郵箱格式錯誤")
以及empName上添加
//Pattern表示自定義註解,regexp屬性是正則表達式
@Pattern(regexp="(^[a-zA-Z0-9_-]{4,16}$)|(^[\u2E80-\u9FFF]{2,5})"
,message="用戶名必須是4-16數字字母組合,或者2-5位中文(後臺校驗)")
如圖:
6)pom中添加後臺校驗JSR303(Hibernate-Validator)
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.1.Final</version>
</dependency>
7)index2.jsp
說明下,form表單中的name屬性,對應着bean的屬性的話,項目會自動幫我們進行對應配置的,此處我們用bootstrap框架的表單,以及其檢驗表單數據,在<script>
中進行操作。
此處主要是各種校驗功能,關鍵數據一定要放在後臺中校驗,畢竟前端校驗可以通過瀏覽器改變來跳過校驗。所以應該是(前端+後端+數據庫信息)三者加起來進行校驗。此處後端校驗用JSR303
此處主要校驗的內容是:姓名格式是否正確,郵件格式是否正確,新增時姓名是否已存在(可以後用於檢驗用戶名不重複)。index.jsp代碼特別亂,但是還在跟着學習就先不管那麼多,等全部學完後把代碼重新整理下
<%@ 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());
%>
<script type="text/javascript"
src="${ APP_PATH }/static/js/jquery-1.11.1.min.js"></script>
<link rel="stylesheet"
href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<script
src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<!-- 員工添加的模態框,bootstrap的JavaScript插件,在<script>裏寫上事件 -->
<!-- Modal -->
<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">
<!-- 從bootstrap上添加的表單模塊 -->
<form class="form-horizontal">
<div class="form-group">
<label class="col-sm-2 control-label">empName</label>
<div class="col-sm-10">
<!-- name屬性可以讓spring自動配置,要求就是要對應bean的屬性 -->
<input type="text" class="form-control" id="empName_add_input"
placeholder="empName" name="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" class="form-control" id="email_add_input"
placeholder="[email protected]" name="email"> <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="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 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>
<!-- 顯示錶格 -->
<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>department</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;
/*頁面加載完成後,直接發送一個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);
build_page_nav(result);
}
});
}
/*=============解析員工數據,並添加到列表下面,形成完整列表模式框架==========*/
function build_emps_table(result) {
//在構建之前,先清空,不然數據會疊加
$("#emps_table tbody").empty();
//此處要對照JSON數據,獲取到員工的list
var emps = result.extend.pageInfo.list;
//jquery的遍歷,emps爲要遍歷的參數,後面的爲每次遍歷返回的內容;index爲下標,item爲當前的數據
$.each(emps, function(index, item) {
//創建列表
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);
//編輯按鈕,利用jquery添加bootstrap所依賴的class
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方法執行完成後,還是返回原來的元素,所以可以不停使用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();
//找到id=page_info_area的div塊 進行操作
$("#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").empty();
//此處的建議對照之前的index.jsp的html部分的代碼看,不如太作死
/*開始構建 首頁 末頁,第一頁...等元素,最後一次性加進去下面 第一段代碼就完成了
<li><a href="#">首頁</a></li> 這段代碼
*/
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 lastPageLi = $("<li></li>").append(
$("<a></a>").append("末頁").attr("href", "#"));
//判斷能不能點擊下一頁或者末頁
if (result.extend.pageInfo.hasNextPage == false) {
nextPageLi.addClass("disabled");
lastPageLi.addClass("disabled");
} else {
nextPageLi.click(function() {
to_page(result.extend.pageInfo.pageNum + 1);
});
lastPageLi.click(function() {
to_page(result.extend.pageInfo.pages);
})
}
//先把首頁和前一頁圖標加上去
ul.append(firstPageLi).append(prePageLi)
//遍歷頁碼號 第一頁第二頁。。。遍歷給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(lastPageLi);
//把ul加入到nav元素
var navEle = $("<nav></nav>").append(ul);
navEle.appendTo("#page_nav_area");
}
/*============每次新增後,再點開新增原來的內容都沒消除,此方法就是消除上一條新增後框框中的信息===*/
function reset_form(ele) {
//重置內容
$(ele)[0].reset();
//清空樣式,找到該元素下的所有內容裏包含這兩個class的內容,清掉它們
$(ele).find("*").removeClass("has-error has-success");
//找到所有class爲helt-block(提示框所在的一小塊區域),清空內容
$(ele).find(".help-block").text("");
}
/*=============點擊新增按鈕彈出懸浮框,(在“新增”鍵處)============*/
$("#emp_add_modal_btn").click(function() {
//重置表單
reset_form("#empAddModal form");
//發送ajax請求,查出部門信息,顯示在下拉列表中
getDepats();
//彈出框框
$("#empAddModal").modal({
//令懸浮框不會刪除
backdrop : "static"
});
});
/*==============封裝方法:查出總共有幾個部門,然後添加到下拉表中======================*/
function getDepats() {
//每次請求前 先清空數據
$("#dept_add_select").empty();
$.ajax({
url : "${APP_PATH}/depts",
type : "GET",
success : function(result) {
//顯示部門信息在下拉列表中
$.each(result.extend.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();
//bootstrap的內容,在input的父元素上添加如下class
var regName = /(^[a-zA-Z0-9_-]{4,16}$)|(^[\u2E80-\u9FFF]{2,5})/;
if (!regName.test(empName)) {
show_validate_msg("#empName_add_input", "error",
"用戶名格式錯誤(前端校驗)");
return false;
} else {
show_validate_msg("#empName_add_input", "success", "");
}
//校驗郵箱
var email = $("#email_add_input").val();
var regEmail = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/;
if (!regEmail.test(email)) {
//bootstrap的內容,在input的父元素上添加如下class
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("");
} else if ("error" == status) {
$(ele).parent().addClass("has-error");
$(ele).next("span").text(msg);
}
}
/*===========================檢驗員工是否重複,並進行提示========================*/
$("#empName_add_input").change(
function() {
var empName = this.value;
//發送ajax請求是否可用
$.ajax({
url : "${APP_PATH}/checkuser",
data : "empName=" + empName,
type : "POST",
success : function(result) {
//此處code是Msg.java中的屬性
if (result.code == 100) {
show_validate_msg("#empName_add_input",
"success", "用戶名可用");
//如果成功,給保存按鈕的鍵添加個自定義的屬性,用於判斷能不能點下保存
$("#emp_save_btn").attr("ajax-va", "success");
} else {
//傳出的錯誤信息,是在EmployeeController中自定義的va_msg
show_validate_msg("#empName_add_input",
"error", result.extend.va_msg);
$("#emp_save_btn").attr("ajax-va", "error");
}
}
});
});
/*======================點擊按鈕後,就會保存數據,並且實現在這實現後臺檢驗=====================*/
$("#emp_save_btn")
.click(
function() {
//對提交的數據進行校驗
if (!validate_add_form()) {
return false;
}
//1、判斷之前的ajax用戶名是否成功,如果成功,才發送ajax
if ($(this).attr("ajax-va") == "error") {
return false;
}
//2、ajax保存員工
$
.ajax({
url : "${APP_PATH}/emp",
type : "POST",
data : $("#empAddModal form")
.serialize(),
success : function(result) {
//員工保存成功後,判斷返回後臺返回的結果狀態碼(JSR303)
if (result.code == 100) {
//1、關閉模態框;就用bootstrap的方法
$("#empAddModal").modal('hide');
//2、來到最後一頁,顯示保存的數據
//發送ajax請求顯示最後一頁數據即可
//此處利用pagehelper中,如果跳轉的頁面數大,則自動訪問最後一頁
to_page(totalRecord);
} else {
//有哪個字段的錯誤信息就顯示哪個字段的,undefined是沒有錯誤下會自動帶上的信息
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>