1. MyBatis-Plus代码生成器深度解析
作为Java后端开发中最受欢迎的ORM框架之一,MyBatis-Plus的代码生成器能帮我们快速生成Entity、Mapper、Service、Controller等基础代码。我使用这个工具已经生成了上百个项目的骨架代码,今天就把实战经验完整分享出来。
先说说为什么需要代码生成器。在常规SpringBoot项目中,每个表对应的四层架构代码(Entity/Mapper/Service/Controller)结构高度相似,手工编写不仅重复劳动,还容易出错。而MyBatis-Plus的代码生成器可以根据数据库表结构,自动生成这些基础代码,开发效率能提升3-5倍。特别是在快速原型开发阶段,10张表的项目可以在5分钟内完成所有基础CRUD代码的生成。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与基础配置
2.1 必要依赖引入
首先在pom.xml中添加核心依赖(以SpringBoot 2.7.x为例):
xml复制<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
注意:建议始终使用最新稳定版,可以通过Maven中央仓库查看最新版本号。老版本可能会缺少一些新特性支持。
2.2 数据库连接配置
在application.yml中配置数据库连接:
yaml复制spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/your_db?useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
3. 代码生成器核心配置
3.1 基础生成器配置
创建CodeGenerator类,这是生成器的核心入口:
java复制public class CodeGenerator {
public static void main(String[] args) {
// 代码生成逻辑将在这里实现
}
}
3.2 数据源配置
在main方法中添加数据源配置:
java复制// 数据源配置
DataSourceConfig dsc = new DataSourceConfig.Builder(
"jdbc:mysql://localhost:3306/your_db",
"root",
"123456")
.dbQuery(new MySqlQuery())
.schema("your_db")
.typeConvert(new MySqlTypeConvert())
.keyWordsHandler(new MySqlKeyWordsHandler())
.build();
3.3 全局配置
全局配置控制生成文件的存放位置等基础设置:
java复制// 全局配置
GlobalConfig gc = new GlobalConfig.Builder()
.outputDir(System.getProperty("user.dir") + "/src/main/java")
.author("YourName")
.enableSwagger() // 开启swagger注解
.dateType(DateType.TIME_PACK)
.commentDate("yyyy-MM-dd")
.build();
实操技巧:outputDir建议使用绝对路径,避免因工作目录不同导致生成位置不符合预期。
3.4 包配置
包配置决定了生成的Java类所在的包结构:
java复制// 包配置
PackageConfig pc = new PackageConfig.Builder()
.parent("com.your.package")
.moduleName("system") // 模块名,会作为子包
.entity("entity")
.service("service")
.serviceImpl("service.impl")
.mapper("mapper")
.xml("mapper.xml")
.controller("controller")
.pathInfo(Collections.singletonMap(OutputFile.xml,
System.getProperty("user.dir") + "/src/main/resources/mapper"))
.build();
4. 策略配置详解
4.1 数据库表配置
指定要生成代码的表,以及表前缀处理:
java复制// 策略配置
StrategyConfig strategy = new StrategyConfig.Builder()
.enableCapitalMode() // 开启大写命名
.enableSkipView() // 跳过视图
.disableSqlFilter() // 禁用sql过滤
.addInclude("sys_user", "sys_role") // 设置需要生成的表名
.addTablePrefix("sys_") // 设置过滤表前缀
.build();
4.2 实体类策略
控制Entity类的生成规则:
java复制strategy.entityBuilder()
.enableLombok() // 使用lombok
.enableChainModel() // 链式模型
.enableRemoveIsPrefix() // 去除is前缀
.enableTableFieldAnnotation() // 加上字段注解
.versionColumnName("version") // 乐观锁字段名
.logicDeleteColumnName("deleted") // 逻辑删除字段名
.naming(NamingStrategy.underline_to_camel) // 下划线转驼峰
.columnNaming(NamingStrategy.underline_to_camel)
.addSuperEntityColumns("id", "create_time", "update_time") // 公共字段
.formatFileName("%sEntity") // 实体类命名格式
.build();
4.3 Mapper策略
Mapper接口和XML的生成配置:
java复制strategy.mapperBuilder()
.enableMapperAnnotation() // 加上@Mapper注解
.enableBaseResultMap() // 生成resultMap
.enableBaseColumnList() // 生成columnList
.formatMapperFileName("%sMapper")
.formatXmlFileName("%sMapper")
.build();
4.4 Service策略
Service层代码生成配置:
java复制strategy.serviceBuilder()
.formatServiceFileName("%sService")
.formatServiceImplFileName("%sServiceImpl")
.build();
4.5 Controller策略
Controller层的生成规则:
java复制strategy.controllerBuilder()
.enableHyphenStyle() // 使用连字符风格
.enableRestStyle() // 使用@RestController
.formatFileName("%sController")
.build();
5. 模板引擎配置
MyBatis-Plus支持多种模板引擎,这里以Freemarker为例:
java复制// 模板引擎配置
TemplateConfig templateConfig = new TemplateConfig.Builder()
.disable(TemplateType.ENTITY)
.entity("/templates/entity.java")
.service("/templates/service.java")
.serviceImpl("/templates/serviceImpl.java")
.mapper("/templates/mapper.java")
.mapperXml("/templates/mapper.xml")
.controller("/templates/controller.java")
.build();
高级技巧:可以自定义模板文件,放在resources/templates目录下,实现完全定制化的代码生成。
6. 执行代码生成
最后组装所有配置并执行生成:
java复制AutoGenerator generator = new AutoGenerator(dsc);
generator.global(gc)
.packageInfo(pc)
.strategy(strategy)
.template(templateConfig)
.execute();
执行main方法后,控制台会输出生成日志,成功后会显示类似信息:
code复制[INFO] 表: sys_user -> com.your.package.system.entity.SysUserEntity
[INFO] 生成成功!
7. 生成结果解析
7.1 实体类示例
生成的实体类会包含Lombok注解和字段注解:
java复制@Data
@EqualsAndHashCode(callSuper = true)
@TableName("sys_user")
public class SysUserEntity extends BaseEntity {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@TableField("username")
private String username;
@TableField("password")
private String password;
}
7.2 Mapper接口示例
生成的Mapper接口会继承MyBatis-Plus的BaseMapper:
java复制@Mapper
public interface SysUserMapper extends BaseMapper<SysUserEntity> {
}
7.3 Service层示例
Service接口和实现类会自动注入Mapper:
java复制public interface ISysUserService extends IService<SysUserEntity> {
}
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUserEntity>
implements ISysUserService {
}
7.4 Controller示例
生成的Controller包含基础的CRUD接口:
java复制@RestController
@RequestMapping("/system/sys-user")
public class SysUserController {
@Autowired
private ISysUserService sysUserService;
@GetMapping("/list")
public R list() {
return R.ok().put("data", sysUserService.list());
}
}
8. 高级功能配置
8.1 自定义模板
在resources/templates目录下创建自定义模板文件,例如entity.java.ftl:
freemarker复制package ${package.Entity};
import java.io.Serializable;
<#list table.importPackages as pkg>
import ${pkg};
</#list>
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("${table.name}")
public class ${entity} implements Serializable {
private static final long serialVersionUID = 1L;
<#-- 主键 -->
@TableId(value = "${table.fieldNames[0]}", type = IdType.AUTO)
private ${table.fields[0].propertyType} ${table.fields[0].propertyName};
<#-- 普通字段 -->
<#list table.fields as field>
<#if field.keyFlag><#continue></#if>
@TableField("${field.name}")
private ${field.propertyType} ${field.propertyName};
</#list>
}
8.2 自定义文件输出
可以通过实现IFileCreate接口完全控制文件生成逻辑:
java复制generator.setFileCreate(new IFileCreate() {
@Override
public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) {
// 自定义判断是否创建文件
return !new File(filePath).exists();
}
});
9. 常见问题与解决方案
9.1 生成代码不符合预期
问题现象:生成的字段类型不正确或缺少某些字段。
解决方案:
- 检查数据库表结构是否最新
- 确认数据库连接配置正确
- 检查策略配置中的addInclude/addExclude设置
9.2 主键策略问题
问题现象:生成的实体类主键策略不符合需求。
解决方案:
java复制strategy.entityBuilder()
.idType(IdType.ASSIGN_ID) // 根据需求选择主键策略
.build();
9.3 字段命名风格问题
问题现象:字段名没有按照预期的驼峰命名。
解决方案:
java复制strategy.entityBuilder()
.naming(NamingStrategy.underline_to_camel)
.columnNaming(NamingStrategy.underline_to_camel)
.build();
9.4 生成代码后编译错误
问题现象:生成的代码引用了不存在的类。
解决方案:
- 检查是否缺少相关依赖
- 确认包路径配置正确
- 检查自定义模板是否有语法错误
10. 最佳实践建议
-
版本控制:生成的代码应该纳入版本控制,但生成器配置更应该纳入。这样团队其他成员可以复现相同的生成结果。
-
增量生成:对于已有代码的表,建议先备份原有代码再生成,避免覆盖自定义逻辑。
-
模板定制:花时间定制适合自己项目的模板,可以大幅减少后续的修改工作。
-
生成时机:建议在数据库表结构确定后再生成代码,避免频繁重新生成。
-
代码审查:生成的代码也要进行审查,特别是安全相关的部分如Controller的接口暴露。
我在实际项目中使用MyBatis-Plus代码生成器的经验是:对于标准CRUD操作,可以节省80%以上的编码时间;对于复杂业务,生成的基础代码也能提供很好的起点。特别是在快速迭代的项目中,当数据库结构调整时,重新生成代码可以确保各层代码的一致性。
