1. MyBatis逆向工程实战指南(Spring整合完整版)
在Java企业级开发中,数据持久化是每个项目都绕不开的核心环节。作为主流ORM框架之一,MyBatis凭借其灵活性和高性能广受欢迎。但手动编写每个实体类、Mapper接口和XML映射文件无疑是项重复劳动。这正是MyBatis Generator(MBG)大显身手的地方。
我曾在多个电商和ERP系统中使用这套方案,单次生成上百张表的完整数据层代码,开发效率提升近70%。本文将分享经过实战检验的完整配置方案,特别适合以下场景:
- 新项目需要快速搭建数据访问层
- 遗留系统数据库表结构变更频繁
- 团队需要统一代码规范
- 需要与Spring框架深度整合
2. 环境准备与项目结构
2.1 依赖管理关键点
在pom.xml配置依赖时,版本兼容性是需要特别注意的坑。经过多个项目验证,我推荐以下稳定组合:
xml复制<!-- MyBatis核心三件套 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.7</version>
</dependency>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.7</version>
</dependency>
<!-- 数据库相关 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version> <!-- 根据MySQL版本选择 -->
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.15</version> <!-- 生产验证过的稳定版 -->
</dependency>
特别注意:MySQL 5.x和8.x的驱动类不同,5.x使用
com.mysql.jdbc.Driver,8.x需要使用com.mysql.cj.jdbc.Driver,否则会报驱动加载错误。
2.2 项目结构规范
合理的目录结构能避免90%的路径配置问题。推荐采用Maven标准结构,并特别注意以下要点:
code复制src/
├── main/
│ ├── java/
│ │ └── com/
│ │ └── yourpackage/
│ │ ├── model/ # 实体类
│ │ ├── dao/ # Mapper接口
│ │ ├── service/ # 业务层
│ │ └── generator/ # 逆向工程执行代码
│ └── resources/
│ ├── mapper/ # XML映射文件
│ ├── db.properties # 数据库配置
│ └── generatorConfig.xml # MBG核心配置
└── test/ # 测试代码
在团队协作中,建议将逆向工程相关代码放在独立模块(如core-generator),与业务代码分离。
3. 逆向工程核心配置详解
3.1 generatorConfig.xml深度解析
这个配置文件是MBG的核心,每个配置项都直接影响生成结果。以下是最佳实践配置:
xml复制<context id="DB2Tables" targetRuntime="MyBatis3">
<!-- 1. 数据库连接配置 -->
<jdbcConnection
driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/yourdb?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8"
userId="root"
password="123456">
<!-- MySQL8+必须添加此属性 -->
<property name="nullCatalogMeansCurrent" value="true"/>
</jdbcConnection>
<!-- 2. 实体类生成策略 -->
<javaModelGenerator targetPackage="com.yourpackage.model"
targetProject="src/main/java">
<property name="enableSubPackages" value="false"/>
<property name="trimStrings" value="true"/>
<!-- 生成字段常量 -->
<property name="rootClass" value="com.yourpackage.model.BaseEntity"/>
</javaModelGenerator>
<!-- 3. XML映射文件配置 -->
<sqlMapGenerator targetPackage="mapper"
targetProject="src/main/resources">
<property name="enableSubPackages" false/>
</sqlMapGenerator>
<!-- 4. Mapper接口配置 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.yourpackage.dao"
targetProject="src/main/java">
<!-- 添加@Mapper注解 -->
<property name="annotated" value="true"/>
</javaClientGenerator>
<!-- 5. 表配置 -->
<table tableName="%"
enableCountByExample="false"
enableUpdateByExample="false"
enableDeleteByExample="false"
enableSelectByExample="false">
<!-- 生成的主键策略 -->
<generatedKey column="id" sqlStatement="MySQL" identity="true"/>
</table>
</context>
关键配置说明:
nullCatalogMeansCurrent:解决MySQL8+的元数据获取问题rootClass:所有实体类继承的基类,可定义公共字段annotated:为Mapper接口添加@Mapper注解,便于Spring扫描
3.2 多环境配置技巧
在实际项目中,我们通常需要区分开发、测试、生产环境。可以通过Maven的profile机制实现:
xml复制<profiles>
<profile>
<id>dev</id>
<properties>
<jdbc.url>jdbc:mysql://dev-db:3306/db</jdbc.url>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<jdbc.url>jdbc:mysql://prod-db:3306/db</jdbc.url>
</properties>
</profile>
</profiles>
然后在generatorConfig.xml中使用Maven变量:
xml复制<jdbcConnection
connectionURL="${jdbc.url}"
... />
执行时通过-P参数指定环境:mvn mybatis-generator:generate -Pdev
4. 代码生成与执行策略
4.1 两种执行方式对比
| 方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Java代码执行 | 灵活可控,便于调试 | 需要编写执行类 | 复杂定制需求 |
| Maven插件执行 | 配置简单,一键执行 | 调试困难 | 简单项目,CI/CD集成 |
对于大多数项目,我推荐使用Maven插件方式,配置如下:
xml复制<build>
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.7</version>
<executions>
<execution>
<id>generate-mybatis</id>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<overwrite>true</overwrite>
<verbose>true</verbose>
</configuration>
</plugin>
</plugins>
</build>
4.2 增量生成策略
在实际开发中,我们经常需要面对表结构变更的情况。MBG提供了几种生成策略:
- 全量覆盖:设置
<overwrite>true</overwrite>,每次都会重新生成所有文件 - 合并模式:设置
<mergeable>true</mergeable>,只修改标记部分 - 增量生成:通过
<table>标签的schema和catalog属性控制生成范围
重要提示:在已有项目中启用逆向工程时,建议先备份现有Mapper文件,特别是包含自定义SQL的部分。
5. Spring整合深度优化
5.1 数据源最佳配置
Druid是生产环境推荐使用的连接池,完整配置如下:
properties复制# druid.properties
druid.url=jdbc:mysql://localhost:3306/db
druid.username=root
druid.password=123456
druid.initialSize=5
druid.maxActive=20
druid.minIdle=5
druid.maxWait=60000
druid.validationQuery=SELECT 1
druid.testWhileIdle=true
druid.testOnBorrow=false
druid.testOnReturn=false
对应的Spring配置:
xml复制<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="url" value="${druid.url}"/>
<property name="username" value="${druid.username}"/>
<property name="password" value="${druid.password}"/>
<!-- 其他配置... -->
</bean>
5.2 MyBatis-Spring高级配置
xml复制<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath*:mapper/**/*.xml"/>
<property name="typeAliasesPackage" value="com.yourpackage.model"/>
<!-- 分页插件 -->
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<value>
helperDialect=mysql
reasonable=true
</value>
</property>
</bean>
</array>
</property>
</bean>
5.3 事务管理增强
对于需要精细控制的事务场景,可以使用注解式配置:
java复制@Configuration
@EnableTransactionManagement
public class TransactionConfig {
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean
public TransactionTemplate transactionTemplate(PlatformTransactionManager manager) {
return new TransactionTemplate(manager);
}
}
然后在Service层使用:
java复制@Service
public class UserServiceImpl implements UserService {
@Autowired
private TransactionTemplate transactionTemplate;
public void complexOperation() {
transactionTemplate.execute(status -> {
// 事务内操作
return null;
});
}
}
6. 高级特性与定制开发
6.1 自定义类型处理器
当需要处理特殊数据类型(如JSON、枚举)时,可以创建自定义TypeHandler:
java复制@MappedTypes(JSONObject.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
public class JsonTypeHandler extends BaseTypeHandler<JSONObject> {
// 实现类型转换方法
}
在generatorConfig.xml中配置:
xml复制<table tableName="user">
<columnOverride column="ext_info"
javaType="com.alibaba.fastjson.JSONObject"
typeHandler="com.yourpackage.handler.JsonTypeHandler"/>
</table>
6.2 动态表名支持
在分库分表场景下,可以通过继承MBG生成的Mapper接口实现动态表名:
java复制public interface UserMapper extends BaseMapper<User> {
@Select("SELECT * FROM ${tableName} WHERE id = #{id}")
User selectById(@Param("tableName") String tableName, @Param("id") Long id);
}
6.3 多数据源整合
对于需要访问多个数据库的项目,可以配置多个SqlSessionTemplate:
java复制@Configuration
public class MyBatisConfig {
@Bean
@Primary
public SqlSessionTemplate primaryTemplate(SqlSessionFactory factory) {
return new SqlSessionTemplate(factory);
}
@Bean
public SqlSessionTemplate secondaryTemplate(
@Qualifier("secondaryDataSource") DataSource dataSource) {
SqlSessionFactory factory = createFactory(dataSource);
return new SqlSessionTemplate(factory);
}
}
7. 性能优化实践
7.1 批量操作优化
MBG生成的Mapper默认支持批量插入,但需要手动启用:
java复制@Autowired
private SqlSessionTemplate sqlSessionTemplate;
public void batchInsert(List<User> users) {
UserMapper mapper = sqlSessionTemplate.getMapper(UserMapper.class);
for (User user : users) {
mapper.insert(user);
}
// 或者使用ExecutorType.BATCH模式
}
7.2 二级缓存配置
在sqlMapConfig.xml中启用二级缓存:
xml复制<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
在Mapper XML中声明缓存:
xml复制<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
7.3 懒加载策略
对于关联查询,可以配置懒加载:
xml复制<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
8. 常见问题解决方案
8.1 生成代码不符合预期
问题现象:
- 字段缺失或类型不正确
- 方法签名不符合要求
解决方案:
- 检查
<table>标签的配置 - 使用
<columnOverride>精确控制字段映射 - 验证数据库元数据是否正确读取
8.2 整合Spring后注入失败
问题现象:
- @Autowired Mapper接口时报错
- 提示"No qualifying bean"
排查步骤:
- 确认
@MapperScan或MapperScannerConfigurer配置正确 - 检查生成的Mapper接口是否有@Mapper注解
- 验证SqlSessionFactory配置
8.3 性能问题
典型场景:
- 大批量数据操作慢
- 内存占用高
优化方案:
- 使用Batch执行器
- 合理配置连接池参数
- 优化事务范围
9. 最佳实践总结
经过多个项目的实践验证,我总结了以下黄金法则:
- 版本锁定原则:固定MyBatis、MBG和驱动版本,避免兼容性问题
- 配置分离原则:将数据库配置、MBG配置与环境解耦
- 增量生成策略:生产环境谨慎使用overwrite模式
- 分层验证策略:从Mapper到Service逐层测试
- 监控接入:集成Druid监控和MyBatis日志
对于大型项目,建议将逆向工程作为独立模块,通过Maven多模块管理。同时建立代码生成规范文档,包括:
- 命名规范
- 异常处理规则
- 事务边界定义
- 性能约束指标
这套方案在我主导的电商平台项目中,成功支持了日均百万级订单的数据访问需求,系统稳定运行超过两年。关键在于合理配置和持续优化,而非简单套用默认设置。