1. 为什么需要定制化生成MyBatis持久层代码
在企业级Java开发中,数据持久化是每个项目都无法绕开的核心环节。传统的MyBatis开发模式要求开发者为每张数据表手动编写Entity实体类、Mapper接口和XML映射文件,这种重复劳动不仅效率低下,而且容易因人为疏忽导致字段遗漏或类型不匹配。我曾参与过一个包含87张表的ERP系统开发,手动编写这些基础代码耗费了团队近两周时间,期间还出现了十余处字段类型定义不一致的问题。
MyBatis Generator(简称MBG)作为MyBatis官方提供的代码生成工具,能够根据数据库表结构自动生成这三层基础代码。但实际项目中我们往往需要更精细的控制:
- 只生成特定业务模块的表对应的代码(避免生成整个数据库的所有表)
- 自定义实体类的命名规则(如添加Entity后缀)
- 过滤掉某些敏感表(如操作日志表)
- 为字段添加Swagger注解等扩展功能
通过配置MBG的table元素和context元素的属性,可以实现这些定制化需求。下面这个典型的配置示例展示了如何精确控制生成范围:
xml复制<table
tableName="user_info"
domainObjectName="UserEntity"
enableCountByExample="false"
enableUpdateByExample="false"
enableDeleteByExample="false"
enableSelectByExample="false"
selectByExampleQueryId="false">
<generatedKey column="id" sqlStatement="MySQL" identity="true"/>
</table>
2. 环境准备与插件配置详解
2.1 项目依赖配置
在Maven项目中集成MyBatis Generator插件,需要在pom.xml中添加以下配置。特别注意版本兼容性:MyBatis Generator 1.4.0+需要JDK 8+,与MyBatis 3.5.0+配合最佳。
xml复制<build>
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.4.2</version>
<dependencies>
<!-- 添加MySQL驱动依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<!-- 添加自定义注释生成器 -->
<dependency>
<groupId>com.github</groupId>
<artifactId>mybatis-generator-comments</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
2.2 generatorConfig.xml核心配置
在src/main/resources目录下创建generatorConfig.xml文件,这是MBG的核心配置文件。一个完整的配置应包含以下部分:
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="mysqlTables" targetRuntime="MyBatis3">
<jdbcConnection
driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/your_db?useSSL=false"
userId="root"
password="123456">
</jdbcConnection>
<!-- Java模型生成配置 -->
<javaModelGenerator
targetPackage="com.example.entity"
targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!-- SQL映射文件生成配置 -->
<sqlMapGenerator
targetPackage="mapper"
targetProject="src/main/resources">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
<!-- DAO接口生成配置 -->
<javaClientGenerator
type="XMLMAPPER"
targetPackage="com.example.mapper"
targetProject="src/main/java"/>
<!-- 指定要生成的表 -->
<table tableName="user" domainObjectName="User"/>
<table tableName="order" domainObjectName="Order"/>
</context>
</generatorConfiguration>
关键提示:connectionURL中的useSSL=false在MySQL 8.0+连接时经常被忽略,但这是导致"Public Key Retrieval is not allowed"错误的常见原因。生产环境应配置为useSSL=true并配合正确的证书。
3. 高级定制化生成策略
3.1 字段级自定义控制
MBG允许对每个字段进行精细控制,这在处理数据库设计不规范的情况时特别有用。例如:
xml复制<table tableName="product">
<columnOverride column="price"
javaType="java.math.BigDecimal"
jdbcType="DECIMAL"
typeHandler="org.apache.ibatis.type.BigDecimalTypeHandler"/>
<ignoreColumn column="internal_code"/>
<columnOverride column="create_time"
property="createTime"
javaType="java.time.LocalDateTime"/>
</table>
这样配置可以实现:
- 将price字段明确映射为BigDecimal类型(避免默认的Double可能丢失精度)
- 忽略不需要生成的internal_code字段
- 将数据库的datetime类型映射为Java 8的LocalDateTime
3.2 自定义注释生成
通过实现CommentGenerator接口,可以定制生成的代码注释。以下是添加Swagger注解的示例:
java复制public class CustomCommentGenerator extends DefaultCommentGenerator {
@Override
public void addFieldComment(Field field,
IntrospectedTable table,
IntrospectedColumn column) {
field.addJavaDocLine("@ApiModelProperty(value = \""
+ column.getRemarks() + "\")");
if (column.isIdentity()) {
field.addJavaDocLine("@TableId(value = \""
+ column.getActualColumnName()
+ "\", type = IdType.AUTO)");
}
}
}
在配置文件中引用自定义注释生成器:
xml复制<commentGenerator type="com.example.CustomCommentGenerator">
<property name="suppressAllComments" value="false"/>
<property name="suppressDate" value="true"/>
</commentGenerator>
3.3 生成DAO接口的多种风格
MBG支持生成不同风格的DAO接口,通过javaClientGenerator的type属性配置:
- XMLMAPPER:生成接口与XML映射文件(最常用)
- ANNOTATEDMAPPER:生成基于注解的接口(无XML文件)
- MIXEDMAPPER:混合模式(部分注解部分XML)
xml复制<javaClientGenerator
type="XMLMAPPER"
targetPackage="com.example.mapper"
targetProject="src/main/java"
implementationPackage="com.example.mapper.impl">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
4. 执行生成与常见问题排查
4.1 执行生成的三种方式
- Maven命令方式(推荐):
bash复制mvn mybatis-generator:generate
- Java代码方式:
java复制List<String> warnings = new ArrayList<>();
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(
new File("src/main/resources/generatorConfig.xml"));
DefaultShellCallback callback = new DefaultShellCallback(true);
MyBatisGenerator generator = new MyBatisGenerator(config, callback, warnings);
generator.generate(null);
- IDE插件方式:
在IntelliJ IDEA中安装"MyBatis Generator Plugin"插件,通过右键菜单执行生成。
4.2 常见错误与解决方案
问题一:Table configuration with catalog null, schema null, table xxx not found
- 检查表名是否拼写正确(区分大小写)
- 检查数据库连接是否有权限访问该表
- 在jdbcConnection中添加属性
<property name="nullCatalogMeansCurrent" value="true"/>
问题二:生成的实体类字段顺序与表定义不一致
- 在jdbcConnection中添加属性:
xml复制<property name="useInformationSchema" value="true"/>
问题三:Blob字段生成过多冗余方法
- 在table配置中添加:
xml复制<property name="useActualColumnNames" value="true"/>
<table tableName="your_table">
<property name="useColumnIndexes" value="true"/>
</table>
4.3 生成结果验证清单
生成完成后,应检查以下关键点:
- 实体类是否包含所有必要字段
- XML中的resultMap是否与实体类属性匹配
- 主键字段是否被正确识别
- 日期类型字段是否使用了合适的Java类型
- 字段注释是否被正确携带
5. 工程化实践建议
5.1 多环境配置管理
在实际项目中,我们通常需要区分开发、测试、生产环境的数据库配置。可以通过Maven的profile机制实现:
xml复制<profiles>
<profile>
<id>dev</id>
<properties>
<jdbc.url>jdbc:mysql://dev-db:3306/app</jdbc.url>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<jdbc.url>jdbc:mysql://prod-db:3306/app</jdbc.url>
</properties>
</profile>
</profiles>
然后在generatorConfig.xml中引用这些属性:
xml复制<jdbcConnection
driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="${jdbc.url}"
userId="${jdbc.user}"
password="${jdbc.password}">
</jdbcConnection>
5.2 增量生成策略
当需要为已有项目添加新表时,为避免覆盖已有代码,可以采用以下策略:
- 使用mergeable文件标识:
xml复制<sqlMapGenerator
targetPackage="mapper"
targetProject="src/main/resources">
<property name="mergeable" value="true"/>
</sqlMapGenerator>
- 为已有实体类添加
@Generated注解识别:
java复制@Generated("org.mybatis.generator.api.MyBatisGenerator")
public class User {
// ...
}
5.3 生成代码的二次加工
虽然MBG生成的代码可以直接使用,但在实际项目中我们通常需要:
- 为实体类添加基类继承:
xml复制<javaModelGenerator>
<property name="rootClass" value="com.example.BaseEntity"/>
</javaModelGenerator>
- 添加自定义接口:
xml复制<javaClientGenerator>
<property name="rootInterface" value="com.example.BaseMapper"/>
</javaClientGenerator>
- 使用插件扩展功能(如添加Lombok注解):
xml复制<plugin type="org.mybatis.generator.plugins.LombokPlugin"/>
