一、核心概念
什么是 Controller 代码生成?
MyBatis-Plus 的代码生成器(AutoGenerator
)不仅可以生成 Entity、Mapper、Service,还可以自动生成基于 Spring MVC 的 RESTful 风格 Controller 类,包含常见的 CRUD 接口:
GET /entity
:分页查询GET /entity/{id}
:根据 ID 查询POST /entity
:新增PUT /entity
:更新DELETE /entity/{id}
:删除
生成 Controller 的作用
- 快速搭建后端接口原型
- 统一接口风格(命名、返回格式)
- 减少样板代码编写
- 提高开发效率(尤其在项目初期或管理后台)
二、操作步骤(超详细)
第一步:添加必要依赖
确保 pom.xml
中包含以下依赖:
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MyBatis-Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.6</version>
</dependency>
<!-- MyBatis-Plus 代码生成器 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.6</version>
</dependency>
<!-- 模板引擎:Velocity(默认) -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version>
</dependency>
<!-- Lombok(可选但推荐) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
⚠️ 注意:
lombok
需要在 IDE 中安装插件才能识别注解。
第二步:创建代码生成器主类
创建 src/test/java/com/example/generator/CodeGenerator.java
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import java.util.Collections;
public class CodeGenerator {
public static void main(String[] args) {
generate();
}
private static void generate() {
FastAutoGenerator.create(
"jdbc:mysql://localhost:3306/your_db?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8",
"root",
"your_password"
)
// 全局配置
.globalConfig(builder -> {
builder.author("Your Name") // 作者
.outputDir(System.getProperty("user.dir") + "/src/main/java") // 输出到 java 目录
.commentDate("yyyy-MM-dd HH:mm:ss") // 注释日期格式
.disableOpenDir(); // 生成后不打开文件夹
})
// 包配置
.packageConfig(builder -> {
builder.parent("com.example.demo") // 父包名
.moduleName("system") // 模块名(可选)
.controller("controller"); // Controller 包路径
})
// 策略配置
.strategyConfig(builder -> {
builder.controllerBuilder()
.enableRestStyle() // 使用 @RestController
.enableHyphenStyle() // URL 驼峰转连字符(如 /user-info)
.formatFileName("%sController") // Controller 类命名格式
.build();
// 指定要生成 Controller 的表
builder.addInclude("user", "role", "dept") // 包含的表
.addTablePrefix("t_", "sys_"); // 过滤表前缀
})
// 执行生成
.execute();
}
}
第三步:运行生成器
- 右键运行
CodeGenerator.main()
方法 - 观察控制台输出:
==> 作者: Your Name ==> 生成包路径: com.example.demo.system.controller ==> 生成表: user, role, dept ==> 生成完成!
- 检查
src/main/java/com/example/demo/system/controller/
目录下是否生成了:UserController.java
RoleController.java
DeptController.java
第四步:生成的 Controller 示例(UserController.java)
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping // 分页查询
public Result<?> selectPage(Page<User> page, User user) {
Page<User> result = userService.page(page, Wrappers.query(user));
return Result.ok(result);
}
@GetMapping("/{id}") // 根据 ID 查询
public Result<User> getById(@PathVariable Long id) {
User user = userService.getById(id);
return Result.ok(user);
}
@PostMapping // 新增
public Result<User> save(@RequestBody User user) {
userService.save(user);
return Result.ok(user);
}
@PutMapping // 更新
public Result<User> update(@RequestBody User user) {
userService.updateById(user);
return Result.ok(user);
}
@DeleteMapping("/{id}") // 删除
public Result<?> delete(@PathVariable Long id) {
userService.removeById(id);
return Result.ok();
}
}
⚠️ 注意:
Result
是 MP Generator 默认使用的返回类型,实际项目中建议替换为自定义统一返回类。
三、常见错误与解决方案
错误现象 | 原因 | 解决方案 |
---|---|---|
ClassNotFoundException: org.springframework.web.bind.annotation.RestController |
缺少 spring-boot-starter-web |
添加 Web 依赖 |
Controller 未生成 | .controllerBuilder() 未调用或 .disable(TemplateType.CONTROLLER) |
确保启用 Controller 生成 |
URL 路径带下划线(如 /user_info ) |
未启用 enableHyphenStyle() |
添加 .enableHyphenStyle() |
生成路径错误(如生成到 test 目录) | outputDir 设置错误 |
设置为 src/main/java |
中文乱码 | 文件编码问题 | 确保项目编码为 UTF-8 |
@Autowired 报错 |
Service 未生成或包扫描问题 | 检查 Service 是否生成,确认 Spring 扫描路径 |
四、注意事项
- ✅ Controller 依赖 Service:必须先生成或存在对应的
UserService
接口及实现类。 - ✅ 包扫描:确保 Spring Boot 主类能扫描到生成的 Controller(通常父包一致即可)。
- ✅ 统一返回格式:默认的
Result
类可能不符合项目规范,建议自定义模板替换。 - ✅ 权限控制:生成的接口无权限校验,需手动添加
@PreAuthorize
或拦截器。 - ✅ 参数校验:生成的接口无参数校验,需手动添加
@Valid
、@NotBlank
等。 - ✅ 异常处理:建议配合
@ControllerAdvice
全局异常处理。 - ✅ 不要覆盖已有文件:默认会覆盖同名文件,建议首次生成前备份。
五、使用技巧
1. 自定义 Controller 模板
复制默认模板到 resources/templates/controller.java.vm
并修改:
package ${package.Controller};
import org.springframework.web.bind.annotation.*;
import ${package.Service}.${serviceClass};
import ${package.Entity}.${entity};
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.common.Result; // 自定义 Result
import javax.annotation.Resource;
@RestController
@RequestMapping("/${table.entityPath}")
public class ${table.controllerName} {
@Resource
private ${serviceClass} ${serviceInstance};
@GetMapping
public Result<Page<${entity}>> list(Page<${entity}> page, ${entity} ${entityProperty}) {
Page<${entity}> data = ${serviceInstance}.page(page, new QueryWrapper<>(${entityProperty}));
return Result.success(data);
}
@GetMapping("/{id}")
public Result<${entity}> getById(@PathVariable ${keyPropertyType} id) {
${entity} data = ${serviceInstance}.getById(id);
return Result.success(data);
}
@PostMapping
public Result<${entity}> create(@RequestBody ${entity} ${entityProperty}) {
${serviceInstance}.save(${entityProperty});
return Result.success(${entityProperty});
}
@PutMapping
public Result<${entity}> update(@RequestBody ${entity} ${entityProperty}) {
${serviceInstance}.updateById(${entityProperty});
return Result.success(${entityProperty});
}
@DeleteMapping("/{id}")
public Result<Void> delete(@PathVariable ${keyPropertyType} id) {
${serviceInstance}.removeById(id);
return Result.success();
}
}
在生成器中指定模板:
.templateConfig(builder -> { builder.controller("/templates/controller.java.vm"); })
2. 禁用特定方法
.controllerBuilder()
.disableRestStyle() // 禁用 @RestController
.disableHyphenStyle() // 禁用连字符风格
.disableRequestMappingAnnot() // 禁用 @RequestMapping
.build();
3. 添加自定义注解
.controllerBuilder()
.customAnnotations(
Collections.singletonList(
new CustomAnnotation().setAnnotation("@Log(operation = \"查询用户\")")
)
)
.build();
六、最佳实践与性能优化
✅ 最佳实践
实践 | 说明 |
---|---|
✅ 生成后立即审查 | 检查接口命名、参数、返回值是否符合规范 |
✅ 添加参数校验 | 为 @RequestBody 添加 @Valid 和 @NotBlank 等 |
✅ 添加权限注解 | 如 @PreAuthorize("hasAuthority('user:add')") |
✅ 统一返回格式 | 使用 Result<T> 包装返回数据 |
✅ 添加 API 文档 | 配合 @Api 、@ApiOperation 生成 Swagger 文档 |
✅ 分页查询加条件 | 在 list 方法中支持动态查询条件 |
✅ 异常统一处理 | 使用 @ControllerAdvice 处理业务异常 |
⚡ 性能优化建议
- ❌ 不要为所有表生成 Controller(如字典表、中间表)
- ✅ 对高频查询接口添加缓存(
@Cacheable
) - ✅ 分页接口注意
pageSize
上限(防止pageSize=10000
) - ✅ 删除操作建议改为逻辑删除(避免误删)
- ✅ 批量操作接口需加限流(防止刷单)
七、完整增强版生成器示例
FastAutoGenerator.create(url, username, password)
.globalConfig(builder -> {
builder.author("Admin")
.outputDir(System.getProperty("user.dir") + "/src/main/java")
.commentDate("yyyy-MM-dd")
.disableOpenDir();
})
.packageConfig(builder -> {
builder.parent("com.example.demo")
.moduleName("system")
.controller("controller")
.service("service")
.serviceImpl("service.impl")
.entity("entity")
.mapper("mapper");
})
.strategyConfig(builder -> {
builder.addInclude("user", "role")
.addTablePrefix("t_");
// 实体配置
builder.entityBuilder()
.enableLombok()
.enableTableFieldAnnotation()
.logicDeleteColumnName("deleted")
.versionColumnName("version");
// Controller 配置
builder.controllerBuilder()
.enableRestStyle()
.enableHyphenStyle()
.formatFileName("%sController");
// Service 配置
builder.serviceBuilder()
.formatServiceFileName("%sService")
.formatServiceImplFileName("%sServiceImpl");
})
.templateConfig(builder -> {
// 可指定自定义模板路径
})
.execute();
总结
MyBatis-Plus 生成 Controller 是快速搭建后端接口的利器,特别适合管理后台、CRUD 频繁的场景。通过合理配置 .controllerBuilder()
,可生成符合 RESTful 规范的接口。