传统 CRUD

1、显示员工列表

① 思路

images

② 代码

[1]配置 SpringMVC 配置文件

images

1
2
3
4
5
6
7
8
9
10
11
<!-- 自动扫描的包 -->
<context:component-scan base-package="com.atguigu.demo.component"/>

<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="viewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>

<!-- 加入SpringMVC标配 -->
<mvc:annotation-driven/>

注意:加入 mvc:annotation-driven 时不要导错名称空间

错误的名称空间是:

xmlns:mvc=”http://www.springframework.org/schema/cache"

正确的名称空间是:

xmlns:mvc=”http://www.springframework.org/schema/mvc"

如果使用了 cache 名称空间,那么 Web 应用启动时会抛出下面异常:

org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from class path resource [spring-mvc.xml];

Caused by: java.lang.NoClassDefFoundError: org/aopalliance/intercept/MethodInterceptor

Caused by: java.lang.ClassNotFoundException: org.aopalliance.intercept.MethodInterceptor

[2]配置 web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
    <servlet>
<!-- 配置SpringMVC的前端控制器:DispatcherServlet -->
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<!-- 使用DispatcherServlet的初始化参数指定Spring配置文件的位置 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>

<!-- 借助load-on-startup标签将Servlet设置为随Web应用一起启动 -->
<load-on-startup>1</load-on-startup>
</servlet>

<!-- 匹配所有请求,使用『/』 -->
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

<!-- 解决字符乱码问题 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>

<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

[3]EmpController 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Controller
public class EmpController {

@Autowired
private EmpService empService;

@RequestMapping("/show/list")
public String showList(Model model) {

// 1.调用EmpService的方法查询数据
List<Employee> employeeList = empService.getEmpList();

// 2.将数据存入模型
model.addAttribute("employeeList", employeeList);

// 3.转发请求,到JSP页面上显示数据
return "emp-list";
}
}

[4]EmpService 代码

1
2
3
4
5
6
7
8
9
10
@Service
public class EmpService {

@Autowired
private EmpDao empDao;

public List<Employee> getEmpList() {
return empDao.getEmpList();
}
}

[5]页面展示数据

(1)导入 JSTL 的 jar 包

images

(2)在页面引入标签库
1
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
(3)JSTL 标签
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<table>
<tr>
<th>员工编号</th>
<td>员工姓名</td>
<td>社会保险号</td>
<td>所属部门</td>
<td colspan="2">操作</td>
</tr>
<c:if test="${empty requestScope.employeeList}">
<tr>
<td colspan="6">抱歉!没有查询到数据!</td>
</tr>
</c:if>
<c:if test="${not empty requestScope.employeeList}">
<c:forEach items="${requestScope.employeeList}" var="employee">
<tr>
<td>${employee.empId}</td>
<td>${employee.empName}</td>
<td>${employee.ssn}</td>
<td>${employee.department.deptName}</td>
<td>删除</td>
<td>编辑</td>
</tr>
</c:forEach>
</c:if>
<tr>
<td colspan="6" style="text-align: center">添加员工数据</td>
</tr>
</table>
(4)编写显示员工列表超链接
1
<a href="${pageContext.request.contextPath}/show/list">显示员工列表</a>

2、删除员工数据

① 思路

[1]删除本身

images

[2]删除之后页面跳转

images

② 代码

[1]编写删除超链接

1
2
3
<a href="${pageContext.request.contextPath}/removeEmp?empId=${employee.empId}"
>删除</a
>

[2]EmpController 代码

1
2
3
4
5
6
7
8
9
10
11
@RequestMapping("/removeEmp")
public String removeEmp(
// 接收请求参数
@RequestParam("empId") String empId) {

// 执行删除
empService.removeEmp(empId);

// 前往结果页面
return "emp-list";
}

[3]EmpService 代码

1
2
3
public void removeEmp(String empId) {
empDao.removeEmp(empId);
}

[4]删除后页面跳转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@RequestMapping("/removeEmp")
public String removeEmp(
// 接收请求参数
@RequestParam("empId") String empId, Model model) {

// 执行删除
empService.removeEmp(empId);

// 前往结果页面
// 方案1:直接返回逻辑视图名称,前往emp-list.jsp
// 问题:到达页面后发现没有数据
// 原因:没有将employeeList数据存入请求域
// return "emp-list";

// 方案2:调用showList()方法
// 问题1:破坏程序的结构
// 问题2:在页面上刷新浏览器会导致再次执行删除操作,浪费系统资源
// return showList(model);

// 方案3:将请求转发到/show/list
// 问题:在页面上刷新浏览器会导致再次执行删除操作,浪费系统资源
// return "forward:/show/list";

// 方案4:将请求重定向到/show/list
return "redirect:/show/list";
}

3、添加员工数据

① 思路

[1]前往添加数据的表单页面

images

[2]提交表单执行保存

images

② 代码

[1]添加员工信息超链接

1
<a href="${pageContext.request.contextPath}/to/add/page">添加员工数据</a>

[2]EmpController 代码

1
2
3
4
5
6
7
8
9
10
11
12
@RequestMapping("/to/add/page")
public String toAddPage(Model model) {

// 1.查询全部部门信息
List<Department> departmentList = empService.getDeptList();

// 2.存入模型
model.addAttribute("departmentList", departmentList);

// 3.返回逻辑视图名称
return "emp-add";
}

[3]EmpService 代码

1
2
3
4
5
6
@Autowired
private DeptDao deptDao;

public List<Department> getDeptList() {
return deptDao.getDeptList();
}

[4]表单页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<form action="${pageContext.request.contextPath}/save/emp" method="post">
员工姓名:<input type="text" name="empName" /><br />
社会保险号:<input type="text" name="ssn" /><br />
所属部门:
<select name="department.deptId">
<c:forEach items="${requestScope.departmentList}" var="dept">
<option value="${pageScope.dept.deptId}">
${pageScope.dept.deptName}
</option>
</c:forEach>
</select>
<br />
<button type="submit">保存</button>
</form>

[5]EmpController 代码

1
2
3
4
5
6
7
@RequestMapping("/save/emp")
public String saveEmp(Employee employee) {

empService.saveEmp(employee);

return "redirect:/show/list";
}

[6]EmpService 代码

1
2
3
public void saveEmp(Employee employee) {
empDao.saveEmp(employee);
}

4、更新员工数据

① 思路

[1]前往更新数据的表单页面

images

[2]提交表单执行更新

images

② 代码

[1]编辑员工信息超链接

1
2
3
<a href="${pageContext.request.contextPath}/editEmp?empId=${employee.empId}"
>编辑</a
>

[2]EmpController 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@RequestMapping("/editEmp")
public String toEditPage(@RequestParam("empId") String empId, Model model) {

// 1.根据empId查询对应Employee对象
Employee employee = empService.getEmpById(empId);

// 2.将Employee对象存入模型
model.addAttribute("employee", employee);

// 3.查询全部的部门信息
List<Department> deptList = empService.getDeptList();

// 4.将deptList存入模型
model.addAttribute("deptList", deptList);

return "emp-edit";
}

[3]EmpService 代码

1
2
3
public Employee getEmpById(String empId) {
return empDao.getEmpById(empId);
}

[4]表单页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<form action="${pageContext.request.contextPath}/update/emp" method="post">
<input type="hidden" name="empId" value="${requestScope.employee.empId}" />
<input type="hidden" name="ssn" value="${requestScope.employee.ssn}" />

员工姓名:<input
type="text"
name="empName"
value="${requestScope.employee.empName}"
/><br />
社会保险号: ${requestScope.employee.ssn}<br />
所属部门:
<!-- 下拉列表回显:让部门列表中在页面一打开时就显示当前员工所属部门 -->
<!-- 1、下拉列表设置默认被选中。给option标签设置selected="selected"属性。 -->
<!-- 2、需要找到那个设置selected="selected"属性的option标签。 -->
<!-- 3、将当前部门的deptId和员工的deptId进行比较 -->
<select name="department.deptId">
<c:forEach items="${requestScope.deptList}" var="dept">
<!-- 将遍历得到的deptId和员工的deptId进行比较 -->
<c:if
test="${requestScope.employee.department.deptId == pageScope.dept.deptId}"
>
<!-- 二者相等时设置option被选中 -->
<option value="${pageScope.dept.deptId}" selected="selected">
${pageScope.dept.deptName}
</option>
</c:if>
<c:if
test="${requestScope.employee.department.deptId != pageScope.dept.deptId}"
>
<!-- 二者不相等时不设置option被选中 -->
<option value="${pageScope.dept.deptId}">
${pageScope.dept.deptName}
</option>
</c:if>
</c:forEach>
</select>
<br />
<button type="submit">更新</button>
</form>

[5]EmpController 代码

1
2
3
4
5
6
7
@RequestMapping("/update/emp")
public String updateEmp(Employee employee) {

empService.updateEmp(employee);

return "redirect:/show/list";
}

[6]EmpService 代码

1
2
3
public void updateEmp(Employee employee) {
empDao.updateEmp(employee);
}

5、用来测试的数据

1、实体类

①Department

1
2
private String deptId;
private String deptName;

②Employee

1
2
3
4
private String empId;
private String empName;
private String ssn;
private Department department;

2、Dao

①DeptDao

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package com.atguigu.demo.component.dao;

import com.atguigu.demo.entity.Department;
import org.springframework.stereotype.Repository;

import java.util.*;

@Repository
public class DeptDao {

private static Map<String, Department> dataMap;
private static Map<String, Department> namedMap;

static {
dataMap = new HashMap<>();
namedMap = new HashMap<>();

Department
department = new Department(UUID.randomUUID().toString(), "市场部");
dataMap.put(department.getDeptId(), department);
namedMap.put(department.getDeptName(), department);

department = new Department(UUID.randomUUID().toString(), "销售部");
dataMap.put(department.getDeptId(), department);
namedMap.put(department.getDeptName(), department);

department = new Department(UUID.randomUUID().toString(), "行政部");
dataMap.put(department.getDeptId(), department);
namedMap.put(department.getDeptName(), department);

department = new Department(UUID.randomUUID().toString(), "人事部");
dataMap.put(department.getDeptId(), department);
namedMap.put(department.getDeptName(), department);

department = new Department(UUID.randomUUID().toString(), "技术部");
dataMap.put(department.getDeptId(), department);
namedMap.put(department.getDeptName(), department);

department = new Department(UUID.randomUUID().toString(), "公关部");
dataMap.put(department.getDeptId(), department);
namedMap.put(department.getDeptName(), department);

}

public static Department getDeptByName(String deptName) {
return namedMap.get(deptName);
}

public static Department getDeptById(String uuid) {
return dataMap.get(uuid);
}

public List<Department> getDeptList() {
return new ArrayList<>(dataMap.values());
}
}

②EmpDao

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package com.atguigu.demo.component.dao;

import com.atguigu.demo.entity.Department;
import com.atguigu.demo.entity.Employee;
import org.springframework.stereotype.Repository;

import java.util.*;

@Repository
public class EmpDao {

private static Map<String, Employee> dataMap;

static {
dataMap = new HashMap<>();

String empId = UUID.randomUUID().toString();
dataMap.put(empId, new Employee(empId, "乔峰", "SSN001", DeptDao.getDeptByName("市场部")));

empId = UUID.randomUUID().toString();
dataMap.put(empId, new Employee(empId, "虚竹", "SSN002", DeptDao.getDeptByName("市场部")));

empId = UUID.randomUUID().toString();
dataMap.put(empId, new Employee(empId, "段誉", "SSN003", DeptDao.getDeptByName("市场部")));

empId = UUID.randomUUID().toString();
dataMap.put(empId, new Employee(empId, "鸠摩智", "SSN004", DeptDao.getDeptByName("技术部")));

empId = UUID.randomUUID().toString();
dataMap.put(empId, new Employee(empId, "萧远山", "SSN005", DeptDao.getDeptByName("技术部")));

empId = UUID.randomUUID().toString();
dataMap.put(empId, new Employee(empId, "慕容复", "SSN006", DeptDao.getDeptByName("技术部")));

empId = UUID.randomUUID().toString();
dataMap.put(empId, new Employee(empId, "段正淳", "SSN007", DeptDao.getDeptByName("公关部")));

empId = UUID.randomUUID().toString();
dataMap.put(empId, new Employee(empId, "段延庆", "SSN008", DeptDao.getDeptByName("公关部")));

empId = UUID.randomUUID().toString();
dataMap.put(empId, new Employee(empId, "丁春秋", "SSN009", DeptDao.getDeptByName("销售部")));

empId = UUID.randomUUID().toString();
dataMap.put(empId, new Employee(empId, "无崖子", "SSN010", DeptDao.getDeptByName("人事部")));

empId = UUID.randomUUID().toString();
dataMap.put(empId, new Employee(empId, "慕容博", "SSN011", DeptDao.getDeptByName("人事部")));
}

public void saveEmp(Employee employee) {

String empId = UUID.randomUUID().toString();
employee.setEmpId(empId);

String deptId = employee.getDepartment().getDeptId();
Department department = DeptDao.getDeptById(deptId);
employee.setDepartment(department);

dataMap.put(empId, employee);
}

public void removeEmp(String empId) {
dataMap.remove(empId);
}

public void updateEmp(Employee employee) {

String deptId = employee.getDepartment().getDeptId();
Department department = DeptDao.getDeptById(deptId);
employee.setDepartment(department);

dataMap.put(employee.getEmpId(), employee);
}

public Employee getEmpById(String empId) {
return dataMap.get(empId);
}

public List<Employee> getEmpList() {
return new ArrayList<>(dataMap.values());
}
}

3、解决字符乱码问题

配置 web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>

<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>