SpringBoot员工管理项目

环境准备

  • jdk1.8
  • maven 3.3.9
  • SpringBoot 2.1.8

导入静态资源

百度网盘链接

提取码:wrbg

将asserts目录下的css、img、js等静态资源放置static目录下 在这里插入图片描述 将html静态资源放置templates目录下 在这里插入图片描述

创建项目

  • File-New-Project-Spring Initializr快速创建Spring Boot项目,修改Group名,注意Java Version版本的选择为8。
  • 引入依赖,选择Web-Spring Web,Template Engines-Thymeleaf,Lombok,如图所示。在这里插入图片描述

模拟数据库

1. 创建数据库实体类

新建 pojo 包,用来存放实体类

在 pojo 包下创建一个部门表Department和一个员工表Employee 在这里插入图片描述

部门表:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Department {
private Integer id;
private String departmentName;
}
员工表:
@Data
@NoArgsConstructor
public class Employee {
private Integer id;
private String lastName;
private String email;
private Integer gender;//0:女 1:男

private Department department;
private Date birth;

public Employee(Integer id, String lastName, String email, Integer gender, Department department) {
this.id = id;
this.lastName = lastName;
this.email = email;
this.gender = gender;
this.department = department;
//默认的创建日期
this.birth = new Date();
}
}

由于导入了lombok依赖,使用@Data注解即可get属性,@AllArgsConstructor有参构造@NoArgsConstructor无参构造

2. 编写Dao层

模拟数据库,完成对员工的增删改查任务。

部门Dao
@Repository
public class DepartmentDao {
//模拟数据库中的数据
private static Map<Integer, Department> department = null;
static{
department = new HashMap<>();//创建一个部门表

department.put(1, new Department(1, "市场部"));
department.put(2, new Department(2, "教学部"));
department.put(3, new Department(4, "运营部"));

}

//获得所有部门信息
public Collection<Department> getDepartment(){
return department.values();
}
//通过id获得部门
public Department getDepartmentById(int id){
return department.get(id);
}

}
员工Dao
@Repository
public class EmployeeDao {
//模拟数据库中的数据
private static Map<Integer, Employee> employees = null;
//
@Autowired
private DepartmentDao departmentDao;

static{
employees = new HashMap<>();//创建一个部门表
employees.put(101, new Employee(101, "张晓明","vdx342@qq.com", 1, new Department(1, "市场部")));
employees.put(102, new Employee(102, "黄校长", "qas261@162.com",0, new Department(2,"教学部")));
employees.put(103, new Employee(103,"王例子", "edf123261@162.com",0, new Department(3,"运营部")));
employees.put(104, new Employee(104,"安吉拉", "wd561@162.com",1, new Department(4,"运营部")));
}

//主键自增
private static Integer initId = 104;
//增加一个员工
public void addEmployee(Employee emp){
if(emp.getId() == null){
emp.setId(initId++);
}
//emp部门由调用DepartmentDao包中的getDepartmentById()方法得到
emp.setDepartment(departmentDao.getDepartmentById(emp.getDepartment().getId()));
employees.put(emp.getId(), emp);
}

//查询全部员工信息
public Collection<Employee> getAll(){
return employees.values();
}

//通过id查询员工
public Employee getEmpById(Integer id){
return employees.get(id);
}

//删除员工
public void delete(Integer id){
employees.remove(id);
}

}

具体实现

(一) 默认访问首页

在controller类可以使用RequestMapping,浏览器发送 “/” 请求来到 templates 下的 index.html 页面。

@Controller
public class IndexController {
@RequestMapping({"/","/index.html"})
public String index(){
return "index";
}
}

但这样每次都定义一个空方法比较麻烦,在MyMvcConfig 类中写webMvcConfigurer方法使所有组件一起起作用。修改引入的index.html 名为 login.html。

@Configuration
//@EnableWebMvc
public class MyMvcConfig implements WebMvcConfigurer {
//添加视图映射
@Override
public void addViewControllers(ViewControllerRegistry registry){
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");

}
将html文件其中的语法改为Thymeleaf,所有页面的静态资源都需要使用其接管。注意所有html都需要引入Thymeleaf命名空间。
xmlns:th="http://www.thymeleaf.org"
例如,在 index.html在这里插入图片描述 其他页面亦是如此,再次测试访问,正确显示页面

在application.properties修改url路径

server.servlet.context-path=/kuang
运行,显示首页为 在这里插入图片描述

(二)国际化

1)、编写国际化配置文件,抽取页面需要显示的国际化消息

在resources 下新建 i18n 包,包中新建配置文件login.propertieslogin_en_US.properties,自动生成如下形式: 在这里插入图片描述

右键选择Add ... 下方 + 添加新语言,输入zh_CN 自动生成 login_zh_CN.properties 在这里插入图片描述

在 Settings/Preferences 中找到 File Encodings,选为UTF8,并勾选自动转为ascii码。(此次是一个坑,不这样设置后面页面显示会出现乱码。) 在这里插入图片描述 添加属性: 在这里插入图片描述

配置好的文件如图 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

2)、Spring Boot自动配置好了管理国际化资源文件的组件

我们的配置文件可以直接放在类路径下叫messages.properties。现在把配置文件放在i18n下,只需在application.properties下修改包名。

spring.messages.basename=i18n/login

3)、去页面获取国际化的值(#{})

在index.html 文件的相应位置用th:**="#{}"修改 在这里插入图片描述 此时显示页面为 在这里插入图片描述 此时,根据浏览器语言设置的信息即可切换中英文显示页面

4)、点击链接切换国际化

上述实现了登录首页显示为中文,我们在index.html页面中可以看到两个标签

<a class="btn btn-sm">中文</a> <a class="btn btn-sm">English</a> 也就对应着视图中的 在这里插入图片描述 那么我们怎么通过这两个标签实现中英文切换呢?

首先在这两个标签上加上跳转链接并带上相应的参数 在这里插入图片描述

此时点击中文链接,url为 在这里插入图片描述

点击英文链接,显示页面为 在这里插入图片描述

但还没有实现点击链接切换。

先分析一下源码,首先搜索WebMvcAutoConfiguration,可以在其中找到关于一个方法 localeResolver()

@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
public LocaleResolver localeResolver() {
//如果用户配置了,则使用用户配置好的
if (this.mvcProperties.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
return new FixedLocaleResolver(this.mvcProperties.getLocale());
}
//用户没有配置,则使用默认的
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
return localeResolver;
}
再点开默认地区解析器的AcceptHeaderLocaleResolver对象,点击此类查看源码
public class AcceptHeaderLocaleContextResolver implements LocaleContextResolver {
private final List<Locale> supportedLocales = new ArrayList(4);
@Nullable
private Locale defaultLocale;

public AcceptHeaderLocaleContextResolver() {
}
可以发现它继承了LocaleResolver接口,实现了地区解析

类似地,我们只需要编写一个自己的地区解析器,继承LocaleResolver接口,重写其方法即可。

编写区域解析器

在这里插入图片描述 并重写resolveLocale 方法,对应着index.html 文件中请求参数 l - 如果点击中文按钮,则跳转到/index.html(l='zh_CN')页面 - 如果点击English按钮,则跳转到/index.html(l='en_US')页面

public class MyLocalResolver implements LocaleResolver {

//解析请求
@Override
public Locale resolveLocale(HttpServletRequest request) {
//如果获取请求中的语言参数链接,就构造一个自己的
String language = request.getParameter("l");//l对应着index.html文件中的跳转链接

// System.out.println(language);
//如果没有就使用默认
Locale locale = Locale.getDefault();
//如果请求的链接携带了国际化参数,就构造一个自己的
if(!StringUtils.isEmpty(language)){
String[] s = language.split("_");//zh_CN
//国家、地区
locale = new Locale(s[0], s[1]);
}
return locale;
}

@Override
public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {

}
}
注入容器

向容器中注入自定义的国际化组件才能生效

MyMvcConfig 中添加代码

@Bean
public LocaleResolver localeResolver(){
return new MyLocalResolver();
}
重启项目即可实现国际化切换!

点击Engilsh 在这里插入图片描述 点击中文在这里插入图片描述

(三)登录

输入正确用户名密码。点击 登录 按钮即可登录进入后台,即dashboard.html页面。

1)、首先在index.html中添加表单提交地址

并添加name属性方便后面传参。

2)、在controller 包新建LoginController 类

@Controller
public class LoginController {
@RequestMapping("/user/login")
public String login(@RequestParam("username") String username, @RequestParam("password") String password, Model model){
//具体的业务
if("admin".equals(username) && "123".equals(password)){
return "dashboard";
}else{
//消息回显,需要model
model.addAttribute("msg","用户名或密码错误");
return "index";
}
}
}
}

在 index.html 文件中添加键 msg 显示错误提示文本

3)、测试:

当输入正确用户名:admin,正确密码:123 时,进入;当输入错误信息时页面提示。 此时可以登录,但url中暴露了用户信息。编写一个映射,将dashboard 映射到main.html。

MyMvcConfig 类中的重写方法添加新的视图映射,

registry.addViewController("/main.html").setViewName("dashboard");
并将 LoginController 类采取重定向的方式
@Controller
public class LoginController {
@RequestMapping("/user/login")
public String login(@RequestParam("username") String username, @RequestParam("password") String password, Model model, HttpSession httpSession){
//具体的业务
if("admin".equals(username) && "123".equals(password)){
//重定向
return "redirect:/main.html";

}else{
//消息回显,需要model
model.addAttribute("msg","用户名或密码错误");
return "index";
}
}
}
此时再次登录,显示的url 就隐藏了用户信息 但此时发现,直接访问 main.html 就进入了首页,造成安全问题,故需要对一些页面进行拦截。

(四)登录拦截器

用户登录后,将用户信息存入session。 - 如果发现session为空,说明没有登录,需要拦截 - 否则,不需要拦截

在 LoginController 类中将用户信息存入session

@Controller
public class LoginController {
@RequestMapping("/user/login")
public String login(@RequestParam("username") String username, @RequestParam("password") String password, Model model, HttpSession httpSession){
//具体的业务
if("admin".equals(username) && "123".equals(password)){
httpSession.setAttribute("loginUser", username);//拦截器获取此session
//重定向
return "redirect:/main.html";

}else{
//消息回显,需要model
model.addAttribute("msg","用户名或密码错误");
return "index";
}
}
}
在 config 包中新建 LoginHandlerInterceptot 类,实现 HandlerInterceptor接口,并重写 preHandle 方法。
public class LoginHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//登录成功之后应该有用户的session
Object userSession = request.getSession().getAttribute("loginUser");
//userSession为空,说明没有登录,需要拦截
if(userSession == null){
//告诉一个消息
request.setAttribute("msg", "没有权限, 请先登录!");
//再返回到首页
request.getRequestDispatcher("/index.html").forward(request, response);
return false;
}else{
return true;
}
}
}
````
在 `MyMvcConfig` 类中添加拦截器,也就是重写addInterceptors 方法。注意排除登录页面及静态资源。
```java
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns("/","/index.html","/user/login","/css/**","/img/**","/js/**");

}
此时,再直接输入main.html 就会提醒,对此页面进行了拦截。

上两篇分别实现了导入静态资源、首页、国际化登录、登录拦截器

这一篇继续实现员工的增删改查 ### (四)CRUD

一、查—显示员工列表

1、实现点击Customers跳转

为了在dashboard页面点击Customers 实现跳转,添加请求路径 /emps 在templates目录下新建一个包emp,用来放所有关于员工信息的页面,将list.html页面移入该包中

添加 EmployeeController 类,处理 /emps 请求

@Controller
public class EmployeeController {

@Autowired
EmployeeDao employeeDao;

@RequestMapping("/emps")
public String list(Model model){
Collection<Employee> employees = employeeDao.getAll();
model.addAttribute("empl", employees);
return "emp/list";
}
}
注意到 list.html 和 dashboard.html 页面的侧边栏和顶部栏是相同的,可以抽取出来

2. 抽取页面公共部分

在 templates 目录下新建一个commons包,并新建commons.html。利用th:fragment 标签抽取公共部分(顶部导航栏和侧边栏) - 抽取公共片段 th:fragment="copy" - 引入公共片段 th:insert="~{footer :: copy}" {templatename::selector}:模板名::选择器 {templatename::fragmentname}:模板名::片段名

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">

<!--顶部导航栏,利用th:fragment提取出来,命名为topbar-->
<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/#">Company
name</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/#">Sign out</a>
</li>
</ul>
</nav>

<!--侧边栏,利用th:fragment提取出来,命名为sidebar-->
<nav class="col-md-2 d-none d-md-block bg-light sidebar" th:fragment="siderbar">
<div class="sidebar-sticky">
<ul class="nav flex-column">
<li class="nav-item">
<a class="nav-link active" 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-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>
Dashboard <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 class="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>
Customers
</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>
</html>

并在 list.html 和 dashboard.html 中删除原导航栏、侧边栏代码,利用th:replace="~{}" 标签引入抽取之后的
<!--导航栏-->
<div th:replace="~{common/common::topbar}"></div>
<div class="container-fluid">
<div class="row">
<!--侧边栏-->
<div th:replace="~{commons/commons::siderbar}"></div></div>

3、点击Customers 高亮

在 dashboard.html 的侧边栏标签传递参数active为 main.html 同样在 list.html 的侧边栏标签传递参数 active 为 list.html 在 commons.html 利用thymeleaf接收参数active,利用三元运算符判断决定是否高亮 [在这里插入图片描述](https://img-blog.csdnimg.cn/20210309204029985.png 再次重启即实现点击高亮!

4、显示员工列表

在 EmployeeController 中传入了empl,用 th:each 遍历取出 在list.html 中修改,并添加两个标签 编辑 和 删除 在这里插入图片描述 此时可以正确显示 在这里插入图片描述

二、增—实现增加员工

1. 实现页面跳转

在list.html 增加一个“添加页面”按钮,并在EmployeeController类中处理请求。 使用Restful风格,这里通过get方式提交请求。

@GetMapping("/emp")
public String toAddPage(Model model){
//查出所有部门信息
Collection<Department> departments = departmentDao.getDepartment();
//获得所有部门再返回前端
model.addAttribute("departments", departments);
return "emp/addEmp";
}
2. 添加员工页面

点击“添加员工”显示/emp/addEmp.html,在emp包下新建addEmp.html,复制 list.html 的主要内容,并修改部门为显示部门名。

<!--导航栏-->
<div th:replace="~{common/common::topbar}"></div>

<div class="container-fluid">
<div class="row">
<!--侧边栏-->
<div th:replace="~{common/common::sidebar(active='list.html')}"></div>

<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
<!--提交表单,点击添加按钮跳转-->
<form th:action="@{/emp}" method="post">
<div class="form-group">
<label>LastName</label>
<input type="text" name="lastName" class="form-control" placeholder="zhangsan">
</div>
<div class="form-group">
<label>Email</label>
<input type="email" name="email" class="form-control" placeholder="zhangsan@atguigu.com">
</div>
<div class="form-group">
<label>Gender</label><br/>
<div class="form-check form-check-inline">
<input 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 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,与value对应。在controller接收的是一个Employee对象,所以需要提交的是其中的一个属性-->
<select class="form-control" name="department.id">
<!--th:text 显示为部门名 用户接收的是部门id,value为部门id-->
<option th:each="dep:${departments}" th:text="${dep.getDepartmentName()}" th:value="${dep.getId()}"></option>
</select>
</div>
<div class="form-group">
<label>Birth</label>
<input type="text" name="birth" class="form-control" placeholder="zhangsan">
</div>
<button type="submit" class="btn btn-primary">添加</button>
</form>
</main>
</div>
</div>
3. 添加员工

点击“添加”按钮,进行表单提交,发出Post请求,路径仍是"/add",重新跳转到/emps 页面展示全部员工信息。 在这里插入图片描述 在EmployeeController中处理请求。

@PostMapping("/emp")
public String addEmp(Employee employee){
//调用底层业务方法保存员工信息
employeeDao.addEmployee(employee);
return "redirect:/emps";
}

添加之后: 注意在添加日期时要注意日期格式,在 application.properties 中进行时间配置

spring.mvc.date-format=yyyy-MM-dd

三、改—修改员工信息

1. 实现页面跳转

在list.html 增加一个“编辑”按钮,选择需要修改的员工id。

<a class="btn btn-sm btn-primary" th:href="@{/emp/update/}+${em.id}">编辑</a>
在EmployeeController类中处理请求,跳转到修改员工页面。@PathVaribale 获取url中的数据即传入前端选择的员工id。
@GetMapping("/emp/update/{id}")
public String toUpdateEmp(@PathVariable("id") Integer id, Model model){
//查出原来的参数
Employee employee = employeeDao.getEmpById(id);
model.addAttribute("emp", employee);
// //查出所有部门信息
Collection<Department> departments = departmentDao.getDepartment();
//获得所有部门再返回前端
model.addAttribute("departments", departments);
return "emp/update";
}

2. 修改员工页面

点击“编辑”显示/emp/addEmp.html,在emp包下新建update.html,复制 addEmp.html 的主要内容,并添加 th:valueth:checkedth:selected取出员工信息。

<div class="container-fluid">
<div class="row">
<!--侧边栏-->
<div th:replace="~{common/common::sidebar(active='list.html')}"></div>

<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
<!--提交表单,点击添加按钮跳转-->
<form th:action="@{/emp/update}" method="post">
<!--指定修改人的id-->
<input type="hidden" name="id" th:value="${emp.getId()}">

<div class="form-group">
<label>LastName</label>
<input type="text" name="lastName" class="form-control" placeholder="zhangsan" th:value="${emp.getLastName()}">
</div>
<div class="form-group">
<label>Email</label>
<input type="email" name="email" class="form-control" placeholder="zhangsan@atguigu.com" th:value="${emp.getEmail()}">
</div>
<div class="form-group">
<label>Gender</label><br/>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="gender" value="1" th:checked="${emp.getGender()==1}">
<label class="form-check-label"></label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="gender" value="0" th:checked="${emp.getGender()==0}">
<label class="form-check-label"></label>
</div>
</div>
<div class="form-group">
<label>department</label>
<!--这里传入参数是id,与value对应。在controller接收的是一个Employee对象,所以需要提交的是其中的一个属性-->
<select class="form-control" name="department.id">
<!--th:text 显示为部门名 用户接收的是部门id,value为部门id-->
<option th:each="dep:${departments}" th:text="${dep.getDepartmentName()}" th:value="${dep.getId()}" th:selected="${emp.getDepartment().getId()==dep.getId()}"></option>
</select>
</div>
<div class="form-group">
<label>Birth</label>
<input type="text" name="birth" class="form-control" placeholder="zhangsan" th:value="${#dates.format(emp.getBirth(),'yyyy-MM-dd')}">
</div>
<button type="submit" class="btn btn-primary">修改</button>
</form>
</main>
</div>
</div>
如修改 101 员工,修改页面显示为:

3. 修改员工

点击“修改”按钮,进行表单提交,发出Post请求,路径仍是"/emp/update",重新跳转到/emps 页面展示修改后的全部员工信息。 在EmployeeController中处理请求,将修改后的员工信息提交给后台。

@PostMapping("/emp/update")
public String updateEmp(Employee employee){
employeeDao.addEmployee(employee);
return "redirect:/emps";
}

修改后返回"/emps",已成功修改。

四、删—删除员工

在list.html 增加一个“删除”按钮,选择需要删除的员工id。

<a class="btn btn-sm btn-danger" th:href="@{/emp/delete/}+${em.id}">删除</a>
在 EmployeeController 类中处理请求,根据传入id删除员工。
@GetMapping("/emp/delete/{id}")
public String deleteEmp(@PathVariable("id") Integer id){
employeeDao.delete(id);
return "redirect:/emps";
}
进行删除操作,显示更新后的员工信息。

(五)注销用户

在common.html 的导航栏中添加“注销”

<a class="nav-link" th:href="@{/user/logout}">注销</a>

在 LoginController 中处理注销请求,清除session,并返回至首页。

@RequestMapping("/user/logout")
public String logout(HttpSession session){
session.invalidate();
return "redirect:/index.html";
}

重启项目即注销,需重新登录。

------ 本文结束感谢您的阅读 ------