阅读本文前,需要先阅读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 */@Repositorypublic class EmployeeDao {    // 通过map集合模拟数据库    private static Map employees = null;    // 静态代码块在类加载时执行,并且只执行一次    static{        employees = new HashMap();        employees.put(1001, new Employee(1001, "E-AA", "aa@163.com", 1));        employees.put(1002, new Employee(1002, "E-BB", "bb@163.com", 1));        employees.put(1003, new Employee(1003, "E-CC", "cc@163.com", 0));        employees.put(1004, new Employee(1004, "E-DD", "dd@163.com", 0));        employees.put(1005, new Employee(1005, "E-EE", "ee@163.com", 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 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组件扫描

在原来的环境中,只扫描控制层组件,现在多了持久层组件,所以要调整扫描包的范围

        

8.1.4、功能清单

功能URL 地址请求方式
访问首页/GET
查询全部数据/employeeGET
跳转到添加数据页面/to/addGET
执行保存/employeePOST
跳转到修改数据页面/to/update/2GET
执行修改/employeePUT
删除/employee/2DELETE

8.2、查询列表功能8.2.1、页面请求示例

查询所有员工的信息

8.2.2、控制器方法示例

    @GetMapping("/employee")    public String getAllEmployee(Model model){        // 获取所有员工的信息        Collection allEmployee = employeeDao.getAll();        // 将所有员工的信息,共享到请求域        model.addAttribute("allEmployee",allEmployee);        // 跳转到列表页面        return "employee_list";    }

8.2.3、列表页面示例

注意:在idea中,某些thymeleaf语法可能会提示错误(红色波浪线),这是误报,可以不用管

employee list
id lastName email gender options
update delete

8.2.4、测试效果

8.3、新增功能8.3.1、页面请求示例

options(add)

8.3.2、视图控制器示例

因为只需要实现页面跳转,没有处理业务的过程,所以可以使用视图控制器实现

8.3.3、新增页面示例

        
employee add
lastName
email
gender male female

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语法中)路径要使用单引号后再使用加号拼接变量

update

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属性的值相等,则选中当前单选框

            
employee update
lastName
email
gender male female

8.4.4、控制器方法示例(执行修改)

    @PutMapping("/employee")    public String updateEmployee(Employee employee){        // 修改员工        employeeDao.save(employee);        // 重定向到查询列表功能        return "redirect:/employee";    }

8.4.5、测试效果

8.5、删除功能8.5.1、页面请求示例

delete
    
    function put() {        // 获取form表单        var form = document.getElementsByTagName("form")[0]        // 将超链接的href属性值赋值给form表单的action属性        // event.target表示当前触发事件的标签        form.action = event.target.href;        // 提交表单        form.submit();        // 阻止超链接的默认行为(跳转)        event.preventDefault();    }

8.5.2、控制器方法示例

    @DeleteMapping("/employee/{id}")    public String deleteEmployee(@PathVariable("id") Integer id){        // 删除员工        employeeDao.delete(id);        // 重定向到查询列表功能        return "redirect:/employee";    }

8.5.3、测试效果