MyBatis-Plus 提供了强大的代码生成器(AutoGenerator),支持高度可定制的模板引擎(如 Freemarker、Velocity)。通过自定义模板配置,开发者可以完全控制生成的 Entity、Mapper、Service、Controller 等代码的结构、命名、注释、注解、格式等,满足企业级开发规范和个性化需求。


一、核心概念

1.1 模板引擎(Template Engine)

  • MyBatis-Plus 支持 FreemarkerVelocity 两种模板引擎。
  • 模板文件是 .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 缺少依赖 添加 freemarkervelocity 依赖

四、注意事项

  1. 模板路径必须正确

    • 推荐使用 resources/templates/ 目录。
    • 路径前加 / 表示类路径根目录。
  2. 避免覆盖重要文件

    • 生产环境慎用 enableFileOverride()
    • 建议首次生成后关闭覆盖。
  3. 模板编码统一为 UTF-8

    • 防止中文注释乱码。
  4. 变量命名规范

    • 使用 table.entityNamefield.propertyName 等标准变量。
  5. 逻辑删除与自动填充

    • 若启用,需在模板中处理对应字段。

五、使用技巧

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 自定义模板配置,你可以:

  • ✅ 完全控制生成代码的结构与风格
  • ✅ 统一团队开发规范
  • ✅ 提升开发效率,减少重复劳动
  • ✅ 适配企业级架构(如多数据源、分布式事务)

🔧 推荐流程

  1. 创建 resources/templates/
  2. 编写 .ftl 模板文件
  3. FastAutoGenerator 中配置 .templateConfig()
  4. 运行生成器,验证输出
  5. 纳入团队规范,持续优化