SpringBoot_staff
写一个简单的员工管理系统,来体验 Spring Boot 开发的整个流程。
1、项目结构
-
创建 Spring Boot Web 项目:
springboot_04_staff
-
导入依赖
- 数据库:JDBC、MySQL 连接、Druid 数据源、MyBatis
- 模板引擎:Thymeleaf
-
完善包结构
- pojo
- dao
- service
- controller
- config
- constant
-
导入静态资源
- static 目录:存放资源文件,如 CSS、JS...
- templates 目录:存放 HTML 页面
2、数据库表、实体类
2.1、数据库springboot_staff
数据库表必备三字段(阿里巴巴规范)
-
id
:逻辑主键,无实际含义,用于唯一标识每个字段 -
create_time
:创建时间 -
update_time
:更新时间
部门表department
-
department_id
:业务主键,部门ID -
name
:部门名
员工表employee
部门和员工是一对多的关系
-
employee_id
:业务主键,员工ID -
name
:员工名 email
gender
birthday
-
department_id
:在数据库中,用 ID 表示部门
2.2、实体类
- 不需要逻辑主键;
- 根据需要添加
constructor
、toString()
、getter和setter
,可以全部添加
部门类Department
public class Department {
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
/**
* 部门ID
*/
private String departmentId;
/**
* 部门名
*/
private String name;
@Override
public String toString() {
...
}
}
员工类Employee
-
Department
:在实体类中,用实体类表示部门
public class Employee {
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
/**
* 员工ID
*/
private String employeeId;
/**
* 员工名
*/
private String name;
/**
* 邮箱
*/
private String email;
/**
* 性别
*/
private Integer gender;
/**
* 生日
*/
private Date birthday;
/**
* 部门
*/
private Department department;
@Override
public String toString() {
...
}
}
2.3、注意
-
ORM原则
-
命名风格:
- 数据库:下划线
- 实体类:小驼峰
-
多对一关系:员工对部门
-
员工实体中对部门的表示
- 数据库- employee 表:部门ID——department_id;
- 实体类- Employee 类:部门——Department;
-
映射问题
- 命名风格映射;
- department_id 和 Department 的映射。
3、整合MyBatis
即整合了 MyBatis后的 DAO层 :10.3、整合 MyBatis
3.1、导入依赖
<!-- JDBC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- MySQL连接 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Druid数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<!-- SpringBoot整合MyBatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<!-- log4j日志 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
3.2、数据库配置文件
- JDBC 数据库配置
- Druid 数据源
- MyBatis
application.yaml
spring:
datasource:
username: root
password: 密码
url: jdbc:mysql://localhost:3306/数据库名?useUnicode=true&characterEncoding=utf8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
# Druid数据源
type: com.alibaba.druid.pool.DruidDataSource
# Druid数据源配置
initialSize: 5
maxActive: 20
minIdle: 5
maxWait: 60000
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
validationQuery: SELECT 1 FROM DUAL
testOnBorrow: false
testOnReturn: false
testWhileIdle: true
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
# filters:stat监控统计、log4j日志记录(需要导入log4j依赖)、wall防御sql注入
filters: stat,wall,log4j
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
# 整合MyBatis配置
mybatis:
type-aliases-package: indi.jaywee.pojo
# Mapper.xml放在resources目录下与mapper同名的包下
mapper-locations: classpath:indi/jaywee/mapper/*.xml
# 自动映射:数据库下划线命名<-->实体类驼峰命名
configuration:
map-underscore-to-camel-case: true
3.3、Mapper
- Mapper 类上方添加
@Mapper
注解 - 编写基本的 CRUD,后面再根据业务需求来添加方法。
DepartmentMapper
@Mapper
public interface DepartmentMapper {
/**
* 根据ID查询部门
*
* @param departmentId 部门ID
* @return 查询部门
*/
Department getDepartment(String departmentId);
/**
* 查询所有部门
*
* @return 部门列表
*/
List<Department> listDepartments();
}
EmployeeMapper
/**
* 添加员工
*
* @param employee 待添加员工
* @return 受影响行数
*/
int insertEmployee(Employee employee);
/**
* 删除员工
*
* @param employeeId 员工ID
* @return 受影响行数
*/
int deleteEmployee(String employeeId);
/**
* 更新员工:改名
*
* @param employeeId 员工ID
* @param newName 新名称
* @return 受影响行数
*/
int updateEmployee(String employeeId, String newName);
/**
* 根据ID查询员工
*
* @param employeeId 员工ID
* @return 待查询员工
*/
Employee getEmployee(String employeeId);
/**
* 查询所有员工
*
* @return 员工列表
*/
List<Employee> listEmployees();
3.4、Mapper.xml
-
绑定对应接口:
namespace="xxx"
; - 命名映射配置:下划线命名和驼峰命名的自动映射;
- 写 SQL 语句注意
- 区分命名风格:数据库字段用下划线,实体类属性用驼峰命名;
- 区分主键:逻辑主键id无实际含义,业务主键有业务逻辑含义;
- 难点:Employee 的部门字段的映射
DepartmentMapper.xml
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 接口绑定 -->
<mapper namespace="indi.jaywee.mapper.DepartmentMapper">
<!-- 根据ID查询部门 -->
<select id="getDepartment" resultType="department">
SELECT create_time,
update_time,
department_id,
name
FROM springboot_staff.department
WHERE department_id = #{departmentId}
</select>
<!-- 查询所有部门 -->
<select id="listDepartments" resultType="department">
SELECT create_time,
update_time,
department_id,
name
FROM springboot_staff.department
</select>
</mapper>
EmployeeMapper.xml
- insert:要求实体类Employee 具有 getDepartmentId 方法,否则无法获取并插入departmentId
-
select:
- 使用 resultMap 处理结果集映射
- 使用 association + 子查询,来映射部门字段(有关说明见MyBatis的多对一和一对多)
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 接口绑定 -->
<mapper namespace="indi.jaywee.mapper.EmployeeMapper">
<!-- 添加员工 -->
<insert id="insertEmployee">
INSERT INTO springboot_staff.employee(create_time, update_time, employee_id, name, email, gender, birthday,department_id)
VALUES (#{createTime}, #{updateTime}, #{employeeId},
#{name}, #{email}, #{gender}, #{birthday}, #{departmentId})
</insert>
<!-- 更新员工:改名 -->
<update id="updateEmployee">
UPDATE springboot_staff.employee
SET name = #{newName}
WHERE employee_id = #{employeeId}
</update>
<!-- 删除员工 -->
<delete id="deleteEmployee">
DELETE
FROM springboot_staff.employee
WHERE employee_id = #{employeeId}
</delete>
<!-- 查询员工 -->
<select id="getEmployee" resultMap="employeeMap">
SELECT create_time,
update_time,
employee_id,
name,
email,
gender,
birthday,
department_id
FROM springboot_staff.employee
WHERE employee_id = #{employeeId}
</select>
<!-- 查询所有员工-->
<select id="listEmployees" resultMap="employeeMap">
SELECT create_time,
update_time,
employee_id,
name,
email,
gender,
birthday,
department_id
FROM springboot_staff.employee
</select>
<!-- 结果映射:数据库department_id与实体类Department -->
<resultMap id="employeeMap" type="employee">
<association property="department" column="department_id" javaType="Department" select="getDepartment"/>
</resultMap>
<select id="getDepartment" resultType="department">
SELECT create_time, update_time, name, department_id
FROM springboot_staff.department
WHERE department_id = #{department_id}
</select>
</mapper>
4、Service层
Service层调用 DAO层方法
EmployeeService
/**
* 添加员工
*
* @param employee 待添加员工
* @return 受影响行数
*/
int insertEmployee(Employee employee);
/**
* 删除员工
*
* @param employeeId 员工ID
* @return 受影响行数
*/
int deleteEmployee(String employeeId);
/**
* 更新员工:改名
*
* @param employeeId 员工ID
* @param newName 新名称
* @return 受影响行数
*/
int updateEmployee(String employeeId, String newName);
/**
* 根据ID查询员工
*
* @param employeeId 员工ID
* @return 待查询员工
*/
Employee getEmployee(String employeeId);
/**
* 查询所有员工
*
* @return 员工列表
*/
List<Employee> listEmployees();
EmployeeServiceImpl
-
使用
@Service
注解,将Service实现类注册到容器中; - 注入
EmployeeMapper
@Service
public class EmployeeServiceImpl implements EmployeeService {
/**
* Service层调用DAO层方法
*/
@Resource
EmployeeMapper employeeMapper;
@Override
public int insertEmployee(Employee employee) {
return employeeMapper.insertEmployee(employee);
}
@Override
public int deleteEmployee(String employeeId) {
return employeeMapper.deleteEmployee(employeeId);
}
@Override
public int updateEmployee(String employeeId, String newName) {
return employeeMapper.updateEmployee(employeeId, newName);
}
@Override
public Employee getEmployee(String employeeId) {
return employeeMapper.getEmployee(employeeId);
}
@Override
public List<Employee> listEmployees() {
return employeeMapper.listEmployees();
}
}
编写完 Service层后,创建相应的 ServiceTest 类,测试是否能正常运行
5、欢迎页面
- 默认启动 Spring Boot 项目时,在没有设置首页的情况下,打开的是错误页面 Whitelabel Error Page;
- 由于使用 Thymeleaf 模板引擎,只能映射 template 目录下的页面,因此需要显式地设置欢迎页面的视图控制器
5.1、模板引擎
导入 Thymeleaf 的 starter:spring-boot-starter-thymeleaf
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
- 添加 pom 依赖后,刷新Maven。
5.2、视图控制器
:创建自定义 SpringMVC 配置类
- 实现
WebMvcConfigurer
接口的@Configuration
类 -
添加视图控制器:访问
/
和/index.html
,会映射到 template 目录下的index.html
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// 欢迎页面
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
}
}