MyBatis-Plus 提供了强大的代码生成器(AutoGenerator
),支持高度可定制的模板引擎(如 Freemarker、Velocity)。通过自定义模板配置,开发者可以完全控制生成的 Entity、Mapper、Service、Controller 等代码的结构、命名、注释、注解、格式等,满足企业级开发规范和个性化需求。
一、核心概念
1.1 模板引擎(Template Engine)
- MyBatis-Plus 支持 Freemarker 和 Velocity 两种模板引擎。
- 模板文件是
.ftl
(Freemarker)或.vm
(Velocity)格式,包含变量和逻辑控制语句。 - 生成器会将数据库元数据(表名、字段、类型等)填充到模板中,输出 Java 文件。
1.2 自定义模板(Custom Template)
- 默认模板位于
mybatis-plus-generator
jar 包内。 - 可通过
templateEngine()
和template()
方法指定自定义模板路径,覆盖默认行为。 - 支持为 Entity、Mapper、Service、Controller、XML 等分别设置模板。
1.3 模板变量(Template Variables)
- 在模板中可使用的变量,如:
entity
:实体类名table
:表信息对象(含字段列表)package
:包信息importPackages
:导入包列表field
:字段对象(含字段名、类型、注释等)
二、操作步骤(非常详细)
以下步骤基于 Spring Boot + MyBatis-Plus + Freemarker 实现自定义模板配置。
步骤 1:添加依赖(Maven)
确保已包含以下依赖:
<!-- MyBatis-Plus Generator -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.3</version>
</dependency>
<!-- Freemarker 模板引擎 -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.32</version>
</dependency>
<!-- Lombok(用于生成 @Data 等注解) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
✅ 建议使用最新稳定版本,避免兼容性问题。
步骤 2:创建自定义模板文件
在 resources/templates
目录下创建自定义模板文件(若不存在请手动创建):
示例 1:自定义 Entity 模板(entity.java.ftl
)
<#assign className = table.entityName>
<#assign packageOutPath = package.entity>
<#assign autoResultMap = table.commonFieldList?size gt 0>
package ${packageOutPath};
<#if swagger2>
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
</#if>
<#if entityLombokModel>
import lombok.Data;
<#if chainModel>
import lombok.experimental.Accessors;
</#if>
</#if>
import java.io.Serializable;
<#list table.importPackages as pkg>
import ${pkg};
</#list>
<#if table.convert>
import com.baomidou.mybatisplus.annotation.TableName;
</#if>
/**
* <p>
* ${table.comment!}
* </p>
*
* @author ${author}
* @since ${date}
*/
<#if table.convert>
@TableName("${table.name}")
</#if>
<#if entityLombokModel>
@Data
<#if chainModel>
@Accessors(chain = true)
</#if>
</#if>
<#if swagger2>
@ApiModel(value = "${className}对象", description = "${table.comment!}")
</#if>
public class ${className} implements Serializable {
private static final long serialVersionUID = 1L;
<#-- 主键字段 -->
<#list table.pkFields as field>
<#if swagger2>
@ApiModelProperty(value = "${field.comment}")
</#if>
private ${field.propertyType} ${field.propertyName};
</#list>
<#-- 普通字段 -->
<#list table.commonFields as field>
<#if swagger2>
@ApiModelProperty(value = "${field.comment}")
</#if>
private ${field.propertyType} ${field.propertyName};
</#list>
<#-- toString, equals, hashCode 可选生成 -->
<#if !entityLombokModel>
@Override
public String toString() {
return "${className}{" +
<#list table.fields as field>
"${field.propertyName}=" + ${field.propertyName}<#if field_has_next> + ", "</#if>
</#list>
"}";
}
</#if>
}
示例 2:自定义 Mapper 模板(mapper.java.ftl
)
<#assign className = table.mapperName>
<#assign packageOutPath = package.mapper>
package ${packageOutPath};
import ${package.entity}.${entity};
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
/**
* <p>
* ${table.comment!} Mapper 接口
* </p>
*
* @author ${author}
* @since ${date}
*/
@Mapper
@Repository
public interface ${className} extends BaseMapper<${entity}> {
// 可在此添加自定义方法声明
}
💡 你可以根据公司规范添加日志、事务、权限注解等。
步骤 3:编写代码生成器(CodeGenerator.java)
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.TemplateType;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import java.util.Collections;
public class CodeGenerator {
public static void main(String[] args) {
FastAutoGenerator.create("jdbc:mysql://localhost:3306/test_db", "root", "your_password")
.globalConfig(builder -> {
builder.author("Your Name") // 作者
.outputDir(System.getProperty("user.dir") + "/src/main/java") // 输出目录
.commentDate("yyyy-MM-dd HH:mm:ss"); // 注释日期格式
})
.packageConfig(builder -> {
builder.parent("com.example") // 父包名
.moduleName("system") // 模块名
.pathInfo(Collections.singletonMap(OutputFile.mapper,
System.getProperty("user.dir") + "/src/main/java/com/example/mapper"));
})
.strategyConfig(builder -> {
builder.entityBuilder()
.naming(com.baomidou.mybatisplus.generator.config.NamingStrategy.underline_to_camel)
.columnNaming(com.baomidou.mybatisplus.generator.config.NamingStrategy.underline_to_camel)
.enableLombok()
.logicDeleteColumnName("deleted")
.addTableFills("create_time", "update_time"); // 自动填充字段
builder.mapperBuilder()
.enableFileOverride() // 允许覆盖(开发阶段可用)
.enableBaseResultMap()
.enableBaseColumnList();
builder.serviceBuilder()
.enableFileOverride();
builder.controllerBuilder()
.enableFileOverride();
builder.addInclude("user", "role", "dept"); // 指定表名
})
// 👇 自定义模板配置
.templateConfig(builder -> {
builder.entity("/templates/entity.java.ftl") // 自定义 Entity 模板
.mapper("/templates/mapper.java.ftl") // 自定义 Mapper 模板
.service("/templates/service.java.ftl") // 可自定义 Service 模板
.controller("/templates/controller.java.ftl"); // 可自定义 Controller 模板
})
.templateEngine(new FreemarkerTemplateEngine()) // 使用 Freemarker
.execute();
}
}
✅ 模板路径说明:
/templates/xxx.ftl
:表示resources/templates/
下的文件- 绝对路径如
file:/D:/templates/entity.java.ftl
步骤 4:运行生成器
运行 CodeGenerator.main()
方法,观察控制台输出:
...
Generator success!
Entity: com.example.entity.User
Mapper: com.example.mapper.UserMapper
...
检查生成的文件是否符合自定义模板内容。
三、常见错误与解决方案
错误 | 原因 | 解决方案 |
---|---|---|
Template not found |
模板路径错误或文件不存在 | 检查路径是否为 resources/templates/xxx.ftl ,确认文件存在 |
生成文件为空或乱码 | 模板语法错误 | 检查 .ftl 文件语法,使用 IDE 插件校验 |
变量未替换(如 ${entity} 显示原样) |
模板引擎未正确加载 | 确保 freemarker 依赖已引入,templateEngine() 设置正确 |
生成器不执行 | 数据库连接失败 | 检查 URL、用户名、密码、驱动版本 |
ClassNotFoundException |
缺少依赖 | 添加 freemarker 或 velocity 依赖 |
四、注意事项
模板路径必须正确:
- 推荐使用
resources/templates/
目录。 - 路径前加
/
表示类路径根目录。
- 推荐使用
避免覆盖重要文件:
- 生产环境慎用
enableFileOverride()
。 - 建议首次生成后关闭覆盖。
- 生产环境慎用
模板编码统一为 UTF-8:
- 防止中文注释乱码。
变量命名规范:
- 使用
table.entityName
、field.propertyName
等标准变量。
- 使用
逻辑删除与自动填充:
- 若启用,需在模板中处理对应字段。
五、使用技巧
5.1 动态控制生成内容
在模板中使用条件判断:
<#if table.fields?seq_contains("status")>
/**
* 状态字段存在,可添加状态枚举
*/
public static final Integer STATUS_ACTIVE = 1;
public static final Integer STATUS_INACTIVE = 0;
</#if>
5.2 添加公司注解或 AOP 标签
@Mapper
@Repository
@TargetDataSource("master") // 自定义数据源注解
@Transactional(readOnly = false)
public interface ${className} extends BaseMapper<${entity}> {
}
5.3 生成 Swagger 注解(可选)
通过 .globalConfig().enableSwagger()
启用:
builder.entityBuilder()
.enableLombok()
.enableSwagger(); // 启用 Swagger 注解
模板中添加:
<#if swagger>
@ApiModelProperty(value = "${field.comment}")
</#if>
5.4 自定义输出路径
.pathInfo(
Map.of(
OutputFile.entity, "D:/generated/entity",
OutputFile.mapper, "D:/generated/mapper"
)
)
六、最佳实践与性能优化
6.1 最佳实践
✅ 统一代码风格:
- 所有项目使用同一套模板,确保命名、注释、注解一致。
✅ 模板版本管理:
- 将模板文件纳入 Git 管理,团队共享。
✅ 模块化模板:
- 将公共部分(如注释头、导入包)抽为宏(macro),提高复用性。
✅ 生成后自动格式化:
- 配合
google-java-format
或 IDE 插件自动格式化代码。
✅ 结合 CI/CD:
- 在构建流程中集成代码生成,确保数据库变更后自动同步代码。
6.2 性能优化(间接)
虽然模板本身不影响运行时性能,但良好的生成策略可提升开发效率:
- 减少冗余代码:模板中避免生成无用方法。
- 合理使用 Lombok:减少 getter/setter 冗余。
- 按需生成:只生成需要的模块(如不生成 Controller)。
- 缓存模板解析结果:Freemarker 本身支持模板缓存,无需手动干预。
七、高级用法(可选)
7.1 自定义模板引擎
可实现 TemplateEngine
接口,支持 Thymeleaf、Handlebars 等。
7.2 动态模板选择
根据表名前缀选择不同模板:
.templateConfig(builder -> {
if (tableName.startsWith("t_log_")) {
builder.entity("/templates/log-entity.java.ftl");
} else {
builder.entity("/templates/default-entity.java.ftl");
}
})
7.3 生成 XML 文件(已过时,推荐注解)
.builder.mapperBuilder()
.enableMapperAnnotation() // 使用 @Select 等注解,避免 XML
八、总结
通过 MyBatis-Plus 自定义模板配置,你可以:
- ✅ 完全控制生成代码的结构与风格
- ✅ 统一团队开发规范
- ✅ 提升开发效率,减少重复劳动
- ✅ 适配企业级架构(如多数据源、分布式事务)
🔧 推荐流程:
- 创建
resources/templates/
- 编写
.ftl
模板文件 - 在
FastAutoGenerator
中配置.templateConfig()
- 运行生成器,验证输出
- 纳入团队规范,持续优化