第一次接触 MyBatis 逆向工程,向工是向工因为接手了一个老项目——数据库里 60 多张表,实体类、向工Mapper 接口、向工XML 映射文件一个都没有。向工手动写?向工光字段名就能把我逼疯。后来同事扔给我一个 generatorConfig.xml,向工说“跑一下,向工省你三天”。向工结果十分钟后,向工所有 Java 文件整整齐齐躺在目录里。向工那一刻我就知道,向工这玩意儿必须掌握。向工
MyBatis 逆向工程的向工核心,就是向工一个叫 mybatis-generator-core 的 jar 包。它读数据库的元数据——表结构、字段类型、主键、外键——然后按模板生成三样东西:和表对应的实体类(POJO)、操作单表的 Mapper 接口、以及对应的 XML 映射文件。注意,它只生成单表 CRUD,不碰多表关联,也不管你业务逻辑。这是它的边界,也是它快的原因。
配置方式有两种:XML 和 Java 代码。实际项目里 99% 用 XML,因为改起来方便。一个最简的 generatorConfig.xml 长这样:
<generatorConfiguration> <context id="mysql" targetRuntime="MyBatis3"> <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/test" userId="root" password="123456"/> <javaModelGenerator targetPackage="com.example.entity" targetProject="src/main/java"/> <sqlMapGenerator targetPackage="com.example.mapper" targetProject="src/main/resources"/> <javaClientGenerator type="XMLMAPPER" targetPackage="com.example.mapper" targetProject="src/main/java"/> <table tableName="user" domainObjectName="User"/> </context> </generatorConfiguration> 几个关键点。第一,targetRuntime 选 MyBatis3 还是 MyBatis3Simple?前者会生成 selectByExample、updateByExample 这类带条件构造的方法,代码多但灵活;后者只生成最基本的 selectByPrimaryKey、insert、updateByPrimaryKey,干净但不够用。我一般选 MyBatis3,因为 Example 模式虽然被一些人吐槽“太重”,但在后台管理系统里写动态查询确实省事。
第二,表名和字段名映射。MySQL 里习惯用下划线,Java 里用驼峰。默认情况下 generator 不会自动转——user_name 生成出来就是 userName 吗?不一定。你需要在 table 标签里加 <property name="useActualColumnNames" value="false"/>,或者直接配 <columnOverride column="user_name" property="userName"/>。我踩过这个坑,生成完发现字段全叫 user_name,编译都过不了。
第三,重复生成的问题。每次跑 generator,它会直接覆盖已有文件。如果你在实体类里加过自定义方法,或者改过注释,全没了。解决办法是用 <plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin"/> 或者手动把生成目录设成临时目录,再拷贝需要的文件。我现在的习惯是:生成到 target/generated-sources,然后只把新增的表对应的文件复制到 src 里。老表不动。
还有个细节:主键策略。MySQL 自增主键,generator 会默认生成 useGeneratedKeys="true" keyProperty="id",这没问题。但如果是 UUID 或者雪花算法,你得手动改 XML——generator 不认识这些。另外,Example 类里的 Criteria 会生成一堆 andXxxEqualTo、andXxxLike,代码量巨大。有人嫌乱,用 MyBatis3Simple 然后自己写 SQL。没有对错,看团队习惯。
实际用下来,逆向工程最适合的场景是:新项目搭架子、老项目补单表操作、数据库表频繁变动时快速同步。但它不适合复杂查询——多表 join、子查询、存储过程,这些还是手写 XML 更靠谱。我见过有人试图用 generator 生成所有 SQL,结果 XML 里全是 Example 嵌套,改一个条件要翻三屏,维护成本反而更高。
最后说一个容易忽略的点:生成后的代码要 review。generator 不认识你的业务语义——它会把 status 字段生成成 Integer,但你的枚举可能更合适;它会把 decimal 生成成 BigDecimal,这没错,但精度和 scale 未必符合预期。花十分钟检查一遍,比事后改一百个文件划算。