从 MyBatis Generator 的 XML 配置看起,很多人第一次用这个工具时对着配置模板一头雾水:classPathEntry是什么意思?table里的domainObjectName到底要不要写全限定名?targetProject该填什么路径?我又不希望生成Example类,该删哪里?
这篇就以我实际项目中反复打磨过的一套配置模板为主线,把每个节点的含义、每个属性的效果、以及运行命令的细节全部盘一遍。无论你是第一次接触 MBG 的初学者,还是被配置文件里的exception报错折磨过的使用者,这篇都值得存下来对照操作。
1. 配置模板的整体设计思路
1.1 为什么需要一份清晰的配置模板
MyBatis Generator(下文简称 MBG)本质是一个代码生成器,它根据数据库表结构生成四类产物:实体类(Model)、Mapper 接口(Dao)、XML 映射文件(Mapper XML)以及可选的 Example 查询条件类。它解决的核心痛点是:CRUD 基础代码反复手写、容易出错、命名不统一。
但 MBG 不是开箱即用的“傻瓜工具”,它的行为完全由一份 XML 配置驱动。同一个数据库表,配置不同,生成出来的代码风格完全不同。我把配置模板的重要性看得和代码本身一样高——它是整个生成过程的地基。配置写得乱,后期生成的代码就乱;配置写得好,团队里任何人拉下来都能在一个命令之内得到风格一致的代码。
很多团队用 MBG 的方式是找一个网上现成的配置文件,改一下连接串和表名就开跑,当时可能感觉“跑通了”。但这些模板往往内容冗余:可能残留了旧版本的 DTD 引用、多余的分页插件配置、或者用了已经不推荐使用的属性。真遇到问题定位起来很困难。所以我对配置模板的要求是:每个节点都清楚它存在的意义,不需要的节点一律不出现。
1.2 配置文件的核心作用域
一套完整的 MBG 配置分为两大作用域:全局配置和表级配置。全局配置控制生成代码的“气质”:编码格式、目标工程目录、生成的注释风格、是否生成 Example;表级配置则决定每一张表具体怎么映射:主键生成策略、字段类型转换、表名与类名的对应关系。
理解这个分层关系之后,调试配置就会有个清晰的思路:如果所有表的生成行为都不符合预期,问题大概率在全局配置;如果只有某一张表设置不了主键或者字段映射错误,问题大概率在表级配置。这个诊断思路帮我省下过大量排查时间。
2. 全局配置:根节点与 context 的深度解读
2.1 DTD 声明与根节点
任何一份 MBG 配置文件的第一行必然是 XML 声明和 DTD 声明。DTD 引用我从引入http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd,这是 MBG 官方定义配置语法格式的文档类型描述。使用新版 MBG 时同样可以沿用这个 1.0 的 DTD,因为配置元素的整体语法结构始终保持了向后兼容。要注意的是,很多教程里的 DTD 地址是http://mybatis.org/dtd/...,不带www,这个地址在国内网络环境下偶尔访问超时——但不影响 MBG 生成代码,因为解析器会优先读取本地内置的 DTD 定义,网络请求失败时不会中断生成过程。
根节点<generatorConfiguration>下面通常直接挂<context>。我在网上下载过的一些模板还会保留<properties>节点,用于读取外部 properties 文件。这个节点在小项目里用处不大,但它能让数据库连接信息与生成规则分离。我推荐的做法是:将数据库连接地址、用户名、密码写入一个独立的generator.properties文件,然后在根节点用<properties resource="generator.properties"/>引入。这样在多人协作时,每个人可以保留自己的数据库配置而不必改动公共的 XML 模板。这算是我多年使用下来体验最舒适的组织方式。
2.2 context 节点的关键属性
<context>节点是整个配置文件的“发动机”,它的核心属性包括:
id:任意字符串,只用于标识不同 context,生成后的内容不会直接使用这个 id,但不同 context 之间必须唯一。targetRuntime:指定生成代码所基于的运行时框架。最常用的是MyBatis3,生成的是标准 MyBatis 风格的 Mapper 与 XML;如果项目使用了 MyBatis 的分页插件PageHelper,MBG 会自动带上分页所需的方法签名(实际上 PageHelper 有自己的拦截器,MBG 只是生成兼容的方法)。若选择MyBatis3Simple,则生成精简的 Mapper 接口和 XML,少了 Example 相关的复杂方法,代码量大幅减少,是我个人偏爱的配置。defaultModelType:控制实体类的生成方式。我对这个属性踩过坑:默认值为conditional,意思是如果一个表有联合主键,可能把主键字段独立到一个类里;而flat则把表的所有字段放在唯一一个实体类中。如果不希望生成“主键类+字段类+BLOB类”这种碎片化的实体结构,推荐显式设置为flat。我见过不少项目使用默认值后,实体类里莫名多了一个“Key”类,排查了半天才发现是这个属性在起作用。
2.3 注释配置与插件注册
<commentGenerator>节点控制生成代码中的注释内容。默认情况下,MBG 会在每个类、每个字段前生成一段冗长的注释,其中包含“This class was generated by MyBatis Generator”等提示文本。如果生成的代码需要交给团队维护,我通常的做法是自定义一个注释生成器,或者直接配置如下:
<commentGenerator> <property name="suppressAllComments" value="true"/> </commentGenerator>suppressAllComments设为true后,所有自动生成的注释都会被抑制。需要注意,这个属性还会影响 Example 类里的criteria注释,但不会影响 XML 映射文件中的必要 SQL 语句。如果你既不希望代码里出现英文注释,又希望保留一点可读性,可以在使用自定义 Java 类的方式生成中文注释,这个在后面的高级配置里我会展开讲。
插件节点<plugin>的使用场景通常包括:MyBatis 分页插件生成器插件、序列化插件、ToString 插件、Equals/HashCode 插件。配置插件时列表顺序有一定讲究,部分插件(比如覆盖主键方法的插件)对生成顺序有依赖。对于入门阶段的项目,保留<plugin type="org.mybatis.generator.plugins.RowBoundsPlugin"/>即可支持分页查询;其余插件按需添加,不要为了齐全而全上——插件越多,生成的代码变化越大,排查问题越困难。
3. 三个生成器:模型、映射文件、客户端接口
这一节是配置模板中最长的部分,也是最容易出问题的地方。MBG 要求<context>内部必须依次声明连接工厂、模型生成器、映射 XML 生成器和客户端(Mapper/Dao)生成器。顺序不能随意颠倒,否则运行时会直接报 XML 配置错误。
3.1 jdbcConnection:连接数据库的“入口”
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver" connectionURL="${jdbc.url}" userId="${jdbc.username}" password="${jdbc.password}"/>使用 MySQL 8.x 及以上版本时,驱动类名必须写com.mysql.cj.jdbc.Driver,如果继续沿用旧的com.mysql.jdbc.Driver会直接连接失败。连接串中要显式声明 UTF-8 编码和服务器时区,比如:
jdbc:mysql://localhost:3306/yourdb?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai这里有一个容易忽略的关键点:MBG 执行的数据库连接过程中,会读取数据库的元数据(表结构、主键、字段注释)。如果数据库账号权限不足,比如没有SELECT权限或者没有SHOW相关权限,生成过程会报“Could not get table info”之类的错。我经历过的某次项目中,DBA 给了应用账号读写权限但没有元数据查询权限,MBG 始终报错,换成具有相应权限的账号后立刻成功。
3.2 javaModelGenerator:实体类生成规格
<javaModelGenerator targetPackage="com.example.model" targetProject="src/main/java"> <property name="enableSubPackages" value="true"/> <property name="trimStrings" value="true"/> <property name="immutable" value="false"/> </javaModelGenerator>targetPackage指定包名,targetProject指定源码根目录。我见过很多初学者的疑问:“为什么生成到别的目录了?”——那是因为targetProject填的是相对路径,而 MBG 在命令行运行时的工作目录决定了相对路径的基准。建议总是填写绝对路径,或者通过命令行参数-DtargetProject=...覆盖,避免“放在哪”的困惑。
enableSubPackages设为true时,会根据数据库的 schema/catalog 再拼接一层包名,多 schema 的库建议打开;普通单库项目保持false更容易控制结构。trimStrings是数据库字段为char类型时,是否对传入的字符串自动trim()。业务上对字符串首尾空格敏感的项目,这个属性必须打开。
值得注意的是immutable属性。默认false,生成带 setter 的普通 POJO;如果设为true,则生成只有构造函数没有 setter 的不可变对象。表面上看起来“代码更安全”,但 MyBatis 反射填值对无 setter 对象的支持依赖构造器参数名,映射配置复杂时会踩坑,所以绝大多数项目我建议保留默认值。
3.3 sqlMapGenerator:XML 映射文件生成规格
<sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"> <property name="enableSubPackages" value="false"/> </sqlMapGenerator>这里我最想强调一个常见认知错误:targetPackage填的是“包路径风格”的目录结构,比如com.example.mapper,MBG 会生成src/main/resources/com/example/mapper这样的目录。如果将它填成mapper,则生成的 XML 直接放在resources/mapper下,通常来说更简洁。targetProject如果是 Maven 项目,记得指向src/main/resources,而不是src/main/java。XML 文件放在 java 源码目录在大多数构建环境并不会报错,但会让项目结构混乱,也违反团队约定。
3.4 javaClientGenerator:Mapper 接口生成规格
<javaClientGenerator type="XMLMAPPER" targetPackage="com.example.dao" targetProject="src/main/java"> <property name="enableSubPackages" value="false"/> </javaClientGenerator>type可选XMLMAPPER(生成独立 XML+接口)、ANNOTATEDMAPPER(接口中直接写注解 SQL)和MIXEDMAPPER(简单 SQL 注解 + 复杂 SQL XML)。最常用也是我推荐的是XMLMAPPER,团队审查 SQL 比较方便,SQL 调整也无需重新编译 Java 代码。
targetPackage的命名通常会根据项目分层习惯设置。我见过一些项目直接把 mapper 接口和实体类放在同一个包下,几百个文件堆积在同一个目录,维护体验非常差。即便 MBG 能生成,规范仍是开发者的责任。
3.5 table 节点的精细配置
<table>节点是配置中使用频率最高的子节点,每一张需要生成的表都要声明一次。核心属性如下:
<table tableName="user" domainObjectName="UserInfo" enableInsert="true" enableUpdateByPrimaryKey="true" enableDeleteByPrimaryKey="true" enableSelectByPrimaryKey="true" enableSelectByExample="true" enableCountByExample="true" enableUpdateByExample="true" enableDeleteByExample="true" selectByExampleQueryId="true">tableName:数据库表名,必填。domainObjectName:实体类名。强烈建议显式声明,而不是靠 MBG 自动推算。自动推算的结果在表名有下划线时往往不符合团队命名规范。enableXxx系列:控制生成哪些方法。如果项目不需要 Example 查询,将enableSelectByExample等属性设为false,再配合targetRuntime="MyBatis3Simple",生成的代码量会大幅减少。<generatedKey>:如果表的主键是自增的,需要在这里配置 JDBC 获取自增主键的方法:
<generatedKey column="id" sqlStatement="MySql" identity="true"/>sqlStatement根据数据库类型填写,MySQL 写MySql,PostgreSQL 写PostgreSQL。配置后 MBG 生成的insert语句会自动包含useGeneratedKeys="true"和keyProperty="id",彻底解决自增主键回填问题。
3.6 字段映射与类型转换
当数据库字段类型与 Java 类型不能自动映射时,通过<columnOverride>手动修正:
<columnOverride column="remark" javaType="java.lang.String" jdbcType="VARCHAR"/>需要处理数字精度问题的场景也很常见,比如数据库decimal(10,4)自动映射为BigDecimal,业务上希望使用Double,可用javaType="java.lang.Double"覆盖。修改基础类型映射会直接影响所有生成代码的 SQL 参数类型,务必要测试后再提交。
此外还有两个常用属性:ignoreColumn用于排除某列不生成;tableName支持 SQL 通配符,比如tableName="%"生成所有表,但在实际项目中我基本不用通配符,宁可显式列出每张表,宁可长一点,也不愿意误生成历史遗留表。
4. 一套可直接复用的完整配置文件
下面给出一个贴近实战的完整配置。这是一份我在某中型项目中使用过的模板,按需删减后用于快速交付。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <properties resource="generator.properties"/> <context id="mysqlContext" targetRuntime="MyBatis3Simple" defaultModelType="flat"> <!-- 关闭自动生成的注释 --> <commentGenerator> <property name="suppressAllComments" value="true"/> </commentGenerator> <!-- 数据库连接 --> <jdbcConnection driverClass="${driverClass}" connectionURL="${connectionURL}" userId="${userId}" password="${password}"/> <!-- 实体类 --> <javaModelGenerator targetPackage="${model.package}" targetProject="${model.project}"> <property name="enableSubPackages" value="false"/> <property name="trimStrings" value="true"/> </javaModelGenerator> <!-- XML映射文件 --> <sqlMapGenerator targetPackage="${xml.package}" targetProject="${xml.project}"> <property name="enableSubPackages" value="false"/> </sqlMapGenerator> <!-- Mapper接口 --> <javaClientGenerator type="XMLMAPPER" targetPackage="${dao.package}" targetProject="${dao.project}"> <property name="enableSubPackages" value="false"/> </javaClientGenerator> <!-- 表配置:显式列出,不开 Example --> <table tableName="sys_user" domainObjectName="SysUser"> <generatedKey column="id" sqlStatement="MySql" identity="true"/> </table> <table tableName="sys_role" domainObjectName="SysRole"> <generatedKey column="id" sqlStatement="MySql" identity="true"/> </table> </context> </generatorConfiguration>配套的generator.properties文件内容如下:
driverClass=com.mysql.cj.jdbc.Driver connectionURL=jdbc:mysql://localhost:3306/yourdb?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai userId=root password=123456 model.package=com.example.model model.project=src/main/java xml.package=mapper xml.project=src/main/resources dao.package=com.example.dao dao.project=src/main/java我在实际项目中常把xml.package直接设为mapper而不是完整的包路径。配置越短后面维护越轻松。如果你使用 Maven,直接在pom.xml中挂载mybatis-generator-maven-plugin,运行时执行mvn mybatis-generator:generate即可。这个插件会把配置文件的相对路径基准自动定为 Maven 项目根目录,所以targetProject一般写src/main/java这种相对路径即可。
5. 常见问题与排查技巧实录
5.1 连接数据库失败,错误信息是中文乱码
经常有人生成时控制台打印的中文乱码,不是代码生成的问题,而是 Maven 运行时默认编码不对。在pom.xml里给插件增加<encoding>配置:
<configuration> <configurationFile>src/main/resources/generatorConfig.xml</configurationFile> <overwrite>true</overwrite> <verbose>true</verbose> </configuration>编码问题建议在 JVM 层面解决:设置MAVEN_OPTS=-Dfile.encoding=UTF-8。如果仍不奏效,在配置文件顶部加上<property name="javaEncoding" value="UTF-8"/>放在<generatorConfiguration>的<properties>之后。
5.2 生成的实体类没有注释,同事抱怨
默认关闭注释,团队协作时对代码可读性要求高的话,可以通过自定义注释生成器来加上中文注释。做法是实现org.mybatis.generator.api.CommentGenerator接口,重写addModelClassComment、addFieldComment等方法,再从数据库的Remark元数据中读取字段注释注入到生成代码里。实现完成后在<commentGenerator type="com.example.CommentGenerator"/>中指定。要注意的是,自定义类必须在 MBG 运行的 classpath 中——Maven 插件方式下,直接将类放在项目源码中即可被加载,命令行方式时需要把编译后的 class 路径加入--classpath参数。
5.3 重复生成文件,手工修改被覆盖
MBG 默认对已存在文件有保留策略:执行生成时,如果某个文件已存在且内容与将要生成的内容一致,或 MBG 检测到文件不是自己生成的,会选择不覆盖。但插件配置里如果显式设置<overwrite>true</overwrite>,则所有被生成的文件都会无条件覆盖。我强调一个团队纪律:MBG 生成的文件不要手工修改,需要调整的地方要么改表结构,要么改配置,要么在生成后用脚本统一替换。一旦手工改了,下次生成就会丢改动的逻辑,而且这种丢失很难通过 Git 记录察觉。
5.4 只生成了一部分表,日志里没有错误
这种情况多半是tableName的匹配问题:MySQL 表名大小写在 Linux 下敏感,而 Windows 下不敏感。如果你的库表名是Sys_User,配置里写sys_user,在 Linux 上跑 Maven 插件就可能匹配不到表,但又不报错。解决方案是严格照搬数据库里的实际表名;如果库表命名比较规范,可以使用%匹配做快速生成,但生成前必须自己过滤掉不需要的表。
5.5 targetRuntime 选错导致生成代码风格诡异
选MyBatis3DynamicSql或更早版本遗留的其他运行时,可能生成大量@Generated等注解和构造器风格的类。团队项目中对生成代码风格有要求时,最好锁定MyBatis3Simple或MyBatis3这两个选项,并在项目 README 中注明原因。换运行时后一定要删掉旧生成的文件再重新生成,因为 MBG 对既有文件的保留策略可能让新旧代码混在一起。
6. 进阶:结合 Lombok、自定义模板与多环境配置
6.1 去掉 Setter/Getter,生成 Lombok 风格的实体
实体类字段多时,产出的上千行 getter/setter 非常占篇幅,而且每次表结构变更重新生成代码,代码 diff 会特别大。我实际项目中的做法是:通过自定义插件在生成实体类时自动添加@Data注解,并抑制所有 getter/setter 的生成。核心思路是继承PluginAdapter,在modelBaseRecordClassGenerated方法中向生成的类添加注解,再重写modelSetterMethodGenerated和modelGetterMethodGenerated返回false。
public class LombokPlugin extends PluginAdapter { @Override public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { topLevelClass.addImportedType("lombok.Data"); topLevelClass.addAnnotation("@Data"); return true; } @Override public boolean modelSetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) { return false; } // getter 同理返回 false }配置中注册插件:
<plugin type="com.example.LombokPlugin"/>这里提醒一点:如果项目原先已经生成了大量带 getter/setter 的旧实体类,启用 Lombok 插件后必须全量重新生成,并检查编译是否引用了那些“被删掉”的方法——虽然 Lombok 编译后会补全,但 IDE 的即时编译在某些环境下会缓存旧结构,建议 clean 后再编译。
6.2 多环境配置:开发、测试、生产用同一套模板
数据库在不同环境下的地址、用户名不同,我们的配置模板通过generator.properties隔离了这些差异。推荐的做法是维护三份 properties 文件:generator-dev.properties、generator-test.properties、generator-prod.properties。在 Maven 插件配置里通过<properties>指定当前激活的环境参数,或者在命令行执行:
mvn mybatis-generator:generate -Dmybatis.generator.properties.file=src/main/resources/generator-dev.properties这种方式最能避免无意中在生成代码时连上生产库。我亲眼见过生产事故(模拟项目)正是因为开发机的配置文件里写了生产库连接地址,凌晨跑定时任务时把生产表结构读了一遍,导致部分运行时元数据被缓存——虽然没改数据,但足够让人后怕。配置文件绑定环境后,这种行为能被有效阻断。
6.3 生成代码的分层依赖
MBG 生成的三类文件之间天然存在依赖关系:实体类不依赖其他生成文件,Mapper 接口依赖实体类,XML 映射文件中的resultMap与parameterType都依赖实体类全限定名。如果调整了targetPackage,务必保持三者之间的包路径彼此协调。举例来说,com.example.model里的实体类如果改到com.example.pojo,那么 XML 文件中的parameterType="com.example.model.SysUser"也得全部替换。有的团队干脆在生成后执行一段全局文本替换脚本,将旧包名批量替换成新包名,这种方法可行,但维护成本更高,我更推荐一步到位直接更新生成配置和模板源,从源头保证一致性。
7. 命令行运行与常见参数说明
除了 Maven 插件外,MBG 也支持命令行运行。命令行方式适合在没有完整 Maven 环境的机器上使用,比如一些内网部署机。运行命令如下:
java -jar mybatis-generator-core-1.4.2.jar \ -configfile generatorConfig.xml \ -overwrite-configfile指定 XML 配置文件路径,-overwrite表示覆盖已存在的同名文件。还有一个-verbose参数,打印生成过程的详细日志,排查问题时建议加上。如果配置文件中引用了外部 properties 文件,而 MBG 无法在当前目录找到它,就会报Cannot load resource ...错误。命令行启动时的工作目录就是当前目录,所以建议把 properties 文件与 XML 放在同一目录,或者使用绝对路径。
依赖 JDBC 驱动时,命令行需要把驱动 jar 和自定义插件 jar 都通过-classpath参数显式指定,例如:
java -cp mybatis-generator-core-1.4.2.jar:mysql-connector-java-8.0.33.jar \ org.mybatis.generator.api.ShellRunner \ -configfile generatorConfig.xml -overwrite -verboseWindows 环境下路径分隔符用分号而非冒号,这一点常有人踩坑。我建议团队统一使用 Maven 插件方式,因为依赖管理、编码、classpath 都更好控制;命令行方式定位为“应急手段”。
8. 配置模板维护的团队协作建议
8.1 版本控制与评审
配置文件需要纳入版本控制,而且应当指定专人维护。它不像普通代码那样频繁变更,但每次变更影响面都很大——一次修改会导致全项目范围内的生成代码全部变化。我经手的项目里,配置文件改动必须经过至少一位熟悉生成机制的同事评审后才允许合并。评审重点不是格式,而是:是否修改了目标包路径?是否更改了运行时?是否关闭了某些表?这些都属于“牵一发动全身”的变更。
8.2 生成代码的提交策略
很多团队把 MBG 生成的代码直接提交到 Git 仓库。我认可这种做法,因为它能保证其他成员克隆后无需任何额外生成步骤即可编译运行。但前提是必须有“生成后 diff 审核”的习惯:执行生成命令后,git diff查看变更内容,确认与表结构变更一致后再提交。没有这个习惯,代码库里会出现大量“幽灵改动”——生成时间不同、驱动版本不同、MBG 版本不同都可能导致细微差异,最终合并的时候痛苦的是所有人。
8.3 与数据库变更的联动
MBG 只是“单向同步”:从表到代码。表结构改了,需要手动重新运行生成命令。比较理想的做法是在数据库迁移脚本(比如 Flyway)中调用生成命令,或至少把生成命令写入 CI 流水线的一个手动触发任务里。这样能强制每人在表结构变更后都看到最新代码,而不是等同事手动跑一遍再传代码。我使用过的一个项目在数据库迁移工具的 afterMigrate 钩子里自动执行 MBG 生成,也会把 Maven 插件绑定到generate-sources阶段,让它成为 Maven 编译的固定环节。这种做法极大程度减少了“代码与表结构不一致”的问题。
8.4 我的经验心得
写到这里,分享一个在实际项目中反复验证过的经验:MBG 配置文件的第一版宁可多花半小时精雕细琢,也不要图快直接复制网上模板。原因很简单,这个文件是一个高频“生产资料”,每一次生成都在消耗它。如果它一开始就是整洁、合理、有注释的,后面所有生成的代码都会在这个轨道上运行。我第一次使用 MBG 时,直接在网上下载了一份包含大量冗余节点的模板,因为对每个节点理解不深,出现问题无法定位,消耗了数倍时间排错。
另一个教训是:生成代码之前,务必确认数据库连接账号不被其他任务占用。MBG 会读取表结构的元数据,如果同时有长事务在更新表结构,可能因为锁等待问题导致生成超时。这个场景不多见,但一旦出现,排查成本极高。我通常的做法是在低峰期执行生成,或者准备一个只读账号,专门用于生成工具连接。
9. 写在最后的小建议
如果你把 MBG 当作“一次性代码生成工具”,用完就忘,那遇到问题是迟早的事;如果你把它当作一套“代码生产流水线”,认真维护配置文件,那么后续的每一次表结构变更、字段新增、索引调整,都会变得非常顺畅。我个人在实际使用中更喜欢让项目始终保持“配置驱动生成”的姿势:表结构变更的意思是先改表,再改配置,再跑命令,最后提交生成代码。这四个动作顺序基本固定,少一步都会出问题。
最后再分享一个小技巧:在tableName中不建议使用%通配符直接生成全库表,除非你确认所有表都要上线。但如果你确实需要快速生成一批表,可以在生成后运行一段简单的文件清理脚本,将不再是业务表的文件移出目录。这比在配置里反复增删table节点更省心。用好 MBG 不在于跑通一次,而在于掌握生成逻辑之后,把它融入日常开发节奏,让它持续替你节省重复劳动。