5.4 员工管理系统之CRUD、错误页面以及注销功能
一.员工信息列表展示
1.步骤:
-
提取公共页面
-
编写控制器
-
列表循环展示
2.提取公共页面
(1)在template文件夹下建立common文件夹添加文件commons.html,将公共部分抽取出来
-
使用 th:fragment="topbar" , th:fragment="sidebar" 将代码块生成片段
-
其中 <a th:class="${active == 'main.html' ? 'nav-link active' : 'nav-link'}" th:href="@{/main.html}"> 和
<a th:class="${active == 'list.html' ? 'nav-link active' : 'nav-link'}" th:href="@{/emps}"> 目的是从其他页面调用公共页面的片段可以传递参数,此处参数是为了高亮显示,如果用户点击首页则首页列表项显示高亮,如果用户点击员工管理页则其显示为高亮
<!--顶部导航栏--> <nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0" th:fragment="topbar"> <a class="navbar-brand col-sm-3 col-md-2 mr-0" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#" th:text="${session.loginUser}"></a> <input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search"> <ul class="navbar-nav px-3"> <li class="nav-item text-nowrap"> <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">注销</a> </li> </ul> </nav> <!--侧边栏--> <nav class="col-md-2 d-none d-md-block bg-light sidebar" th:fragment="sidebar"> <div class="sidebar-sticky"> <ul class="nav flex-column"> <li class="nav-item"> <a th:class="${active == 'main.html' ? 'nav-link active' : 'nav-link'}" th:href="@{/main.html}"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-home"> <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path> <polyline points="9 22 9 12 15 12 15 22"></polyline> </svg> 首页 <span class="sr-only">(current)</span> </a> </li> <li class="nav-item"> <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file"> <path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path> <polyline points="13 2 13 9 20 9"></polyline> </svg> Orders </a> </li> <li class="nav-item"> <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-shopping-cart"> <circle cx="9" cy="21" r="1"></circle> <circle cx="20" cy="21" r="1"></circle> <path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path> </svg> Products </a> </li> <li class="nav-item"> <a th:class="${active == 'list.html' ? 'nav-link active' : 'nav-link'}" th:href="@{/emps}"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-users"> <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path> <circle cx="9" cy="7" r="4"></circle> <path d="M23 21v-2a4 4 0 0 0-3-3.87"></path> <path d="M16 3.13a4 4 0 0 1 0 7.75"></path> </svg> 员工管理 </a> </li> <li class="nav-item"> <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-bar-chart-2"> <line x1="18" y1="20" x2="18" y2="10"></line> <line x1="12" y1="20" x2="12" y2="4"></line> <line x1="6" y1="20" x2="6" y2="14"></line> </svg> Reports </a> </li> <li class="nav-item"> <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-layers"> <polygon points="12 2 2 7 12 12 22 7 12 2"></polygon> <polyline points="2 17 12 22 22 17"></polyline> <polyline points="2 12 12 17 22 12"></polyline> </svg> Integrations </a> </li> </ul> <h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted"> <span>Saved reports</span> <a class="d-flex align-items-center text-muted" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-plus-circle"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="16"></line><line x1="8" y1="12" x2="16" y2="12"></line></svg> </a> </h6> <ul class="nav flex-column mb-2"> <li class="nav-item"> <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file-text"> <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path> <polyline points="14 2 14 8 20 8"></polyline> <line x1="16" y1="13" x2="8" y2="13"></line> <line x1="16" y1="17" x2="8" y2="17"></line> <polyline points="10 9 9 9 8 9"></polyline> </svg> Current month </a> </li> <li class="nav-item"> <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file-text"> <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path> <polyline points="14 2 14 8 20 8"></polyline> <line x1="16" y1="13" x2="8" y2="13"></line> <line x1="16" y1="17" x2="8" y2="17"></line> <polyline points="10 9 9 9 8 9"></polyline> </svg> Last quarter </a> </li> <li class="nav-item"> <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file-text"> <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path> <polyline points="14 2 14 8 20 8"></polyline> <line x1="16" y1="13" x2="8" y2="13"></line> <line x1="16" y1="17" x2="8" y2="17"></line> <polyline points="10 9 9 9 8 9"></polyline> </svg> Social engagement </a> </li> <li class="nav-item"> <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file-text"> <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path> <polyline points="14 2 14 8 20 8"></polyline> <line x1="16" y1="13" x2="8" y2="13"></line> <line x1="16" y1="17" x2="8" y2="17"></line> <polyline points="10 9 9 9 8 9"></polyline> </svg> Year-end sale </a> </li> </ul> </div> </nav>
(2)在dashboard.html和list.html中使用片段:th:replace="~{xxx}"
-
向公共部分传递参数:使用小括号包含,中间使用键值对赋值 (active='main.html') ,此处active目的是被点到的列表项显示高亮
<!--顶部导航栏--> <div th:replace="~{common/commons::topbar}"></div> <!--侧边栏--> <div th:replace="~{common/commons::sidebar(active='main.html')}"></div>
3.编写控制器
添加EmployeeController.java
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import ustc.wzh.dao.EmployeeDao; import ustc.wzh.pojo.Employee; import java.util.Collection; @Controller public class EmployeeController { @Autowired EmployeeDao employeeDao; //查询所有员工,返回列表页面 @GetMapping("/emps") public String list(Model model){ Collection<Employee> employees = employeeDao.getAll(); //将结果放在请求中 model.addAttribute("emps",employees); return "emp/list"; } }
4.列表循环展示
-
Thymeleaf的循环: th:each="emp:${emps}" ,emps为后台传递来的数据,emp为循环变量
-
Thymeleaf自带的日期处理工具: th:text="${#dates.format(emp.birth,'yyyy-MM-dd HH:mm')}"
1 <div class="table-responsive"> 2 <table class="table table-striped table-sm"> 3 <thead> 4 <tr> 5 <th>id</th> 6 <th>lastName</th> 7 <th>email</th> 8 <th>gender</th> 9 <th>department</th> 10 <th>birth</th> 11 </tr> 12 </thead> 13 <tbody> 14 <tr th:each="emp:${emps}"> 15 <td th:text="${emp.id}"></td> 16 <td>[[${emp.lastName}]]</td> 17 <td th:text="${emp.email}"></td> 18 <td th:text="${emp.gender==0?'女':'男'}"></td> 19 <td th:text="${emp.department.departmentName}"></td> 20 <!--<td th:text="${emp.birth}"></td>--> 21 <!--使用时间格式化工具--> 22 <td th:text="${#dates.format(emp.birth,'yyyy-MM-dd HH:mm')}"></td> 23 24 <!--操作--> 25 <td> 26 <button class="btn btn-sm btn-primary">编辑</button> 27 <button class="btn btn-sm btn-danger">删除</button> 28 </td> 29 </tr> 30 </tbody> 31 </table> 32 </div>
二.添加员工信息
1.步骤:
-
添加按钮用于跳转到添加员工信息页面
-
编写员工信息添加页面
-
添加控制器方法
-
配置文件中修改日期格式
2.添加按钮用于跳转到添加员工信息页面
-
th:href="@{/emp}" 默认为get请求跳转到 @GetMapping("/emp") 方法中
<!--添加员工按钮--> <h2> <a class="btn btn-sm btn-success"th:href="@{/emp}">添加员工</a></h2>
3.编写员工信息添加页面
-
th:action="@{/emp}" method="post" 使用post方法跳转到 @PostMapping("/emp") 方法中
-
需要提交的信息需要name属性
-
部门显示内容使用部门名称,value为部门id,还要thymeleaf的循环表达式:
th:each="dept:${departments}" th:text="${dept.departmentName}" th:value="${dept.id}" -
部门提交时使用部门id: name="department.id"
1 <h2>添加员工</h2> 2 <form th:action="@{/emp}" method="post"> 3 <div class="form-group"> 4 <label>LastName</label> 5 <input type="text" name="lastName" class="form-control" placeholder="kuangshen"> 6 </div> 7 <div class="form-group"> 8 <label>Email</label> 9 <input type="email" name="email" class="form-control" placeholder="24736743@qq.com"> 10 </div> 11 <div class="form-group"> 12 <label>Gender</label><br/> 13 <div class="form-check form-check-inline"> 14 <input class="form-check-input" type="radio" name="gender" value="1"> 15 <label class="form-check-label">男</label> 16 </div> 17 <div class="form-check form-check-inline"> 18 <input class="form-check-input" type="radio" name="gender" value="0"> 19 <label class="form-check-label">女</label> 20 </div> 21 </div> 22 <div class="form-group"> 23 <label>department</label> 24 <!--提交的是部门的ID--> 25 <select class="form-control" name="department.id"> 26 <option th:each="dept:${departments}" th:text="${dept.departmentName}" th:value="${dept.id}"></option> 27 </select> 28 </div> 29 <div class="form-group"> 30 <label>Birth</label> 31 <input type="text" name="birth" class="form-control" placeholder="kuangstudy"> 32 </div> 33 <button type="submit" class="btn btn-primary">添加</button> 34 </form>
4.添加控制器方法
- 使用RestFul风格提交方式 @PostMapping("/emp") , @GetMapping("/emp")
1 @Autowired 2 DepartmentDao departmentDao; 3 4 //跳转到员工添加页面 5 @GetMapping("/emp") 6 public String toAddPage(Model model){ 7 //查出所有的部门,提供选择 8 Collection<Department> departments = departmentDao.getDepartments(); 9 model.addAttribute("departments",departments); 10 return "emp/add"; 11 } 12 13 //员工添加功能 14 //接收前端传递的参数,自动封装成为对象[要求前端传递的参数名,和属性名一致] 15 @PostMapping("/emp") 16 public String addEmp(Employee employee){ 17 System.out.println(employee); 18 employeeDao.save(employee); //保存员工信息 19 //回到员工列表页面,可以使用redirect或者forward 20 return "redirect:/emps"; 21 }
5.配置文件中修改日期格式
-
一旦修改就不能使用原来的yyyy/MM/dd的方式提交
# 设置日期格式
spring.mvc.date-format=yyyy-MM-dd
三.员工信息修改
1.步骤:
-
修改编辑按钮
-
添加修改页面
-
添加控制器方法
-
修改日期格式
2.修改编辑按钮
-
跳转路径 th:href="@{/emp/}+${emp.id}" ,Restful风格的参数传递
<a class="btn btn-sm btn-primary" th:href="@{/emp/}+${emp.id}">编辑</a>
-
官网文档推荐 th:href="@{/emp/{id}(id=${emp.id})}"
<a class="btn btn-sm btn-primary" th:href="@{/emp/{id}(id=${emp.id})}">编辑</a>
3.添加修改页面
-
th:action="@{/updateEmp}" method="post" ,跳转路径和post提交方式
-
type="hidden" th:value="${emp.id}" ,隐藏值传回id值
-
th:value="${emp.getLastName()}" ,input标签填充值
-
th:checked="${emp.gender==1}" ,判断选择哪一个单选框
-
th:selected="${dept.getId() == emp.getDepartment().getId()}" ,获得下拉列表中的值
-
th:value="${#dates.format(emp.birth,'yyyy-MM-dd HH:mm:ss')}" ,设置日期值
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4"> <h2>修改员工信息</h2> <form th:action="@{/updateEmp}" method="post"> <input name="id" type="hidden" class="form-control" th:value="${emp.id}"> <div class="form-group"> <label>LastName</label> <input th:value="${emp.getLastName()}" type="text" name="lastName" class="form-control" placeholder="kuangshen"> </div> <div class="form-group"> <label>Email</label> <input th:value="${emp.getEmail()}" type="email" name="email" class="form-control" placeholder="24736743@qq.com"> </div> <div class="form-group"> <label>Gender</label><br/> <div class="form-check form-check-inline"> <input th:checked="${emp.gender==1}" class="form-check-input" type="radio" name="gender" value="1"> <label class="form-check-label">男</label> </div> <div class="form-check form-check-inline"> <input th:checked="${emp.gender==0}" class="form-check-input" type="radio" name="gender" value="0"> <label class="form-check-label">女</label> </div> </div> <div class="form-group"> <label>department</label> <!--提交的是部门的ID--> <select class="form-control" name="department.id"> <option th:selected="${dept.getId() == emp.getDepartment().getId()}" th:each="dept:${departments}" th:text="${dept.departmentName}" th:value="${dept.id}"></option> </select> </div> <div class="form-group"> <label>Birth</label> <input type="text" name="birth" class="form-control" th:value="${#dates.format(emp.birth,'yyyy-MM-dd HH:mm:ss')}" placeholder="kuangstudy"> </div> <button type="submit" class="btn btn-primary">修改</button> </form> </main>
4.添加控制器方法
//跳转到员工修改页面 @GetMapping("/emp/{id}") public String toUpdateEmp(@PathVariable("id") Integer id, Model model){ //根据id查出来员工 Employee employee = employeeDao.get(id); //将员工信息返回页面 model.addAttribute("emp",employee); //查出所有的部门,提供修改选择 Collection<Department> departments = departmentDao.getDepartments(); model.addAttribute("departments",departments); return "emp/update"; } // 修改员工信息 @PostMapping("/updateEmp") public String updateEmp(Employee employee){ employeeDao.save(employee); //回到员工列表页面 return "redirect:/emps"; }
5.修改日期格式
# 设置日期格式
spring.mvc.date-format=yyyy-MM-dd HH:mm:ss
四.员工信息删除
1.步骤:
-
添加删除按钮
-
添加控制器方法
2.添加删除按钮
<a class="btn btn-sm btn-danger" th:href="@{/delEmp/{id}(id=${emp.id})}">删除</a>
3.添加控制器方法
@GetMapping("/delEmp/{id}") public String delEmp(@PathVariable("id") Integer id){ employeeDao.delete(id); return "redirect:/emps"; }
五.错误页面
1.在template目录下添加error文件夹
-
添加404.html等错误页面即可,springboot会自动定位
六.注销功能
1.步骤:
-
编写注销按钮
-
控制器添加方法
2.编写注销按钮
<a class="nav-link" th:href="@{/user/loginOut}">注销</a>
3.控制器添加方法
-
在LoginController中添加方法
@GetMapping("/user/loginOut") public String loginOut(HttpSession session){ session.invalidate(); return "redirect:/index.html"; }