jaysee-sjc头像
关注
【JavaWeb】Tlias智能学习辅助系统|后端Web实战(部门管理)封面图

【JavaWeb】Tlias智能学习辅助系统|后端Web实战(部门管理)

目录

前言

1. 准备工作

1.1 开发规范

1.1.1 前后端分离开发

1.1.2 RESTful 风格

1.1.3 Apifox

1.2 工程搭建

2. 查询部门

2.1 基本实现

需求

接口描述

实现思路

代码实现

接口测试

数据封装问题

2.2 前后端联调

3. 删除部门

3.1 需求

3.2 接口描述

3.3 思路分析

3.4 简单参数接收

3.5 代码实现

4. 新增部门

4.1 需求

4.2 接口描述

4.3 思路分析

4.4 JSON 参数接收

4.5 代码实现

5. 修改部门

5.1 查询回显

​编辑

接口描述

路径参数接收

代码实现

5.2 修改数据

需求

接口描述

代码实现

5.2.5 抽取公共路径

6. 日志技术

6.1 概述

6.2 日志框架简介

6.3 Logback 快速入门

6.4 配置文件详解

6.5 在项目中使用


前言

前面我们已经一起学习了 Web 开发的基础知识,包括 Maven、HTTP 协议、SpringBoot Web 基础、IOC、DI、MySQL、JDBC、Mybatis 等。现在我们正式进入后端 Web 实战篇,把这些基础串联起来,完成一个综合案例 —— Tlias 智能学习辅助系统

这个系统将包含以下功能:

  • 部门管理

  • 员工管理

  • 员工信息统计

  • 学员信息统计

  • 班级、学员管理

今天我们就来搞定第一个模块:部门管理。从环境搭建到接口实现,再到前后端联调,一站式拿下!


1. 准备工作

1.1 开发规范

1.1.1 前后端分离开发

现代企业项目开发主要有两种模式:前后台混合开发 和 前后台分离开发

前后台混合开发 时,前端页面和后端代码混在同一个工程里:

这种模式的缺点很明显:

  • 沟通成本高:后台人员发现前端问题要找前端改,前端改完再丢给后台。

  • 分工不明确:后台不仅要写 Java,还得写部分前端代码,难以培养专精人才。

  • 管理不便:所有代码塞在一个工程里,容易混乱。

  • 维护困难:前端一个样式调整,可能就得把整个工程重新打包部署。

所以现在主流都是 前后台分离开发

我们将工程拆分为前端工程后端工程,分别交给专业的前端和后端人员。前端通过异步请求(Ajax)从后端获取数据。那问题来了:前端怎么知道后端返回什么格式?后端又怎么知道前端需要什么数据?

答案就是 接口文档。前后端共同约定一套接口规范,大家按照文档各写各的,最后联调对接。接口文档通常由后端根据产品原型和需求文档编写,有离线版和在线版。

后端开发流程 总结为:

  1. 需求分析:阅读需求文档,理解要做什么。

  2. 接口定义:查看接口文档,明确地址、参数、响应格式等。

  3. 前后端并行开发:各自按文档开发。

  4. 各自测试:后端用工具测接口,前端用 Mock 数据测页面。

  5. 前后端联调:把前端请求指到真实后端,打通整个流程。

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

在前后端分离并行开发时,有两个现实问题:

  • 后端写完接口,怎么方便地测试?

  • 前端还在开发,怎么拿到数据来渲染页面?

这时候就需要借助接口测试工具,比如 PostmanApipost,以及我们课程中使用的 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 前后端联调

接口测试通过后,我们还要和真实前端环境联调。

步骤

  1. 将资料中的“前端环境”压缩包解压到无中文、无空格的目录。

  2. 双击 nginx.exe 启动 Nginx(任务管理器里能看到两个 nginx 进程即成功)。

  3. 浏览器访问 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:执行 delete SQL。

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 概述

什么是日志?
日志就像程序的“日记本”,记录运行信息、状态、错误等。

为什么需要日志?

  1. 追踪程序执行过程和数据

  2. 性能优化分析

  3. 排查问题

  4. 监控系统状态

之前我们常用 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

文章来源crawl

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--