3、后端框架搭建:Spring Boot项目创建、MyBatis-Plus集成、统一返回结果封装、全局异常处理
好,咱们正式开始动手了。这一章,我会带你把后端项目的骨架搭起来。说白了,就是让Spring Boot跑起来,连上数据库,再搞定接口的返回格式和异常处理。
我个人习惯,先把基础设施弄扎实了,后面写业务代码才不慌。你想想看,如果连统一返回格式都没有,每个接口返回的数据结构都不一样,前端同学不得疯掉?
3.1 Spring Boot项目创建
我用的是Spring Initializr,IDEA里直接新建项目就行。选Java 17,Spring Boot 2.7.x版本,这个版本比较稳,我在好几个生产项目里都用过。
依赖方面,先勾这几个核心的:
- Spring Web — 提供RESTful API能力
- Spring Boot DevTools — 热部署,改代码不用重启
- Lombok — 少写getter/setter,代码清爽
- MySQL Driver — 连数据库用
项目建好后,pom.xml里会自动生成这些依赖。不过别急,我们还要手动加MyBatis-Plus。
3.2 MyBatis-Plus集成
MyBatis-Plus,说白了就是MyBatis的增强版。它帮你把单表的CRUD都封装好了,你连SQL都不用写。
在pom.xml里加上这个:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
然后配置application.yml:
spring:
datasource:
url: jdbc:mysql://localhost:3306/oa_system?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: root
password: your_password
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
id-type: auto
logic-delete-field: deleted
logic-delete-value: 1
logic-not-delete-value: 0
嗯,这里要注意。逻辑删除字段我习惯叫deleted,0表示未删除,1表示已删除。这样删除数据时只是标记一下,不会真丢数据。
接下来,写一个BaseMapper:
public interface BaseMapper<T> extends com.baomidou.mybatisplus.core.mapper.BaseMapper<T> {
// 这里可以加一些公共方法
}
再写个配置类,扫描Mapper:
@Configuration
@MapperScan("com.oa.system.mapper")
public class MyBatisPlusConfig {
// 分页插件,这个很常用
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
3.3 统一返回结果封装
为什么需要统一返回结果?你想想看,如果每个接口返回的格式都不一样,前端处理起来得多痛苦。我见过一个项目,有的接口返回{code: 200, data: {...}},有的返回{success: true, result: {...}},前端同学直接崩溃。
我的做法是定义一个Result类:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result<T> {
private Integer code;
private String message;
private T data;
// 成功
public static <T> Result<T> success(T data) {
return new Result<>(200, "操作成功", data);
}
// 失败
public static <T> Result<T> error(Integer code, String message) {
return new Result<>(code, message, null);
}
// 带自定义消息的成功
public static <T> Result<T> success(String message, T data) {
return new Result<>(200, message, data);
}
}
这样,所有接口返回的都是Result对象。前端拿到数据后,先看code,如果是200就正常处理,否则弹个错误提示。
200成功、400参数错误、500服务器异常,这样更规范。
3.4 全局异常处理
程序跑起来,难免会出异常。如果每个接口都写try-catch,代码会变得很臃肿。我的做法是用@ControllerAdvice做全局异常处理。
先定义一个业务异常类:
@Data
@EqualsAndHashCode(callSuper = true)
public class BusinessException extends RuntimeException {
private Integer code;
public BusinessException(Integer code, String message) {
super(message);
this.code = code;
}
public BusinessException(String message) {
super(message);
this.code = 400;
}
}
然后写全局异常处理器:
@RestControllerAdvice
public class GlobalExceptionHandler {
// 处理业务异常
@ExceptionHandler(BusinessException.class)
public Result<?> handleBusinessException(BusinessException e) {
return Result.error(e.getCode(), e.getMessage());
}
// 处理参数校验异常
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result<?> handleValidationException(MethodArgumentNotValidException e) {
String message = e.getBindingResult().getAllErrors().stream()
.map(DefaultMessageSourceResolvable::getDefaultMessage)
.collect(Collectors.joining(", "));
return Result.error(400, message);
}
// 处理其他未知异常
@ExceptionHandler(Exception.class)
public Result<?> handleException(Exception e) {
log.error("系统异常", e);
return Result.error(500, "服务器内部错误,请稍后重试");
}
}
这样,业务代码里只需要抛出BusinessException,全局处理器会自动捕获并返回统一格式的错误信息。
3.5 验证一下
写个简单的测试接口:
@RestController
@RequestMapping("/api/test")
public class TestController {
@GetMapping("/hello")
public Result<String> hello() {
return Result.success("Hello, OA System!");
}
@GetMapping("/error")
public Result<?> error() {
throw new BusinessException("这是一个测试异常");
}
}
启动项目,访问/api/test/hello,应该返回:
{
"code": 200,
"message": "操作成功",
"data": "Hello, OA System!"
}
访问/api/test/error,返回:
{
"code": 400,
"message": "这是一个测试异常",
"data": null
}
嗯,到这里,后端框架的基础就搭好了。下一章,我们会开始设计数据库表结构,然后写第一个业务模块——用户管理。
- Spring Boot项目创建,选对依赖
- MyBatis-Plus集成,配置数据源和分页插件
- 统一返回结果封装,用Result类规范接口格式
- 全局异常处理,用@ControllerAdvice统一捕获异常
记住,框架搭建是地基,地基稳了,后面盖楼才踏实。我曾经见过一个项目,框架没搭好就急着写业务,结果后面改接口格式改到崩溃。所以,别急,慢慢来。