Skip to content

MyBatis Generator 指南 ​

本指南介绍两种通过读取数据库表结构自动产出模板文件的工具:MyBatis 官方的 mybatis-generator-maven-plugin(MBG)与 MyBatis-Plus 的 mybatis-plus-generator。 适用于 mybatis-generator-maven-plugin 1.4.2 / mybatis-plus-generator 3.5.17 / MyBatis-Plus 3.5.17 / Java 17+。 假设你已了解 MyBatis 的 Mapper 接口与 XML 映射基础,可参考 MyBatis 指南;MyBatis-Plus 的日常用法见 MyBatis-Plus 指南。


目录 ​

  1. 前言
  2. mybatis-generator-maven-plugin
  3. mybatis-plus-generator

1. 前言 ​

写 MyBatis 时,需要写实体类、Mapper、XML 等文件,可使用插件或依赖通过读取 SQL 表,直接生成对应的模板文件。

核心原则是:凡是标准的、单表的 CRUD(增删改查)操作,交给 MBG 自动生成;凡是涉及多表关联、复杂业务逻辑(复杂的统计与分组查询),必须手工编写。

下面两套工具对应两种取舍:MBG 生成"实体 + Example + 接口 + XML"的经典风格,可控性强;mybatis-plus-generator 直接产出 MyBatis-Plus 风格的整套代码,配置更少。


2. mybatis-generator-maven-plugin ​

2.1 pom.xml 引入 ​

在 pom.xml 的 <build><plugins> 中加入插件:

xml
<plugin>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-maven-plugin</artifactId>
    <version>1.4.2</version>
    <configuration>
        <!-- generatorConfig.xml 的位置(相对项目根目录);不写则用默认值
             src/main/resources/generatorConfig.xml -->
        <configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
        <!-- 已存在的同名生成文件是否覆盖;默认 false(只跳过,不报错) -->
        <overwrite>true</overwrite>
        <!-- 打印更详细的生成日志 -->
        <verbose>true</verbose>
    </configuration>
    <dependencies>
        <!-- 关键:JDBC 驱动必须作为插件依赖,否则报 Cannot load driver class -->
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <version>8.4.0</version>
        </dependency>
    </dependencies>
</plugin>

两处容易出问题的配置:

  1. 驱动加在插件的 <dependencies> 里。MBG 本身不带任何数据库驱动;把 mysql-connector-j 加在插件依赖里,是保证生成时能加载到驱动的可靠方式。
  2. overwrite 默认是 false:同名文件已存在时直接跳过(生成器不覆盖、不报错)。开发期反复生成建议设成 true,或者每次生成前删掉旧文件。

2.2 编写 generatorConfig.xml ​

新建 src/main/resources/generatorConfig.xml。

这是生成器的"剧本":告诉它连哪个库、生成到哪个包、按什么风格生成。先看一个最小完整配置:

xml
<?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>

    <!-- context:一次生成任务。id 任意;targetRuntime 决定生成风格(见下文,务必留意) -->
    <context id="mysqlTables" targetRuntime="MyBatis3" defaultModelType="conditional">

        <!-- 数据库连接 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/mydb?useSSL=false&amp;serverTimezone=Asia/Shanghai"
                        userId="root"
                        password="your_password"/>

        <!-- 类型解析:数据库类型 → Java 类型。forceBigDecimals 控制 DECIMAL 是否一律映射为 BigDecimal -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>

        <!-- 实体类输出:包名 + 目录 -->
        <javaModelGenerator targetPackage="com.example.demo.entity"
                            targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>

        <!-- XML 映射文件输出:targetProject 通常是 src/main/resources -->
        <sqlMapGenerator targetPackage="mapper"
                         targetProject="src/main/resources">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>

        <!-- Mapper 接口输出;type="XMLMAPPER" 表示接口 + XML 配套生成 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.example.demo.mapper"
                             targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>

        <!-- 要生成的表。domainObjectName 自定义实体名(不写则表名转驼峰) -->
        <table tableName="user" domainObjectName="User">
            <!-- 自增主键:插入后把生成的主键回填到实体的 id 属性 -->
            <generatedKey column="id" sqlStatement="MySql" identity="true"/>
        </table>

    </context>

</generatorConfiguration>

targetRuntime 是 context 上最重要的决策,它决定生成哪套 API。三个选项:

targetRuntime生成内容有无 Example 类
MyBatis3完整经典风格:实体 + Example + 接口 + XML,含全部 ByExample 方法✅ 有(本指南重点)
MyBatis3Simple精简风格:只有 insert / selectByPrimaryKey / updateByPrimaryKey / deleteByPrimaryKey / selectAll❌ 无
MyBatis3DynamicSql1.4.0 起默认。基于 MyBatis Dynamic SQL,方法参数用 SelectStatementProvider 等❌ 无

defaultModelType(conditional 为默认)控制实体类的组织方式:

  • conditional(默认):单主键表生成扁平实体(一个类);复合主键 / 含 BLOB 列时才拆分。
  • flat:一律扁平,一个表只生成一个实体类。
  • hierarchical:按主键、BLOB、普通字段拆成多个类,日常基本用不到。

2.3 生成 ​

配置就绪后,在项目根目录执行:

bash
./mvnw mybatis-generator:generate

3. mybatis-plus-generator ​

3.1 pom.xml 引入 ​

先将原先的 mybatis-spring-boot-starter 替换为 mybatis-plus-spring-boot4-starter:

xml
<!-- 原先 -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>4.0.1</version>
</dependency>

<!-- 现在 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-spring-boot4-starter</artifactId>
    <version>3.5.17</version>
</dependency>

新增代码生成器与模板引擎依赖(放在 test 作用域):

xml
<!-- MyBatis-Plus 代码生成器(仅生成时使用,放在 test 作用域) -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.5.17</version>
    <scope>test</scope>
</dependency>

<!-- 生成器模板引擎 FreeMarker -->
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.34</version>
    <scope>test</scope>
</dependency>

3.2 编写 CodeGenerator ​

新建 src/test/java/com/example/mybatis/CodeGenerator.java。

因为生成器依赖的 scope 是 test,所以代码生成器的类也放在 test 目录:好处是相关代码不会被打进最终产物,工程更干净。

java
package com.example.mybatis;

import java.util.Collections;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

/**
 * MyBatis-Plus 代码生成器入口类。
 * 直接运行 main 方法即可生成实体类、Mapper 接口和 Mapper XML。
 */
public class CodeGenerator {

    public static void main(String[] args) {
        String projectPath = System.getProperty("user.dir");

        FastAutoGenerator.create(
                        "jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai",
                        "root",
                        "123456")
                // 全局配置
                .globalConfig(builder -> builder
                        .author("example")
                        .outputDir(projectPath + "/src/main/java")
                        // 生成后不自动打开输出目录窗口
                        .disableOpenDir())
                // 包配置
                .packageConfig(builder -> builder
                        .parent("com.example")
                        .moduleName("mybatis")
                        .entity("entity")
                        .mapper("mapper")
                        // Mapper XML 输出位置
                        .pathInfo(Collections.singletonMap(OutputFile.xml,
                                projectPath + "/src/main/resources/mapper")))
                // 策略配置
                .strategyConfig(builder -> builder
                        // 需要生成的表
                        .addInclude("user", "role", "user_role")
                        .entityBuilder()
                        .enableLombok()
                        .enableTableFieldAnnotation()
                        .idType(IdType.AUTO)
                        .mapperBuilder()
                        .enableBaseResultMap()
                        .enableBaseColumnList())
                // 模板引擎
                .templateEngine(new FreemarkerTemplateEngine())
                .execute();
    }

}

3.3 生成 ​

提示:运行的指令和项目名称有关,在项目根目录执行:

bash
./mvnw.cmd test-compile exec:java "-Dexec.mainClass=com.example.mybatis.CodeGenerator" "-Dexec.classpathScope=test"