主题
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. 前言
写 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>两处容易出问题的配置:
- 驱动加在插件的
<dependencies>里。MBG 本身不带任何数据库驱动;把mysql-connector-j加在插件依赖里,是保证生成时能加载到驱动的可靠方式。 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&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 | ❌ 无 |
MyBatis3DynamicSql | 1.4.0 起默认。基于 MyBatis Dynamic SQL,方法参数用 SelectStatementProvider 等 | ❌ 无 |
defaultModelType(conditional 为默认)控制实体类的组织方式:
conditional(默认):单主键表生成扁平实体(一个类);复合主键 / 含 BLOB 列时才拆分。flat:一律扁平,一个表只生成一个实体类。hierarchical:按主键、BLOB、普通字段拆成多个类,日常基本用不到。
2.3 生成
配置就绪后,在项目根目录执行:
bash
./mvnw mybatis-generator:generate3. 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"