1. 项目概述
作为一名Java开发者,我最近在学习SpringBoot和MyBatis框架时,整理了一套完整的部门员工管理系统开发笔记。这个项目涵盖了从环境搭建到功能实现的完整流程,特别适合刚接触JavaWeb开发的同行参考。下面我将详细分享这个项目的开发过程,包括RESTful API设计、MyBatis使用技巧以及实际开发中遇到的坑和解决方案。
1.1 核心需求解析
这个管理系统主要实现以下功能:
- 部门管理:包括部门的新增、删除、查询
- 员工管理:支持员工信息的分页查询(带条件)和批量删除
- RESTful风格API设计
- MyBatis的两种使用方式:注解和XML配置
2. 环境准备与项目搭建
2.1 开发环境配置
在开始编码前,我们需要准备好开发环境。我使用的是以下技术栈:
- JDK 1.8
- SpringBoot 2.7.0
- MyBatis 3.5.6
- MySQL 8.0
- Lombok 1.18.24
提示:建议使用IDEA作为开发工具,它对SpringBoot项目有很好的支持,可以自动处理很多依赖关系。
2.1.1 数据库准备
首先创建两张基础表:
sql复制-- 部门表
CREATE TABLE dept (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
create_time DATETIME,
update_time DATETIME
);
-- 员工表
CREATE TABLE emp (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
gender TINYINT COMMENT '1-男, 2-女',
entrydate DATE,
dept_id INT,
create_time DATETIME,
update_time DATETIME
);
2.1.2 SpringBoot工程创建
使用Spring Initializr创建项目时,需要选择以下依赖:
- Spring Web
- MyBatis Framework
- MySQL Driver
- Lombok
在application.properties中配置数据库连接:
properties复制spring.datasource.url=jdbc:mysql://localhost:3306/your_db?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=your_password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# MyBatis配置
mybatis.type-aliases-package=com.example.pojo
mybatis.mapper-locations=classpath:mapper/*.xml
2.2 项目结构设计
良好的项目结构能让代码更易维护。我采用了典型的三层架构:
code复制src/main/java
├── com.example
│ ├── controller # 控制层
│ ├── service # 业务层
│ │ ├── impl # 实现类
│ ├── mapper # 持久层
│ ├── pojo # 实体类
│ └── config # 配置类
src/main/resources
├── static
├── templates
└── application.properties
3. RESTful API设计与实现
3.1 RESTful规范实践
RESTful是一种软件架构风格,不是标准。在实际项目中,我们通常遵循以下约定:
| HTTP方法 | 路径示例 | 操作 | 返回状态码 |
|---|---|---|---|
| GET | /depts | 查询所有部门 | 200 |
| GET | /depts/ | 查询单个部门 | 200/404 |
| POST | /depts | 新增部门 | 201 |
| PUT | /depts/ | 修改部门 | 200/204 |
| DELETE | /depts/ | 删除部门 | 204 |
3.1.1 路径设计技巧
- 使用复数名词表示资源集合
- 使用连字符(-)而不是下划线(_)分隔单词
- 避免在URI中使用动词
- 版本控制可以在URI或Header中实现
3.2 部门管理实现
3.2.1 查询所有部门
Controller层代码:
java复制@Slf4j
@RestController
@RequestMapping("/depts")
public class DeptController {
@Autowired
private DeptService deptService;
@GetMapping
public Result list() {
log.info("查询所有部门数据");
List<Dept> deptList = deptService.list();
return Result.success(deptList);
}
}
Service层实现:
java复制@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper;
@Override
public List<Dept> list() {
return deptMapper.list();
}
}
Mapper接口:
java复制@Mapper
public interface DeptMapper {
@Select("SELECT id, name, create_time, update_time FROM dept")
List<Dept> list();
}
3.2.2 新增部门
Controller层处理JSON请求:
java复制@PostMapping
public Result add(@RequestBody Dept dept) {
log.info("新增部门:{}", dept);
deptService.add(dept);
return Result.success();
}
Service层补全时间信息:
java复制@Override
public void add(Dept dept) {
dept.setCreateTime(LocalDateTime.now());
dept.setUpdateTime(LocalDateTime.now());
deptMapper.insert(dept);
}
Mapper使用注解方式:
java复制@Insert("INSERT INTO dept(name, create_time, update_time) VALUES(#{name}, #{createTime}, #{updateTime})")
void insert(Dept dept);
4. 员工管理高级功能实现
4.1 分页查询实现
4.1.1 基础分页查询
分页查询需要考虑以下参数:
- 当前页码(page)
- 每页条数(pageSize)
- 总记录数(total)
- 当前页数据列表(rows)
PageBean封装类:
java复制@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageBean {
private Long total;
private List<?> rows;
}
Service实现逻辑:
java复制@Override
public PageBean page(Integer page, Integer pageSize) {
// 设置分页参数
PageHelper.startPage(page, pageSize);
// 执行查询
List<Emp> empList = empMapper.list();
// 获取分页结果
Page<Emp> p = (Page<Emp>) empList;
return new PageBean(p.getTotal(), p.getResult());
}
4.1.2 使用PageHelper插件
PageHelper是国内最流行的MyBatis分页插件,使用步骤:
- 添加依赖:
xml复制<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
- 在Service中调用:
java复制PageHelper.startPage(page, pageSize); // 关键代码
List<Emp> list = empMapper.list();
注意事项:PageHelper.startPage()必须紧跟在查询方法前调用,中间不能有其他逻辑。
4.2 条件分页查询
4.2.1 前端参数处理
Controller接收多种查询条件:
java复制@GetMapping
public Result page(
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer pageSize,
String name, Short gender,
@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,
@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) {
PageBean pageBean = empService.page(page, pageSize, name, gender, begin, end);
return Result.success(pageBean);
}
4.2.2 MyBatis动态SQL
使用XML配置实现复杂查询:
xml复制<select id="list" resultType="com.example.pojo.Emp">
SELECT * FROM emp
<where>
<if test="name != null and name != ''">
name LIKE CONCAT('%', #{name}, '%')
</if>
<if test="gender != null">
AND gender = #{gender}
</if>
<if test="begin != null and end != null">
AND entrydate BETWEEN #{begin} AND #{end}
</if>
</where>
ORDER BY update_time DESC
</select>
4.3 批量删除功能
4.3.1 接收数组参数
Controller使用路径变量接收ID列表:
java复制@DeleteMapping("/{ids}")
public Result delete(@PathVariable List<Integer> ids) {
empService.delete(ids);
return Result.success();
}
4.3.2 MyBatis批量操作
使用foreach实现批量删除:
xml复制<delete id="delete">
DELETE FROM emp WHERE id IN
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</delete>
5. 开发经验与避坑指南
5.1 常见问题解决
-
日期格式问题:
- 前端传日期字符串,后端用
@DateTimeFormat转换 - 数据库datetime类型对应Java的LocalDateTime
- 前端传日期字符串,后端用
-
MyBatis参数绑定:
- 简单参数直接使用
- 对象参数用
@Param注解指定名称 - 集合参数注意
collection属性设置
-
Lombok注解不生效:
- 检查IDE是否安装了Lombok插件
- 在设置中启用注解处理
5.2 性能优化建议
-
分页查询优化:
- 避免
SELECT *,只查询必要字段 - 大数据量时考虑使用游标分页
- 避免
-
MyBatis缓存:
- 一级缓存默认开启(SqlSession级别)
- 二级缓存需要手动配置(namespace级别)
-
SQL优化:
- 为常用查询条件添加索引
- 复杂查询考虑使用JOIN替代子查询
5.3 扩展思考
-
接口文档生成:
- 使用Swagger或Knife4j自动生成API文档
- 示例配置:
java复制@Bean public Docket docket() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.example.controller")) .paths(PathSelectors.any()) .build(); } -
全局异常处理:
- 使用
@ControllerAdvice统一处理异常 - 自定义业务异常类
- 使用
-
参数校验:
- 使用Hibernate Validator进行参数校验
- 示例:
java复制@PostMapping public Result add(@Valid @RequestBody Dept dept) { // ... } public class Dept { @NotBlank private String name; // ... }
这个项目完整实现了部门员工管理系统的后端开发,涵盖了SpringBoot和MyBatis的核心用法。在实际开发中,我发现合理设计RESTful API和熟练使用MyBatis动态SQL能极大提高开发效率。特别是PageHelper插件,让分页查询变得非常简单。希望这份笔记能帮助到正在学习JavaWeb开发的同行们。