目录
前言
前面我们已经一起学习了 Web 开发的基础知识,包括 Maven、HTTP 协议、SpringBoot Web 基础、IOC、DI、MySQL、JDBC、Mybatis 等。现在我们正式进入后端 Web 实战篇,把这些基础串联起来,完成一个综合案例 —— Tlias 智能学习辅助系统。
这个系统将包含以下功能:
-
部门管理
-
员工管理
-
员工信息统计
-
学员信息统计
-
班级、学员管理
今天我们就来搞定第一个模块:部门管理。从环境搭建到接口实现,再到前后端联调,一站式拿下!
1. 准备工作
1.1 开发规范
1.1.1 前后端分离开发
现代企业项目开发主要有两种模式:前后台混合开发 和 前后台分离开发。
前后台混合开发 时,前端页面和后端代码混在同一个工程里:

这种模式的缺点很明显:
-
沟通成本高:后台人员发现前端问题要找前端改,前端改完再丢给后台。
-
分工不明确:后台不仅要写 Java,还得写部分前端代码,难以培养专精人才。
-
管理不便:所有代码塞在一个工程里,容易混乱。
-
维护困难:前端一个样式调整,可能就得把整个工程重新打包部署。
所以现在主流都是 前后台分离开发:

我们将工程拆分为前端工程和后端工程,分别交给专业的前端和后端人员。前端通过异步请求(Ajax)从后端获取数据。那问题来了:前端怎么知道后端返回什么格式?后端又怎么知道前端需要什么数据?
答案就是 接口文档。前后端共同约定一套接口规范,大家按照文档各写各的,最后联调对接。接口文档通常由后端根据产品原型和需求文档编写,有离线版和在线版。

后端开发流程 总结为:
-
需求分析:阅读需求文档,理解要做什么。
-
接口定义:查看接口文档,明确地址、参数、响应格式等。
-
前后端并行开发:各自按文档开发。
-
各自测试:后端用工具测接口,前端用 Mock 数据测页面。
-
前后端联调:把前端请求指到真实后端,打通整个流程。
1.1.2 RESTful 风格
前后端交互时,我们通常采用 REST 风格的 API 接口。
什么是REST风格呢?
REST(Representational State Transfer),表述性状态转换,它是一种软件架构风格。

传统 URL 风格 可能长这样:
-
http://localhost:8080/user/getById?id=1查询 -
http://localhost:8080/user/saveUser新增 -
http://localhost:8080/user/updateUser修改 -
http://localhost:8080/user/deleteUser?id=1删除
缺点:URL 复杂,行为暴露,不同开发人员命名习惯不同(getById、queryById、loadById…),难以统一。
REST 风格 URL:
-
GET http://localhost:8080/users/1查询 id 为 1 的用户 -
POST http://localhost:8080/users新增用户 -
PUT http://localhost:8080/users修改用户 -
DELETE http://localhost:8080/users/1删除 id 为 1 的用户
核心思想:通过 URL 定位资源,通过 HTTP 动词(请求方式)描述操作。
| 请求方式 | 操作 |
|---|---|
| GET | 查询 |
| POST | 新增 |
| PUT | 修改 |
| DELETE | 删除 |
注意事项:
REST 是风格,是约定,不是强制规定,可以打破。
资源通常用复数表示,如
/users、/emps、/books。
1.1.3 Apifox
在前后端分离并行开发时,有两个现实问题:
-
后端写完接口,怎么方便地测试?
-
前端还在开发,怎么拿到数据来渲染页面?
这时候就需要借助接口测试工具,比如 Postman、Apipost,以及我们课程中使用的 Apifox。
Apifox( https://apifox.com/)是一款集成了 API 文档、API 调试、API Mock、API 测试的一体化协作平台。我们可以用它来管理接口文档、测试接口、生成 Mock 数据。
安装:直接双击资料中的安装包,安装后扫码登录即可使用。

1.2 工程搭建
正式开始写代码之前,先把基础工程搭好。
1) 创建 SpringBoot 工程
引入依赖:Spring Web、Mybatis、MySQL 驱动、Lombok。

2) 创建数据库及表结构
创建名为 tlias 的数据库,并执行以下建表语句:
CREATE TABLE dept (
id int unsigned PRIMARY KEY AUTO_INCREMENT COMMENT 'ID, 主键',
name varchar(10) NOT NULL UNIQUE COMMENT '部门名称',
create_time datetime DEFAULT NULL COMMENT '创建时间',
update_time datetime DEFAULT NULL COMMENT '修改时间'
) COMMENT '部门表';
INSERT INTO dept VALUES (1,'学工部','2023-09-25 09:47:40','2024-07-25 09:47:40'),
(2,'教研部','2023-09-25 09:47:40','2024-08-09 15:17:04'),
(3,'咨询部','2023-09-25 09:47:40','2024-07-30 21:26:24'),
(4,'就业部','2023-09-25 09:47:40','2024-07-25 09:47:40'),
(5,'人事部','2023-09-25 09:47:40','2024-07-25 09:47:40'),
(6,'行政部','2023-11-30 20:56:37','2024-07-30 20:56:37');
在 application.yml 中配置数据库连接信息:
spring:
application:
name: tlias-web-management
#mysql连接配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/tlias
username: root
password: 1234
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
3) 准备基础包结构及实体类
创建如下包结构:
Dept 实体类(使用 Lombok 简化):
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Dept {
private Integer id;
private String name;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}
统一响应结果类 Result:
/**
* 后端统一返回结果
*/
@Data
public class Result {
private Integer code; //编码:1成功,0为失败
private String msg; //错误信息
private Object data; //数据
public static Result success() {
Result result = new Result();
result.code = 1;
result.msg = "success";
return result;
}
public static Result success(Object object) {
Result result = new Result();
result.data = object;
result.code = 1;
result.msg = "success";
return result;
}
public static Result error(String msg) {
Result result = new Result();
result.msg = msg;
result.code = 0;
return result;
}
}
基础代码骨架:
// DeptMapper
@Mapper
public interface DeptMapper { }
// DeptService
public interface DeptService { }
// DeptServiceImpl
@Service
public class DeptServiceImpl implements DeptService { }
// DeptController
@RestController
public class DeptController { }
至此,工程搭建完毕,接下来我们正式实现部门管理功能!
2. 查询部门
2.1 基本实现
需求
查询所有部门数据,展示在部门管理页面上。

接口描述
根据接口文档:部门管理 → 部门列表查询,请求方式为 GET,路径
/depts,无需参数,返回所有部门的 JSON 数组。
实现思路

采用经典三层架构:
-
Controller:接收请求,调用 Service 查询数据,返回 Result。
-
Service:调用 Mapper 获取部门列表。
-
Mapper:执行 SQL 查询所有部门。
代码实现
Controller 层:
/**
* 部门管理控制器
*/
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
/**
* 查询部门列表
*/
@RequestMapping("/depts")
public Result list(){
List<Dept> deptList = deptService.findAll();
return Result.success(deptList);
}
}
Service 层:
public interface DeptService {
/**
* 查询所有部门
*/
public List<Dept> findAll();
}
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper;
public List<Dept> findAll() {
return deptMapper.findAll();
}
}
Mapper 层:
@Mapper
public interface DeptMapper {
/**
* 查询所有部门
*/
@Select("select * from dept")
public List<Dept> findAll();
}
接口测试
启动项目,打开 Apifox,新建一个 GET 请求:http://localhost:8080/depts,发送后可以看到成功返回了所有部门数据。

如果我们用 POST、PUT 等请求方式也能访问到这个接口,这不符合接口文档的限制。我们可以通过 @GetMapping 这样的衍生注解来限制请求方式:
@GetMapping→ 只处理 GET
@PostMapping→ 只处理 POST
@PutMapping→ 只处理 PUT
@DeleteMapping→ 只处理 DELETE@RestController public class DeptController { @Autowired private DeptService deptService; /** * 查询部门列表 */ @GetMapping("/depts") public Result list(){ List<Dept> deptList = deptService.findAll(); return Result.success(deptList); } }推荐直接使用这些注解,既简洁又安全。
数据封装问题
测试时发现
createTime和updateTime字段为 null,但数据库里有值。这是因为:
实体类属性名
createTime与数据库列名create_time不一致,Mybatis 无法自动映射。
三种解决方案:
1. 手动结果映射(使用 @Results 和 @Result):
在DeptMapper接口方法上,通过 @Results及@Result 进行手动结果映射。
@Results({@Result(column = "create_time", property = "createTime"),
@Result(column = "update_time", property = "updateTime")})
@Select("select id, name, create_time, update_time from dept")
public List<Dept> findAll();
2. SQL 起别名:
在SQL语句中,对不一样的列名起别名,别名和实体类属性名一样。
@Select("select id, name, create_time createTime, update_time updateTime from dept")
public List<Dept> findAll();
3. 开启驼峰命名映射(推荐):
如果字段名与属性名符合驼峰命名规则,mybatis会自动通过驼峰命名规则映射。驼峰命名规则: abc_xyz => abcXyz
表中字段名:abc_xyz
类中属性名:abcXyz
在 application.yml 中配置:
mybatis:
configuration:
map-underscore-to-camel-case: true
这样
create_time会自动映射为createTime,前提是字段名严格遵守驼峰规则。
2.2 前后端联调
接口测试通过后,我们还要和真实前端环境联调。
步骤:
-
将资料中的“前端环境”压缩包解压到无中文、无空格的目录。
-
双击
nginx.exe启动 Nginx(任务管理器里能看到两个 nginx 进程即成功)。 -
浏览器访问
http://localhost:90,即可看到前端页面。

请求流程:
前端请求
http://localhost:90/api/depts,Nginx 接收到请求后,通过反向代理转发给后端的 Tomcat(http://localhost:8080/depts),最终由 Tomcat 处理并返回数据。
使用 Nginx 的好处:
安全:后端服务器不直接暴露。
灵活:后端增减服务器前端无感知。
负载均衡:可以方便地分发请求。
Nginx 配置关键指令(了解即可):
location ^~ /api/ {
rewrite ^/api/(.*)$ /$1 break; # 去掉 /api 前缀
proxy_pass http://localhost:8080; # 转发到后端
}
3. 删除部门
3.1 需求
点击“删除”按钮,根据部门 ID 删除该部门。

3.2 接口描述
根据接口文档:DELETE
/depts,参数id(Query 参数)。
3.3 思路分析

三层职责:
-
Controller:接收
id参数,调用 Service 删除,返回成功。 -
Service:调用 Mapper 删除。
-
Mapper:执行
deleteSQL。
3.4 简单参数接收
SpringBoot 中接收简单参数(比如 ?id=5)有三种方式:
方式一:HttpServletRequest(不推荐)
/**
* 根据ID删除部门 - 简单参数接收: 方式一 (HttpServletRequest)
*/
@DeleteMapping("/depts")
public Result delete(HttpServletRequest request){
String idStr = request.getParameter("id");
int id = Integer.parseInt(idStr);
System.out.println("根据ID删除部门: " + id);
return Result.success();
}
方式二:@RequestParam 注解
@DeleteMapping("/depts")
public Result delete(@RequestParam("id") Integer deptId){
System.out.println("根据ID删除部门: " + deptId);
return Result.success();
}
@RequestParam注解required属性默认为true,代表该参数必须传递,如果不传递将报错。 如果参数可选,可以将属性设置为false。
方式三:直接使用同名形参(推荐)
@DeleteMapping("/depts")
public Result delete(Integer id){
System.out.println("根据ID删除部门: " + deptId);
return Result.success();
}
请求参数名与形参名一致时,可以省略
@RequestParam。
3.5 代码实现
Controller:
/**
* 根据id删除部门 - delete http://localhost:8080/depts?id=1
*/
@DeleteMapping("/depts")
public Result delete(Integer id){
System.out.println("根据id删除部门, id=" + id);
deptService.deleteById(id);
return Result.success();
}
Service:
/**
* 根据id删除部门
*/
void deleteById(Integer id);
public void deleteById(Integer id) {
deptMapper.deleteById(id);
}
Mapper:
/**
* 根据id删除部门
*/
@Delete("delete from dept where id = #{id}")
void deleteById(Integer id);
注:
#{...}里的占位符名可以随意,如果只有一个简单类型参数,写#{value}也行。
启动服务,用 Apifox 发送 DELETE 请求:http://localhost:8080/depts?id=5,成功删除。

4. 新增部门
4.1 需求
点击“新增部门”,弹出表单,填写部门名称后点击确定,保存部门。

4.2 接口描述
POST
/depts,请求体为 JSON:{"name":"研发部"}。
4.3 思路分析

-
Controller:接收 JSON 数据,调用 Service 保存。
-
Service:补全时间字段,调用 Mapper 插入。
-
Mapper:执行 insert SQL。
4.4 JSON 参数接收
JSON 格式的请求体通常用一个实体类对象接收,需要加 @RequestBody 注解,JSON 的键名与对象属性名一致即可。
示例:
/**
* 新增部门 - POST http://localhost:8080/depts 请求参数:{"name":"研发部"}
*/
@PostMapping("/depts")
public Result save(@RequestBody Dept dept){
System.out.println("新增部门, dept=" + dept);
deptService.save(dept);
return Result.success();
}
4.5 代码实现
Controller:
/**
* 新增部门 - POST http://localhost:8080/depts 请求参数:{"name":"研发部"}
*/
@PostMapping("/depts")
public Result save(@RequestBody Dept dept){
System.out.println("新增部门, dept=" + dept);
deptService.save(dept);
return Result.success();
}
Service:
/**
* 新增部门
*/
void save(Dept dept);
public void save(Dept dept) {
//补全基础属性
dept.setCreateTime(LocalDateTime.now());
dept.setUpdateTime(LocalDateTime.now());
//保存部门
deptMapper.insert(dept);
}
Mapper:
/**
* 保存部门
*/
@Insert("insert into dept(name,create_time,update_time) values(#{name},#{createTime},#{updateTime})")
void insert(Dept dept);
用 Apifox 发送 POST 请求,Body 选择 JSON,输入 {"name":"开发部"},即可新增成功。

5. 修改部门
修改功能一般分两步:查询回显 和 修改数据。

5.1 查询回显

接口描述
GET
/depts/{id},路径参数id,返回该部门对象。
路径参数接收
URL 中的 {id} 就是路径参数,用 @PathVariable 接收:

如果形参名与路径变量名相同,
@PathVariable的 value 可省略。
代码实现
Controller:
/**
* 根据ID查询 - GET http://localhost:8080/depts/1
*/
@GetMapping("/depts/{id}")
public Result getById(@PathVariable Integer id){
System.out.println("根据ID查询, id=" + id);
Dept dept = deptService.getById(id);
return Result.success(dept);
}
Service:
/**
* 根据id查询部门
*/
Dept getById(Integer id);
public Dept getById(Integer id) {
return deptMapper.getById(id);
}
Mapper:
/**
* 根据ID查询部门数据
*/
@Select("select id, name, create_time, update_time from dept where id = #{id}")
Dept getById(Integer id);
测试一下,访问 GET /depts/6,返回对应部门信息。

5.2 修改数据
需求


回显后,用户修改部门名称,点击确定,根据 ID 更新部门数据。
接口描述
PUT
/depts,请求体 JSON:{"id":1, "name":"新部门名"}。
代码实现
Controller:
/**
* 修改部门 - PUT http://localhost:8080/depts 请求参数:{"id":1,"name":"研发部"}
*/
@PutMapping("/depts")
public Result update(@RequestBody Dept dept){
System.out.println("修改部门, dept=" + dept);
deptService.update(dept);
return Result.success();
}
Service:
/**
* 修改部门
*/
void update(Dept dept);
public void update(Dept dept) {
//补全基础属性
dept.setUpdateTime(LocalDateTime.now());
//保存部门
deptMapper.update(dept);
}
Mapper:
/**
* 更新部门
*/
@Update("update dept set name = #{name},update_time = #{updateTime} where id = #{id}")
void update(Dept dept);
通过 Apifox 发送 PUT 请求,Body 携带 JSON,更新成功。

5.2.5 抽取公共路径
我们发现 DeptController 中所有方法的路径都以 /depts 开头,可以将其抽取到类上:

一个完整的请求路径,应该是类上的 @RequestMapping 的value属性 + 方法上的 @RequestMapping的value属性。
6. 日志技术
6.1 概述
什么是日志?
日志就像程序的“日记本”,记录运行信息、状态、错误等。
为什么需要日志?
-
追踪程序执行过程和数据
-
性能优化分析
-
排查问题
-
监控系统状态
之前我们常用 System.out.println 输出,但它有严重缺陷:
-
硬编码:要移除日志只能删代码。
-
只能输出到控制台。
-
不易扩展维护。
因此我们使用专业的日志框架。
6.2 日志框架简介

-
JUL(java.util.logging):Java 自带,功能较弱。
-
Log4j:功能丰富,配置灵活。
-
Logback:Log4j 的升级版,性能更好,SpringBoot 默认内置。
-
SLF4J:日志门面,提供统一接口,底层可切换不同实现。
6.3 Logback 快速入门
SpringBoot 已经传递了 Logback 依赖,无需额外引入。我们只需添加配置文件 logback.xml 放到 src/main/resources 下。
示例配置(控制台输出):
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d 表示日期,%thread 表示线程名,%-5level表示级别从左显示5个字符宽度,%logger显示日志记录器的名称, %msg表示日志消息,%n表示换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%msg%n</pattern>
</encoder>
</appender>
<!-- 系统文件输出 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 日志文件输出的文件名及文件路径, %i表示序号 -->
<FileNamePattern>./logs/tlias-%d{yyyy-MM-dd}-%i.log</FileNamePattern>
<!-- 最多保留的历史日志文件数量 -->
<MaxHistory>30</MaxHistory>
<!-- 最大文件大小,超过这个大小会触发滚动到新文件,默认为 10MB -->
<maxFileSize>10MB</maxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d 表示日期,%thread 表示线程名,%-5level表示级别从左显示5个字符宽度,%msg表示日志消息,%n表示换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%msg%n</pattern>
</encoder>
</appender>
<!-- 日志输出级别 -->
<!-- OFF, ERROR, WARN, INFO, DEBUG, TRACE, ALL -->
<root level="INFO">
<appender-ref ref="STDOUT" /><!-- 控制台输出 -->
<appender-ref ref="FILE" /><!-- 系统文件输出 -->
</root>
</configuration>
记录日志示例:
public class LogTest {
//定义日志记录对象
private static final Logger log = LoggerFactory.getLogger(LogTest.class);
@Test
public void testLog(){
log.debug("开始计算...");
int sum = 0;
int[] nums = {1, 5, 3, 2, 1, 4, 5, 4, 6, 7, 4, 34, 2, 23};
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
}
log.info("计算结果为: "+sum);
log.debug("结束计算...");
}
}
控制台会输出带时间、线程、级别、类名的完整日志。
6.4 配置文件详解
logback.xml 可以配置输出位置和日志级别。
输出到文件(按日期和大小滚动):
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d 表示日期,%thread 表示线程名,%-5level表示级别从左显示5个字符宽度,%logger显示日志记录器的名称, %msg表示日志消息,%n表示换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%msg%n</pattern>
</encoder>
</appender>
<!-- 系统文件输出 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 日志文件输出的文件名及文件路径, %i表示序号 -->
<FileNamePattern>./logs/tlias-%d{yyyy-MM-dd}-%i.log</FileNamePattern>
<!-- 最多保留的历史日志文件数量 -->
<MaxHistory>30</MaxHistory>
<!-- 最大文件大小,超过这个大小会触发滚动到新文件,默认为 10MB -->
<maxFileSize>10MB</maxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d 表示日期,%thread 表示线程名,%-5level表示级别从左显示5个字符宽度,%msg表示日志消息,%n表示换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%msg%n</pattern>
</encoder>
</appender>
<!-- 日志输出级别 -->
<!-- OFF, ERROR, WARN, INFO, DEBUG, TRACE, ALL -->
<root level="INFO">
<appender-ref ref="STDOUT" /><!-- 控制台输出 -->
<appender-ref ref="FILE" /><!-- 系统文件输出 -->
</root>
</configuration>
日志级别(由低到高):
| 日志级别 | 说明 | 记录方式 |
| trace | 追踪,记录程序运行轨迹 【使用很少】 | log.trace("...") |
| debug | 调试,记录程序调试过程中的信息,实际应用中一般将其视为最低级别 【使用较多】 | log.debug("...") |
| info | 记录一般信息,描述程序运行的关键事件,如:网络连接、io操作 【使用较多】 | log.info("...") |
| warn | 警告信息,记录潜在有害的情况 【使用较多】 | log.warn("...") |
| error | 错误信息 【使用较多】 | log.error("...") |
配置
root level="INFO"时,只会输出 INFO 及以上级别的日志(INFO、WARN、ERROR)。开发阶段可以调低级别看详细信息,生产环境调高减少日志量。
6.5 在项目中使用
利用 Lombok 的 @Slf4j 注解,可以省去手动创建 Logger 对象,直接使用 log 变量:
/**
* 部门管理控制器
*/
@Slf4j
@RequestMapping("/depts")
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
/**
* 查询部门列表
*/
//@RequestMapping(value = "/depts", method = RequestMethod.GET)
@GetMapping
public Result list(){
//System.out.println("查询部门列表");
log.info("查询部门列表");
List<Dept> deptList = deptService.findAll();
return Result.success(deptList);
}
/**
* 根据id删除部门 - delete http://localhost:8080/depts?id=1
*/
@DeleteMapping
public Result delete(Integer id){
//System.out.println("根据id删除部门, id=" + id);
log.info("根据id删除部门, id: {}" , id);
deptService.deleteById(id);
return Result.success();
}
/**
* 新增部门 - POST http://localhost:8080/depts 请求参数:{"name":"研发部"}
*/
@PostMapping
public Result save(@RequestBody Dept dept){
//System.out.println("新增部门, dept=" + dept);
log.info("新增部门, dept: {}" , dept);
deptService.save(dept);
return Result.success();
}
/**
* 根据ID查询 - GET http://localhost:8080/depts/1
*/
@GetMapping("/{id}")
public Result getById(@PathVariable Integer id){
//System.out.println("根据ID查询, id=" + id);
log.info("根据ID查询, id: {}" , id);
Dept dept = deptService.getById(id);
return Result.success(dept);
}
/**
* 修改部门 - PUT http://localhost:8080/depts 请求参数:{"id":1,"name":"研发部"}
*/
@PutMapping
public Result update(@RequestBody Dept dept){
//System.out.println("修改部门, dept=" + dept);
log.info("修改部门, dept: {}" , dept);
deptService.update(dept);
return Result.success();
}
}
lombok中提供的@Slf4j注解,可以简化定义日志记录器这步操作。添加了该注解,就相当于在类中定义了日志记录器,就下面这句代码:
private static Logger log = LoggerFactory. getLogger(Xxx. class);
至此,部门管理的增删改查功能全部完成,并且添加了规范的日志记录。后续我们可以继续完善员工管理、报表统计等模块,整个实战篇稳步推进。
小结:本文从前后端分离模式出发,基于 RESTful 风格和 Apifox 工具,完整实现了部门管理的查询、删除、新增、修改功能,并引入了日志技术优化程序可观测性。希望这篇实战教程能帮你顺利上手 SpringBoot 后端开发!
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/2301_78993433/article/details/163397602








