閱讀本文前,需要先閱讀SpringMVC之RESTful概述 8.1、前期工作 8.1.1、創建實體類Employee package org.rain.pojo; import java.io.Serializable; /** * @author liaojy * @date 2023/10/1 ...
閱讀本文前,需要先閱讀SpringMVC之RESTful概述
8.1、前期工作
8.1.1、創建實體類Employee
package org.rain.pojo;
import java.io.Serializable;
/**
* @author liaojy
* @date 2023/10/19 - 21:31
*/
public class Employee implements Serializable {
private Integer id;
private String lastName;
private String email;
//1 male, 0 female
private Integer gender;
public Employee() {
}
public Employee(Integer id, String lastName, String email, Integer gender) {
this.id = id;
this.lastName = lastName;
this.email = email;
this.gender = gender;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", lastName='" + lastName + '\'' +
", email='" + email + '\'' +
", gender=" + gender +
'}';
}
}
8.1.2、創建EmployeeDao模擬操作數據
package org.rain.dao;
import org.rain.pojo.Employee;
import org.springframework.stereotype.Repository;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
* @author liaojy
* @date 2023/10/19 - 21:36
*/
@Repository
public class EmployeeDao {
// 通過map集合模擬資料庫
private static Map<Integer, Employee> employees = null;
// 靜態代碼塊在類載入時執行,並且只執行一次
static{
employees = new HashMap<Integer, Employee>();
employees.put(1001, new Employee(1001, "E-AA", "[email protected]", 1));
employees.put(1002, new Employee(1002, "E-BB", "[email protected]", 1));
employees.put(1003, new Employee(1003, "E-CC", "[email protected]", 0));
employees.put(1004, new Employee(1004, "E-DD", "[email protected]", 0));
employees.put(1005, new Employee(1005, "E-EE", "[email protected]", 1));
}
// 新數據的id
private static Integer initId = 1006;
// 新增或修改
public void save(Employee employee) {
// 參數沒有id表示要執行新增操作
if (employee.getId() == null) {
// 設置新增數據的id,並自增id值為下一次新增數據做準備
employee.setId(initId++);
}
// 更新模擬資料庫的數據
employees.put(employee.getId(), employee);
}
// 查詢所有
public Collection<Employee> getAll(){
return employees.values();
}
// 根據id查詢
public Employee get(Integer id){
return employees.get(id);
}
// 根據id刪除
public void delete(Integer id){
employees.remove(id);
}
}
8.1.3、調整bean組件掃描
在原來的環境中,只掃描控制層組件,現在多了持久層組件,所以要調整掃描包的範圍
<!--在指定的包中,掃描bean組件-->
<context:component-scan base-package="org.rain"></context:component-scan>
8.1.4、功能清單
功能 | URL 地址 | 請求方式 |
---|---|---|
訪問首頁 | / | GET |
查詢全部數據 | /employee | GET |
跳轉到添加數據頁面 | /to/add | GET |
執行保存 | /employee | POST |
跳轉到修改數據頁面 | /to/update/2 | GET |
執行修改 | /employee | PUT |
刪除 | /employee/2 | DELETE |
8.2、查詢列表功能
8.2.1、頁面請求示例
<a th:href="@{/employee}">查詢所有員工的信息</a>
8.2.2、控制器方法示例
@GetMapping("/employee")
public String getAllEmployee(Model model){
// 獲取所有員工的信息
Collection<Employee> allEmployee = employeeDao.getAll();
// 將所有員工的信息,共用到請求域
model.addAttribute("allEmployee",allEmployee);
// 跳轉到列表頁面
return "employee_list";
}
8.2.3、列表頁面示例
註意:在idea中,某些thymeleaf語法可能會提示錯誤(紅色波浪線),這是誤報,可以不用管
<table border="10">
<tr>
<!--表頭合併五列-->
<th colspan="5">employee list</th>
</tr>
<tr>
<th>id</th>
<th>lastName</th>
<th>email</th>
<th>gender</th>
<th>options</th>
</tr>
<!--在thymeleaf語法中,要迴圈一個標簽,只需要在該標簽中添加迴圈屬性即可-->
<tr th:each="employee : ${allEmployee}">
<td th:text="${employee.id}"></td>
<td th:text="${employee.lastName}"></td>
<td th:text="${employee.email}"></td>
<td th:text="${employee.gender}"></td>
<td>
<a href="">update</a>
<a href="">delete</a>
</td>
</tr>
</table>
8.2.4、測試效果
8.3、新增功能
8.3.1、頁面請求示例
<th>options(<a th:href="@{/to/add}">add</a>)</th>
8.3.2、視圖控制器示例
因為只需要實現頁面跳轉,沒有處理業務的過程,所以可以使用視圖控制器實現
<mvc:view-controller path="/to/add" view-name="employee_add"></mvc:view-controller>
8.3.3、新增頁面示例
<form th:action="@{/employee}" method="post">
<!--因為table標簽中的子標簽是固定的,所以要用form標簽包含table標簽-->
<table border="10">
<tr>
<th colspan="2">employee add</th>
</tr>
<tr>
<td>lastName</td>
<td> <input type="text" name="lastName"> </td>
</tr>
<tr>
<td>email</td>
<td> <input type="text" name="email"> </td>
</tr>
<tr>
<td>gender</td>
<td>
<input type="radio" name="gender" value="1">male
<input type="radio" name="gender" value="0">female
</td>
</tr>
<tr>
<td colspan="2"> <input type="submit" value="add"> </td>
</tr>
</table>
</form>
8.3.4、控制器方法示例
註意:直接跳轉到列表頁面會顯示不了數據,因為還沒向請求域共用數據,所以需要先跳轉到查詢列表功能
此外,跳轉要用重定向,而不是用請求轉發;
如果用請求轉發,因為源請求的請求方式是post,所以請求轉發後的請求方式還會是post,這樣就會一直重覆調用insertEmployee方法,直至記憶體耗盡;
如果用重定向,因為重定向的請求方式肯定是get,所以會調用getAllEmployee方法,從而實現查詢列表功能
@PostMapping("/employee")
public String insertEmployee(Employee employee){
// 新增員工
employeeDao.save(employee);
// 重定向到查詢列表功能
return "redirect:/employee";
}
8.3.5、測試效果
8.4、修改功能
8.4.1、頁面請求示例
註意:因為員工id是變數,所以(在thymeleaf語法中)路徑要使用單引號後再使用加號拼接變數
<a th:href="@{'/to/update/'+${employee.id}}">update</a>
8.4.2、控制器方法示例(回顯數據)
@GetMapping("/to/update/{id}")
public String toUpdate(@PathVariable("id") Integer id, Model model){
// 根據id查詢員工信息
Employee employee = employeeDao.get(id);
// 將員工信息共用到請求域
model.addAttribute("employee",employee);
// 跳轉到更新頁面
return "employee_update";
}
8.4.3、更新頁面示例
註意:請求方式和id用了隱藏域;
單選框的回顯,用了th:field的屬性,如果其值和value屬性的值相等,則選中當前單選框
<form th:action="@{/employee}" method="post">
<input type="hidden" name="_method" value="put">
<input type="hidden" name="id" th:value="${employee.id}">
<table border="10">
<tr>
<th colspan="2">employee update</th>
</tr>
<tr>
<td>lastName</td>
<td> <input type="text" name="lastName" th:value="${employee.lastName}"> </td>
</tr>
<tr>
<td>email</td>
<td> <input type="text" name="email" th:value="${employee.email}"> </td>
</tr>
<tr>
<td>gender</td>
<td>
<input type="radio" name="gender" value="1" th:field="${employee.gender}">male
<input type="radio" name="gender" value="0" th:field="${employee.gender}">female
</td>
</tr>
<tr>
<td colspan="2"> <input type="submit" value="update"> </td>
</tr>
</table>
</form>
8.4.4、控制器方法示例(執行修改)
@PutMapping("/employee")
public String updateEmployee(Employee employee){
// 修改員工
employeeDao.save(employee);
// 重定向到查詢列表功能
return "redirect:/employee";
}
8.4.5、測試效果
8.5、刪除功能
8.5.1、頁面請求示例
<a onclick="put()" th:href="@{'/employee/'+${employee.id}}">delete</a>
<form method="post">
<input type="hidden" name="_method" value="delete">
</form>
<script type="text/javascript">
function put() {
// 獲取form表單
var form = document.getElementsByTagName("form")[0]
// 將超鏈接的href屬性值賦值給form表單的action屬性
// event.target表示當前觸發事件的標簽
form.action = event.target.href;
// 提交表單
form.submit();
// 阻止超鏈接的預設行為(跳轉)
event.preventDefault();
}
</script>
8.5.2、控制器方法示例
@DeleteMapping("/employee/{id}")
public String deleteEmployee(@PathVariable("id") Integer id){
// 刪除員工
employeeDao.delete(id);
// 重定向到查詢列表功能
return "redirect:/employee";
}