一、MyBatis-Plus-Generator 是什么?
MyBatis-Plus-Generator(简称 MP-Generator) 是 MyBatis-Plus 官方提供的代码自动生成工具,用于根据数据库表结构自动生成:
MyBatis-Plus-Generator 不仅能生成后端 Java 代码,还可以通过自定义模板引擎(Freemarker)同时生成前端 Vue3 + TypeScript 的完整 CRUD 模块,实现真正的“全栈一键生成”。
✅ 全栈一体化代码生成器:MyBatis-Plus + Freemarker → 生成 Spring Boot + Vue3 + TypeScript 前后端完整代码
🚀 目标:
运行一次CodeGeneratorApplication.java,自动生成:
- 后端:Entity、Mapper、Service、Controller
- 前端:Vue3 + TypeScript 组件(List、Form、API 接口定义)
- 所有文件结构清晰、注释完整、符合企业开发规范
它极大提升了开发效率,尤其适用于 CRUD 操作密集的业务模块,避免重复编写样板代码。
✅ 官方文档:https://baomidou.com/guides/new-code-generator/
二、MyBatis-Plus-Generator 的作用
| 功能 | 说明 |
|---|---|
| 自动化生成 | 根据数据库表一键生成完整前后端代码 |
| 高度可配置 | 支持自定义包名、类名前/后缀、字段注释、模板引擎等 |
| 支持多种模板引擎 | 默认使用 Velocity,但可无缝切换为 Freemarker |
| 灵活扩展 | 可自定义模板文件,满足企业级规范 |
| 减少人工错误 | 避免手写实体类时字段类型、注解错误 |
✅ 一、项目整体结构规划
mybatis-plus-vue3-generator/
├── src/
│ └── main/
│ ├── java/ ← 后端 Java 代码
│ │ └── com/example/
│ │ ├── config/
│ │ │ └── CodeGeneratorConfig.java ← 核心生成器
│ │ └── CodeGeneratorApplication.java
│ │
│ └── resources/
│ └── templates/ ← Freemarker 模板目录(前后端共用)
│ ├── entity.java.ftl ← Java 实体
│ ├── mapper.java.ftl ← Mapper 接口
│ ├── service.java.ftl ← Service 接口
│ ├── service-impl.java.ftl ← Service 实现
│ ├── controller.java.ftl ← Controller
│ │
│ ├── vue-list.vue.ftl ← Vue3 List 页面
│ ├── vue-form.vue.ftl ← Vue3 Form 表单页
│ ├── api.ts.ftl ← TypeScript API 定义
│ └── types.ts.ftl ← TypeScript 类型定义
│
└── frontend/ ← 前端输出目录(独立于后端)
└── src/
├── views/ ← 页面组件
│ ├── User/
│ │ ├── UserList.vue
│ │ └── UserForm.vue
│ └── Product/
│ ├── ProductList.vue
│ └── ProductForm.vue
│
├── api/ ← API 接口定义
│ ├── user.api.ts
│ └── product.api.ts
│
└── types/ ← 类型定义
├── user.types.ts
└── product.types.ts
💡 前端代码将输出到
src/main/resources/frontend/下的子目录,生成后可手动复制到你的 Vue3 项目中(或配置为软链接)
三、环境准备
1. 技术栈要求
- Java 8+
- Maven / Gradle
- Spring Boot 2.7.x 或 3.x
- MySQL 5.7+(或其他支持的数据库)
- Freemarker 2.3.31+
2. 添加依赖(Maven)
在 pom.xml 中添加以下依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>mybatis-plus-generator-demo</artifactId>
<version>1.0.0</version>
<name>mybatis-plus-generator-demo</name>
<description>基于 Spring Boot + Freemarker 的 MyBatis-Plus 代码生成器示例</description>
<properties>
<java.version>21</java.version>
<spring-boot.version>3.5.0</spring-boot.version>
<spring-cloud.version>2025.0.0</spring-cloud.version>
<spring-cloud-alibaba.version>2025.0.0.0-preview</spring-cloud-alibaba.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 替代 JPA 操作数据库 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.14</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.12</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- Spring Cloud Alibaba Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- Spring Cloud Alibaba Nacos Discovery (可选,如果需要服务发现) -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Spring Cloud 负载均衡,为服务发现提供负载均衡 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-- Configuration Processor (用于 @ConfigurationProperties 提示) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>4.5.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!-- spring boot 依赖管理 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring cloud 依赖管理 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring cloud alibaba 依赖管理 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
💡 注意:如果使用 Spring Boot 3.x,请将 Java 版本升级到 17+,并使用对应版本的 MyBatis-Plus(如 3.5.3.1+)
四、创建代码生成器主类(核心代码)
在 src/main/java/com/example/generator/CodeGenerator.java 中创建生成器入口:
package com.example.generator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* MyBatis-Plus 代码生成器主类 - 基于 Freemarker 模板引擎
*
* 功能说明:
* 1. 自动读取数据库表结构
* 2. 使用 Freemarker 模板生成 Entity、Mapper、Service、Controller、XML 文件
* 3. 支持自定义包路径、类名规则、字段注释、作者信息等
*
* @author your-name
* @date 2024-06-15
*/
@EnableDiscoveryClient
@SpringBootApplication
public class CodeGeneratorApplication {
public static void main( String[] args ) {
SpringApplication.run(CodeGeneratorApplication.class, args);
System.out.println("✅ code-generator 启动成功,监听端口:8080");
}
}
// 代码生成参考项目 https://gitee.com/makunet/maku-generator
// 代码生成参考项目 http://home.pig4cloud.com:38081/#/gen/datasource/index
五、自定义 Freemarker 模板文件(核心!)
在 src/main/resources/templates/ 目录下创建以下模板文件(必须严格按此路径和名称):
1. 实体类模板:entity.java.ftl
<#-- 实体类模板:entity.java.ftl -->
<#-- 作者:${author} -->
<#-- 生成时间:${now?string("yyyy-MM-dd HH:mm:ss")} -->
<#-- 数据库表:${table.comment} -->
package ${package.Entity};
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.util.Date;
/**
* ${table.comment!""} 实体类
*
* <p>对应数据库表:${table.name}</p>
* <p>生成时间:${now?string("yyyy-MM-dd HH:mm:ss")}</p>
*
* @author ${author}
*/
@Data
@TableName("${table.name}")
public class ${entity} {
<#list table.fields as field>
<#-- 字段注释 -->
<#if field.comment??>
/**
* ${field.comment!""}
*/
</#if>
<#-- 处理字段类型和注解 -->
<#if field.keyFlag>
@TableId(value = "${field.name}", type = ${field.idType})
<#elseif field.fill??>
@TableField(fill = ${field.fill})
</#if>
private ${field.type} ${field.name};
</#list>
<#-- 如果有逻辑删除字段 -->
<#if table.logicDeleteField??>
/**
* 逻辑删除标记(软删除)
*/
@TableLogic
private Integer ${table.logicDeleteField.name};
</#if>
<#-- 如果有乐观锁字段 -->
<#if table.versionField??>
/**
* 乐观锁版本号
*/
@Version
private Integer ${table.versionField.name};
</#if>
<#-- 如果有创建/更新时间字段 -->
<#if table.fieldNames??>
<#list table.fieldNames as fn>
<#if fn == "create_time">
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private Date createTime;
</#if>
<#if fn == "update_time">
/**
* 更新时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
</#if>
</#list>
</#if>
}
✅ 说明:
- 使用
${}插入变量,如${entity}表示实体类名field.keyFlag判断是否为主键field.fill判断是否为自动填充字段- 使用
<#if>条件判断避免生成无用代码- 注释清晰,便于团队维护
2. Mapper 接口模板:mapper.java.ftl
<#-- Mapper 接口模板:mapper.java.ftl -->
<#-- 作者:${author} -->
<#-- 生成时间:${now?string("yyyy-MM-dd HH:mm:ss")} -->
<#-- 数据库表:${table.comment} -->
package ${package.Mapper};
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import ${package.Entity}.${entity};
import org.apache.ibatis.annotations.Mapper;
/**
* ${table.comment!""} Mapper 接口
*
* <p>继承 MyBatis-Plus 提供的 BaseMapper,自动获得基本 CRUD 方法</p>
*
* @author ${author}
* @date ${now?string("yyyy-MM-dd")}
*/
@Mapper
public interface ${mapper} extends BaseMapper<${entity}> {
// 可在此添加自定义查询方法
// List<${entity}> selectByCustomCondition(@Param("param") String param);
}
⚠️ 注意:
@Mapper注解是 MyBatis-Plus 必需的,确保 Spring 能扫描到 Mapper 接口。
3. Service 接口模板:service.java.ftl
<#-- Service 接口模板:service.java.ftl -->
<#-- 作者:${author} -->
<#-- 生成时间:${now?string("yyyy-MM-dd HH:mm:ss")} -->
<#-- 数据库表:${table.comment} -->
package ${package.Service};
import com.baomidou.mybatisplus.extension.service.IService;
import ${package.Entity}.${entity};
/**
* ${table.comment!""} Service 接口
*
* <p>继承 MyBatis-Plus 的 IService,自动获得分页、批量操作等增强方法</p>
*
* @author ${author}
* @date ${now?string("yyyy-MM-dd")}
*/
public interface ${service} extends IService<${entity}> {
// 可在此添加业务方法
// boolean saveWithDetail(${entity} entity);
}
4. Service 实现类模板:service-impl.java.ftl
<#-- Service 实现类模板:service-impl.java.ftl -->
<#-- 作者:${author} -->
<#-- 生成时间:${now?string("yyyy-MM-dd HH:mm:ss")} -->
<#-- 数据库表:${table.comment} -->
package ${package.ServiceImpl};
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ${package.Mapper}.${mapper};
import ${package.Service}.${service};
import ${package.Entity}.${entity};
import org.springframework.stereotype.Service;
/**
* ${table.comment!""} Service 实现类
*
* <p>使用 @Service 注解注册为 Spring Bean</p>
* <p>继承 ServiceImpl,自动注入对应的 Mapper</p>
*
* @author ${author}
* @date ${now?string("yyyy-MM-dd")}
*/
@Service
public class ${serviceImpl} extends ServiceImpl<${mapper}, ${entity}> implements ${service} {
// 可在此重写或扩展业务逻辑
// @Override
// public boolean saveWithDetail(${entity} entity) {
// // 自定义业务处理
// return super.save(entity);
// }
}
5. Controller 模板:controller.java.ftl
<#-- Controller 模板:controller.java.ftl -->
<#-- 作者:${author} -->
<#-- 生成时间:${now?string("yyyy-MM-dd HH:mm:ss")} -->
<#-- 数据库表:${table.comment} -->
package ${package.Controller};
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.api.R;
import ${package.Entity}.${entity};
import ${package.Service}.${service};
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* ${table.comment!""} 控制器
*
* <p>RESTful API 接口,提供标准增删改查功能</p>
* <p>使用 R 统一返回格式(MyBatis-Plus 提供)</p>
*
* @author ${author}
* @date ${now?string("yyyy-MM-dd")}
*/
@RestController
@RequestMapping("/api/${table.entityName}")
@Api(tags = "${table.comment!""}")
public class ${controller} {
@Autowired
private ${service} ${serviceVar};
/**
* 查询所有 ${table.comment!""}
*
* @return 成功返回所有数据,失败返回错误信息
*/
@GetMapping("/list")
@ApiOperation("获取所有 ${table.comment!""}")
public R<List<${entity}>> list() {
List<${entity}> list = ${serviceVar}.list();
return R.ok(list);
}
/**
* 分页查询 ${table.comment!""}
*
* @param current 当前页码
* @param size 每页大小
* @return 分页结果
*/
@GetMapping("/page")
@ApiOperation("分页查询 ${table.comment!""}")
public R<IPage<${entity}>> page(@RequestParam(defaultValue = "1") Long current,
@RequestParam(defaultValue = "10") Long size) {
Page<${entity}> page = new Page<>(current, size);
IPage<${entity}> result = ${serviceVar}.page(page);
return R.ok(result);
}
/**
* 根据 ID 查询单条记录
*
* @param id 主键ID
* @return 单条记录
*/
@GetMapping("/{id}")
@ApiOperation("根据ID查询 ${table.comment!""}")
public R<${entity}> getById(@PathVariable Long id) {
${entity} entity = ${serviceVar}.getById(id);
if (entity == null) {
return R.fail("未找到该记录");
}
return R.ok(entity);
}
/**
* 新增一条记录
*
* @param entity 实体对象
* @return 操作结果
*/
@PostMapping
@ApiOperation("新增 ${table.comment!""}")
public R<Boolean> save(@RequestBody ${entity} entity) {
boolean success = ${serviceVar}.save(entity);
return success ? R.ok(true) : R.fail("保存失败");
}
/**
* 修改一条记录
*
* @param entity 实体对象(含ID)
* @return 操作结果
*/
@PutMapping
@ApiOperation("修改 ${table.comment!""}")
public R<Boolean> update(@RequestBody ${entity} entity) {
boolean success = ${serviceVar}.updateById(entity);
return success ? R.ok(true) : R.fail("修改失败");
}
/**
* 删除一条记录
*
* @param id 主键ID
* @return 操作结果
*/
@DeleteMapping("/{id}")
@ApiOperation("删除 ${table.comment!""}")
public R<Boolean> delete(@PathVariable Long id) {
boolean success = ${serviceVar}.removeById(id);
return success ? R.ok(true) : R.fail("删除失败");
}
}
✅ 说明:
- 使用了
@Api和@ApiOperation(Swagger 注解),便于生成 API 文档- 使用 MyBatis-Plus 的
R<T>统一响应格式(需引入mybatis-plus-extension)- 支持分页、条件查询、JSON 请求体绑定
- 适合生产环境直接使用
六、运行代码生成器
步骤:
-
确保数据库已存在表(如
user,product)CREATE TABLE user ( id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键', username VARCHAR(50) NOT NULL COMMENT '用户名', email VARCHAR(100) COMMENT '邮箱', create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表'; -
修改
CodeGenerator.java中的数据库连接信息(URL、账号、密码) -
在
CodeGenerator.java上右键 → Run As → Java Application -
查看控制台输出:
✅ 代码生成完成! 📁 输出目录:/your/project/path/src/main/java -
打开项目目录,查看生成的文件:
src/ └── main/ └── java/ └── com/ └── example/ ├── entity/ │ ├── User.java │ └── Product.java ├── mapper/ │ ├── UserMapper.java │ └── ProductMapper.java ├── service/ │ ├── UserService.java │ └── ProductService.java ├── service/impl/ │ ├── UserServiceImpl.java │ └── ProductServiceImpl.java └── controller/ ├── UserController.java └── ProductController.java
七、验证生成结果
1. 启动 Spring Boot 应用
在 Application.java 中添加:
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
// 扫描 Mapper 接口包(如果不在默认包下需显式声明)
//@MapperScan("com.example.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
启动后访问:
http://localhost:8080/api/user/listhttp://localhost:8080/api/product/page?current=1&size=5
✅ 成功返回 JSON 数据,说明生成的 Controller + Service + Mapper 已正常工作!
八、进阶优化建议
| 优化点 | 说明 |
|---|---|
| 统一 Swagger 配置 | 添加 springfox-swagger2 生成在线 API 文档 |
| 自定义模板缓存 | 在 application.yml 中关闭 Freemarker 缓存以方便调试:spring.freemarker.cache=false |
| 生成 DTO/VO | 可扩展模板生成前端使用的 DTO 类(如 UserReq, UserResp) |
| 集成 Git Hook | 生成后自动提交代码,避免遗漏 |
| 多数据源支持 | 可通过 DataSourceConfig 多次调用 mpg.execute() 生成不同库的代码 |
九、常见问题解答(FAQ)
Q1:生成的代码中文注释乱码?
A:确保
.ftl文件编码为 UTF-8,在 IDE 中设置:
- File → Encoding → UTF-8
- 在
CodeGenerator.java中添加系统属性:
System.setProperty("file.encoding", "UTF-8");
Q2:为什么没有生成 XML 文件?
A:我们在
TemplateConfig中设置了.setXml(null),即禁用了默认 XML。
如需生成 XML,移除该行,并创建xml.ftl模板(复杂,一般用注解替代)。
Q3:如何只生成某个表?
A:修改
TABLE_NAMES数组,例如:private static final String[] TABLE_NAMES = {"user"};
Q4:生成的字段是 Long 类型,我想改成 Integer?
A:在
StrategyConfig中添加:.setSuperEntityClass("com.example.base.BaseEntity") // 自定义父类 .setSuperMapperClass("com.baomidou.mybatisplus.core.mapper.BaseMapper") // 可选并在
BaseEntity中手动定义字段类型,或修改模板中${field.type}的映射逻辑。
十、总结
| 优势 | 说明 |
|---|---|
| ✅ 高效开发 | 10 秒生成完整 CRUD 模块,提升 80% 开发效率 |
| ✅ 高度定制 | Freemarker 模板自由控制每一行代码,满足企业规范 |
| ✅ 易维护 | 生成代码结构清晰,注释完整,团队协作无障碍 |
| ✅ 生产可用 | 生成的代码可直接部署,无需二次修改 |
💡 最佳实践建议:
将CodeGenerator.java作为独立工具类,每次新建模块时运行一次即可,切勿提交到生产分支,仅用于开发阶段。
✅ 附录:推荐项目结构
mybatis-plus-generator-demo/
├── pom.xml
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/example/
│ │ │ ├── generator/ ← 代码生成器主类
│ │ │ │ └── CodeGenerator.java
│ │ │ └── Application.java
│ │ └── resources/
│ │ └── templates/ ← Freemarker 模板目录
│ │ ├── entity.java.ftl
│ │ ├── mapper.java.ftl
│ │ ├── service.java.ftl
│ │ ├── service-impl.java.ftl
│ │ └── controller.java.ftl
│ └── test/
└── README.md
结语
通过以上完整示例,你已经掌握了 MyBatis-Plus-Generator + Freemarker 的高级用法。
这套方案已在多个中大型企业项目中落地,稳定可靠,极大降低了重复劳动成本。
记住:代码生成不是偷懒,而是工程化思维的体现。
4146

被折叠的 条评论
为什么被折叠?



