完整项目地址:https://download.csdn.net/download/lijunhcn/88430276
基于SpringBoot+Mybatis+Thymeleaf架构实现的员工管理系统(源码+数据库)
SpringBoot整合CRUD实现员工管理案例,将Mybatis整合到原项目中,加入了数据库,添加了日期选项的控件。
环境要求
- JDK8以上
- IDEA
- MySQL8
- Maven3
- 需要熟练掌握MySQL数据库,SpringBoot及MyBatis知识,简单的前端知识;
数据库环境
创建案例所使用的数据库
CREATE DATABASE `employee`;
USE `employee`;
创建登陆用户数据表
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(10) NOT NULL,
`user_name` varchar(255) NOT NULL COMMENT '用户名',
`password` varchar(255) NOT NULL COMMENT '密码',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
INSERT INTO `user` VALUES (1, 'admin', '123456');
创建部门信息的数据库表
DROP TABLE IF EXISTS `department`;
CREATE TABLE `department` (
`id` int(10) NOT NULL,
`department_name` varchar(255) NOT NULL COMMENT '部门名称',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
BEGIN;
INSERT INTO `department` VALUES (1, '市场部');
INSERT INTO `department` VALUES (2, '技术部');
INSERT INTO `department` VALUES (3, '销售部');
INSERT INTO `department` VALUES (4, '客服部');
INSERT INTO `department` VALUES (5, '公关部');
COMMIT;
创建存放员工信息的数据库表
DROP TABLE IF EXISTS `employee`;
CREATE TABLE `employee` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`employee_name` varchar(255) NOT NULL COMMENT '员工姓名',
`email` varchar(255) NOT NULL COMMENT '员工邮箱',
`gender` int(2) NOT NULL COMMENT '员工性别',
`department_id` int(10) NOT NULL COMMENT '部门编号',
`date` date NOT NULL COMMENT '入职日期',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;
BEGIN;
INSERT INTO `employee` VALUES (1, '张三', '[email protected]', 0, 1, '2020-05-12');
INSERT INTO `employee` VALUES (2, '李四', '[email protected]', 1, 2, '2020-05-05');
INSERT INTO `employee` VALUES (3, '王五', '[email protected]', 0, 3, '2020-05-15');
INSERT INTO `employee` VALUES (4, '赵六', '[email protected]', 1, 4, '2020-04-21');
INSERT INTO `employee` VALUES (5, '田七', '[email protected]', 0, 3, '2020-05-14');
INSERT INTO `employee` VALUES (10, '王伟', '[email protected]', 1, 3, '2020-05-08');
INSERT INTO `employee` VALUES (11, '张伟', '[email protected]', 1, 2, '2020-05-11');
INSERT INTO `employee` VALUES (12, '李伟', '[email protected]', 1, 3, '2020-05-18');
COMMIT;
基本环境搭建
- 新建Spring项目, 添加Lombok,Spring Web,Thymeleaf,Mybatis,MySQL Driver的支持
- 相关的pom依赖 org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-web org.mybatis.spring.boot mybatis-spring-boot-starter 2.1.2 mysql mysql-connector-java runtime org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test org.junit.vintage junit-vintage-engine
- 建立基本结构和配置框架
com/
|-- godfrey |-- config |-- controller |-- dto |-- mapper |-- pojo |-- service
- application.yml里配置数据库连接信息及Mapper映射文件信息spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/employee?useSSL=true&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8 username: employee password: employee123 thymeleaf: cache: false messages: basename: i18n.loginmybatis: type-aliases-package: com.godfrey.pojo mapper-locations: classpath:com.godfrey.mapper/*Mapper.xml configuration: map-underscore-to-camel-case: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
- 测试数据库连接package com.godfrey;import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest;import javax.sql.DataSource; import java.sql.Connection; import java.sql.SQLException;@SpringBootTest class ApplicationTests {
@AutowiredDataSource dataSource;@Testvoid contextLoads() throws SQLException { System.out.println("数据源>>>>>>" + dataSource.getClass()); Connection connection = dataSource.getConnection(); System.out.println("连接>>>>>>>>>" + connection); System.out.println("连接地址>>>>>" + connection.getMetaData().getURL()); connection.close();}
}
查看输出结果,数据库配置ok
创建pojo实体类
- 创建User实体package com.godfrey.pojo;import lombok.Data;/**- description : 登录验证实体类- @author godfrey- @since 2020-05-26 */ @Data public class User { private Integer id; private String userName; private String password; }
- 创建Department实体package com.godfrey.pojo;import lombok.Data;/**- description : 部门实体类- @author godfrey- @since 2020-05-26 */ @Data public class Department { private Integer id; private String departmentName; }
- 创建Employee实体package com.godfrey.pojo;import lombok.Data;import java.sql.Date;/**- description : 员工实体类- @author godfrey- @since 2020-05-26 */ @Data public class Employee { private Integer id; private String employeeName; private String email; private Integer gender; //0:女 1:男 private Date date; private Integer departmentId; }
- 创建EmployeeDTO实体package com.godfrey.dto;import lombok.Data;import java.sql.Date;/**- description : EmployeeDTO- @author godfrey- @since 2020-05-26 */ @Data public class EmployeeDTO { private Integer id; private String employeeName; private String email; private Integer gender; private String departmentName; private Date date; }
Mapper层
文件存放目录:
com.godfrey.mapper 相关接口
resources/com.godfrey.mapper 相关mapper.xml
- 编写User的Mapper接口:UserMapperpackage com.godfrey.mapper;import com.godfrey.pojo.User; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository;/**- description : 登录验证查询Mapper- @author godfrey- @since 2020-05-26 */ @Mapper @Repository public interface UserMapper { User selectPasswordByName(@Param(“userName”) String userName, @Param(“password”) String password); }
- 编写接口对应的Mapper.xml文件:UserMapper.xml <?xml version="1.0" encoding="UTF-8" ?> select * from employee.user where user_name = #{userName} and password = #{password};
- 编写Department的Mapper接口:DepaertmentMapperpackage com.godfrey.mapper;import com.godfrey.pojo.Department; import org.apache.ibatis.annotations.Mapper; import org.springframework.stereotype.Repository;import java.util.List;/**- description : 部门Mapper- @author godfrey- @since 2020-05-26 */ @Mapper @Repository public interface DepartmentMapper {List selectAllDepartment(); }
- 编写接口对应的Mapper.xml文件:DepaertmentMapper.xml <?xml version="1.0" encoding="UTF-8" ?> select * from department;
- 编写Employee的Mapper接口:EmployeeMapperpackage com.godfrey.mapper;import com.godfrey.dto.EmployeeDTO; import com.godfrey.pojo.Employee; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository;import java.util.List;/**- description : 员工Mapper- @author godfrey- @since 2020-05-26 */ @Mapper @Repository public interface EmployeeMapper { //查询全部员工信息 List selectAllEmployeeDTO();//根据id查询员工信息 Employee selectEmployeeById(@Param(“id”) Integer id);//添加一个员工信息 int addEmployee(Employee employee);//修改一个员工信息 int updateEmployee(Employee employee);//根据id删除员工信息 int deleteEmployee(@Param(“id”) Integer id); }
- 编写接口对应的Mapper.xml文件:EmployeeMapper.xml <?xml version="1.0" encoding="UTF-8" ?>
<resultMap id="EmployeeDTO" type="com.godfrey.dto.EmployeeDTO"> <id column="id" jdbcType="INTEGER" property="id"/> <result column="employee_name" jdbcType="VARCHAR" property="employeeName"/> <result column="email" jdbcType="VARCHAR" property="email"/> <result column="gender" jdbcType="INTEGER" property="gender"/> <result column="department_name" jdbcType="VARCHAR" property="departmentName"/> <result column="date" jdbcType="DATE" property="date"/></resultMap><select id="selectAllEmployeeDTO" resultMap="EmployeeDTO"> select e.id, e.employee_name, e.email, e.gender, d.department_name, e.date from employee e, department d where e.department_id = d.id;</select><select id="selectEmployeeById" resultType="Employee"> select * from employee where id = #{id}</select><insert id="addEmployee" parameterType="Employee"> insert into employee (id, employee_name, email, gender, department_id, date) values (#{id}, #{employeeName}, #{email}, #{gender}, #{departmentId}, #{date})</insert><update id="updateEmployee" parameterType="Employee"> update employee set employee_name=#{employeeName}, email=#{email}, gender=#{gender}, department_id=#{departmentId}, date=#{date} where id = #{id}</update><delete id="deleteEmployee" parameterType="int"> delete from employee where id = #{id}</delete>
Service层
com.wangqiang.service
- EmployeeService接口:package com.godfrey.service;import com.godfrey.dto.EmployeeDTO; import com.godfrey.pojo.Employee;import java.util.List;/**- description : 员工业务层接口- @author godfrey- @since 2020-05-26 */ public interface EmployeeService { //查询全部员工信息 List selectAllEmployeeDTO(); //根据id查询员工信息 Employee selectEmployeeById(int id); //添加一个员工信息 int addEmployee(Employee employee); //修改一个员工信息 int updateEmployee(Employee employee); //根据id删除员工信息 int deleteEmployee(int id); }
- EmployeeServiceImpl实现类:package com.godfrey.service.impl;import com.godfrey.dto.EmployeeDTO; import com.godfrey.mapper.EmployeeMapper; import com.godfrey.pojo.Employee; import com.godfrey.service.EmployeeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;import java.util.List;/**- description : 员工业务层实现类- @author godfrey- @since 2020-05-26 */ @Service public class EmployeeServiceImpl implements EmployeeService { @Autowired private EmployeeMapper employeeMapper;@Override public List selectAllEmployeeDTO() { return employeeMapper.selectAllEmployeeDTO(); }@Override public Employee selectEmployeeById(int id) { return employeeMapper.selectEmployeeById(id); }@Override public int addEmployee(Employee employee) { return employeeMapper.addEmployee(employee); }@Override public int updateEmployee(Employee employee) { return employeeMapper.updateEmployee(employee); }@Override public int deleteEmployee(int id) { return employeeMapper.deleteEmployee(id); } }
- DepartmentService接口package com.godfrey.service;import com.godfrey.pojo.Department;import java.util.List;/**- description : DepartmentService- @author godfrey- @since 2020-05-27 */ public interface DepartmentService { List selectAllDepartment(); }
- DepartmentImpl实现类:package com.godfrey.service.impl;/**- description : DepartmentServiceImpl- @author godfrey- @since 2020-05-27 */import com.godfrey.mapper.DepartmentMapper; import com.godfrey.pojo.Department; import com.godfrey.service.DepartmentService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;import java.util.List;@Service public class DepartmentServiceImpl implements DepartmentService {
@Autowiredprivate DepartmentMapper departmentMapper;@Overridepublic List<Department> selectAllDepartment() { return departmentMapper.selectAllDepartment();}
} - UserService接口package com.godfrey.service;import com.godfrey.pojo.User;/**- description : User业务层- @author godfrey- @since 2020-05-26 */ public interface UserService { User selectPasswordByName(String userName, String password); }
- UserServiceImpl实现类package com.godfrey.service.impl;import com.godfrey.mapper.UserMapper; import com.godfrey.pojo.User; import com.godfrey.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;/**- description : UserServiceImpl- @author godfrey- @since 2020-05-26 */ @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper;@Override public User selectPasswordByName(String userName, String password) { return userMapper.selectPasswordByName(userName, password); } }
- 测试获取数据情况@Autowired EmployeeService employeeService;@Test public void test(){ List employees = employeeService.selectAllEmployeeDTO(); for (EmployeeDTO employee : employees) { System.out.println(employee); } } @Test public void test2(){ Employee employee = employeeService.selectEmployeeById(1); System.out.println(employee); //Employee(id=1, employeeName=张三, email=zhangsan@gmail.com, gender=0, departmentId=1, date=2020-02-12) }@Test public void test3(){ Employee employee = new Employee(); employee.setId(6); employee.setEmployeeName(“test”); employee.setEmail(“123@qq.com”); employee.setDepartmentId(2); Date date = new Date(2020-02-02); employee.setDate(date); employeeService.addEmployee(employee); Employee employee1 = employeeService.selectEmployeeById(6); System.out.println(employee1); //Employee(id=6, employeeName=test, email=123@qq.com, gender=0, departmentId=2, date=1970-01-01) }@Test public void test4(){ Employee employee = new Employee(); employee.setId(6); employee.setEmployeeName(“test”); employee.setEmail(“123@qq.com”); employee.setDepartmentId(3); Date date = new Date(2020-02-02); employee.setDate(date); employeeService.updateEmployee(employee); Employee employee1 = employeeService.selectEmployeeById(6); System.out.println(employee1); //Employee(id=6, employeeName=test, email=123@qq.com, gender=0, departmentId=3, date=1970-01-01) }@Test public void test05(){ employeeService.deleteEmployee(6); }@Autowired private UserService userService; @Test public void test06(){ User admin = userService.selectPasswordByName(“admin”,“123456”); System.out.println(admin); //User(id=1, name=admin, password=123456) }@Autowired private DepartmentService departmentService; @Test public void test07(){ List departments = departmentService.selectAllDepartment(); for (Department department : departments) { System.out.println(department); } }
Controller层
- 登陆页LoginControllerpackage com.godfrey.controller;import com.godfrey.pojo.User; import com.godfrey.service.UserService; 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 org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam;import javax.servlet.http.HttpSession;/**- description : 登录Controller- @author godfrey- @since 2020-05-26 */ @Controller public class LoginController {@Autowired private UserService userService;@RequestMapping(“/login”) public String login(@RequestParam(“username”)String username, @RequestParam(“password”)String password, HttpSession session, Model model){ User user = userService.selectPasswordByName(username, password); if ( user != null){ //登录成功! session.setAttribute(“username”,user.getUserName()); //登录成功!防止表单重复提交,我们重定向 return “redirect:/main.html”; }else { //登录失败!存放错误信息 model.addAttribute(“msg”,“用户名或密码错误”); return “index”; } }@GetMapping(“/user/loginOut”) public String loginOut(HttpSession session){ session.invalidate(); return “redirect:/index.html”; } }
- 员工信息Controllerpackage com.godfrey.controller;import com.godfrey.dto.EmployeeDTO; import com.godfrey.pojo.Department; import com.godfrey.pojo.Employee; import com.godfrey.service.DepartmentService; import com.godfrey.service.EmployeeService; 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 org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping;import java.util.Collection;/**- description : EmployeeController- @author godfrey- @since 2020-05-26 */ @Controller public class EmployeeController {@Autowired private EmployeeService employeeService;@Autowired private DepartmentService departmentService;//查询所有员工,返回列表页面 @GetMapping(“/emp”) public String list(Model model){ Collection employees = employeeService.selectAllEmployeeDTO(); // 将结果放在请求中 model.addAttribute(“emps”,employees); return “emp/list.html”; }//to员工添加页面 @GetMapping(“/add”) public String toAdd(Model model){ //查出所有的部门,提供选择 Collection departments = departmentService.selectAllDepartment(); model.addAttribute(“departments”,departments); return “emp/add.html”; }//员工添加功能,使用post接收 @PostMapping(“/add”) public String add(Employee employee){ //保存员工信息 employeeService.addEmployee(employee); //回到员工列表页面,可以使用redirect或者forward return “redirect:/emp”; }//to员工修改页面 @GetMapping(“/emp/{id}”) public String toUpdateEmp(@PathVariable(“id”) Integer id, Model model){ //根据id查出来员工 Employee employee = employeeService.selectEmployeeById(id); //将员工信息返回页面 model.addAttribute(“emp”,employee); //查出所有的部门,提供修改选择 Collection departments = departmentService.selectAllDepartment(); model.addAttribute(“departments”,departments);
return "emp/update.html";
}@PostMapping(“/updateEmp”) public String updateEmp(Employee employee){ employeeService.updateEmployee(employee); //回到员工列表页面 return “redirect:/emp”; }@GetMapping(“/delEmp/{id}”) public String deleteEmp(@PathVariable(“id”)Integer id){ //根据id删除员工 employeeService.deleteEmployee(id); return “redirect:/emp”; } }
完善Config文件
- 编写Interceptor拦截器配置package com.godfrey.config;import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;/**- description : Interceptor登录拦截器- @author godfrey- @since 2020-05-26 */ public class MyHandlerInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Object username = request.getSession().getAttribute(“username”); if (username == null) {//未登录,返回登录页面 request.setAttribute(“msg”, “没有权限,请先登录”); request.getRequestDispatcher(“/index.html”).forward(request, response); return false; } else {//登录,放行 return true; } } }
- 编写国际化配置文件package com.godfrey.config;import org.springframework.util.StringUtils; import org.springframework.web.servlet.LocaleResolver;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Locale;/**- description : 国际化语言解析器- @author godfrey- @since 2020-05-26 */ public class MyLocaleResolver implements LocaleResolver { //解析请求 @Override public Locale resolveLocale(HttpServletRequest httpServletRequest) { //获取请求中的语言参数 String language = httpServletRequest.getParameter(“lang”); Locale locale = Locale.getDefault();//如果没有就使用默认的 if(!StringUtils.isEmpty(language)){ String[] split = language.split(“_”); locale = new Locale(split[0],split[1]); } return locale; }@Override public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {} }
- 编写WebMvc文件,将上述配置到MvcConfiguration中package com.godfrey.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/**- description : 扩展MVC配置- @author godfrey- @since 2020-05-26 */ @Configuration public class MyWebMvcConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController(“/”).setViewName(“index”); registry.addViewController(“/index.html”).setViewName(“index”); registry.addViewController(“/main.html”).setViewName(“main”); }//自定义国际化组件 @Bean public LocaleResolver localeResolver(){ return new MyLocaleResolver(); }@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyHandlerInterceptor()) .addPathPatterns(“/**“) .excludePathPatterns(”/“,”/index.html",“/login”,"/css/**”,“/js/**“,”/img/**”); } }
前端视图
- 登陆页index.htmlSignin Template for Bootstrap
<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1><input type="text" name="username" class="form-control" th:placeholder="#{login.username}" required="" autofocus=""><input type="password" name="password" class="form-control" th:placeholder="#{login.password}" required=""><!--判断是否显示,使用if, ${}可以使用工具类,可以看thymeleaf的中文文档--><p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p><div class="checkbox mb-3"> <label> <input type="checkbox" value="remember-me" > [[#{login.remember}]] </label></div><button class="btn btn-lg btn-primary btn-block" type="submit">[[#{login.btn}]]</button><p class="mt-5 mb-3 text-muted">© 2017-2018</p><a class="btn btn-sm" th:href="@{/index.html(lang=zh_CN)}">中文</a><a class="btn btn-sm" th:href="@{/index.html(lang=en_US)}">English</a>
- 系统管理页 main.html
<title>Dashboard Template for Bootstrap</title><!-- Bootstrap core CSS --><link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"><!-- Custom styles for this template --><link th:href="@{/css/dashboard.css}" rel="stylesheet"><style type="text/css"> /* Chart.js */ @-webkit-keyframes chartjs-render-animation { from { opacity: 0.99 } to { opacity: 1 } } @keyframes chartjs-render-animation { from { opacity: 0.99 } to { opacity: 1 } } .chartjs-render-monitor { -webkit-animation: chartjs-render-animation 0.001s; animation: chartjs-render-animation 0.001s; }</style>`````` <main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4"> <div class="chartjs-size-monitor" style="position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px; overflow: hidden; pointer-events: none; visibility: hidden; z-index: -1;"> <div class="chartjs-size-monitor-expand" style="position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;"> <div style="position:absolute;width:1000000px;height:1000000px;left:0;top:0"></div> </div> <div class="chartjs-size-monitor-shrink" style="position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;"> <div style="position:absolute;width:200%;height:200%;left:0; top:0"></div> </div> </div> <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pb-2 mb-3 border-bottom"> <h1 class="h2">Dashboard</h1> <div class="btn-toolbar mb-2 mb-md-0"> <div class="btn-group mr-2"> <button class="btn btn-sm btn-outline-secondary">Share</button> <button class="btn btn-sm btn-outline-secondary">Export</button> </div> <button class="btn btn-sm btn-outline-secondary dropdown-toggle"> <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-calendar"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect><line x1="16" y1="2" x2="16" y2="6"></line><line x1="8" y1="2" x2="8" y2="6"></line><line x1="3" y1="10" x2="21" y2="10"></line></svg> This week </button> </div> </div> <canvas class="my-4 chartjs-render-monitor" id="myChart" width="1076" height="454" style="display: block; width: 1076px; height: 454px;"></canvas> </main></div>
版权归原作者 辣椒种子 所有, 如有侵权,请联系我们删除。