本文目录导读:

- 引言:告别“复制粘贴”,让机器去写机器
- 案例一:基于MyBatis-Plus的自动化CRUD生成器
- 案例二:策略模式下的动态SQL生成器
- 案例三:基于Freemarker的DTO/VO转换层生成
- 案例四:异步任务与定时任务的脚手架生成
- 案例五:简易RESTful API文档与Mock数据生成器
- 高频问答(FAQ):关于代码生成器的5个灵魂拷问
- 总结:将代码生成嵌入你的CI/CD流水线
五个高可用Java代码生成案例,彻底告别重复CRUD**
目录导读
- 为什么你需要“代码生成”而非“手写代码”?
- 基于MyBatis-Plus的CRUD代码自动生成器(含核心代码)
- 策略模式下的动态SQL生成器(应对复杂查询)
- 基于模板引擎(Freemarker)的DTO/VO转换层生成
- 异步任务与定时任务的脚手架代码生成
- 简易RESTful API文档与Mock数据生成器
- 高频问答(FAQ):关于代码生成器的5个灵魂拷问
- 如何将代码生成嵌入你的CI/CD流水线
引言:告别“复制粘贴”,让机器去写机器
在Java后端开发中,最耗时的往往不是核心业务逻辑,而是那些枯燥的、重复的样板代码:Entity、Mapper、Service、Controller、DTO、VO,据统计,在一个典型的业务系统中,这类代码占比高达40%-60%。代码生成案例的价值在于:将“人写代码”转变为“配置驱动生成代码”,从而将开发者的精力聚焦于真正的业务规则。
本文将结合搜索引擎中的主流实践(如MyBatis-Generator、EasyCode插件、自定义模板引擎),去伪存真,提供5个可直接落地的Java代码生成案例,这些案例不仅包含代码,更包含设计思路,帮助你举一反三。
基于MyBatis-Plus的自动化CRUD生成器
痛点:每新建一张表,都要手动写一遍基础的增删改查。
实现方案:利用MyBatis-Plus的AutoGenerator,结合Freemarker模板,实现“一键生成”。
核心代码示例(精简版):
public static void main(String[] args) {
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/your_db?useUnicode=true&useSSL=false");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("password");
// 代码生成器
AutoGenerator mpg = new AutoGenerator();
mpg.setDataSource(dsc);
// 包配置(关键:定义生成路径)
PackageConfig pc = new PackageConfig();
pc.setParent("com.example.generated");
pc.setEntity("entity");
pc.setMapper("mapper");
pc.setService("service");
pc.setServiceImpl("service.impl");
pc.setController("controller");
mpg.setPackageInfo(pc);
// 策略配置(表名过滤)
StrategyConfig strategy = new StrategyConfig();
strategy.setInclude("user", "order"); // 指定表名
strategy.setEntityLombokModel(true); // 使用Lombok
strategy.setRestControllerStyle(true);
mpg.setStrategy(strategy);
mpg.execute();
}
生成结果:自动生成User、UserMapper、UserService、UserController,且包含分页、条件构造器等高级功能。
SEO优化点:此案例在搜索引擎中搜索量极大,核心关键词为MyBatis-Plus 代码生成,本文强调高可用和自动化,直击用户痛点。
策略模式下的动态SQL生成器
痛点:传统的<script>标签写动态SQL容易出错,且无法复用。
实现方案:通过Java代码构建QueryWrapper,并封装成模板方法,实现“参数对象”到“SQL语句”的转换。
核心逻辑:
- 定义查询参数对象(如
UserQuery)。 - 使用策略接口处理不同字段的查询逻辑(等于、模糊、范围)。
- 生成SQL时,利用
ReflectionUtils遍历字段,自动拼接WHERE条件。
代码片段:
public class SqlGenerator<T> {
public String buildSelectSql(Class<T> clazz, Object queryParam) {
StringBuilder sql = new StringBuilder("SELECT * FROM ");
sql.append(getTableName(clazz)).append(" WHERE 1=1");
// 遍历字段,利用反射获取注解值
Arrays.stream(clazz.getDeclaredFields()).forEach(field -> {
field.setAccessible(true);
String columnName = field.getAnnotation(Column.class).name();
try {
Object value = field.get(queryParam);
if (value != null) {
sql.append(" AND ").append(columnName).append(" = '").append(value).append("'");
}
} catch (IllegalAccessException e) { e.printStackTrace(); }
});
return sql.toString();
}
}
注意:此案例更偏向于工具类封装,适合动态报表查询等场景。
基于Freemarker的DTO/VO转换层生成
痛点:Entity(持久层)与VO(视图层)字段几乎一致,但就是需要手写BeanUtils.copyProperties()或setter。
实现方案:使用Freemarker模板,读取.java文件中的注解和字段,生成对应的XxxDTO和XxxVO,同时生成转换工具类。
模板示例(vo.ftl):
package ${packageName}.vo;
import lombok.Data;
import java.util.Date;
@Data
public class ${className}VO {
<#list fields as field>
private ${field.type} ${field.name};
</#list>
}
生成逻辑:通过Java的Reflection解析Entity字段,填充模板,输出至指定目录。
异步任务与定时任务的脚手架生成
痛点:项目初始化时,需要配置线程池、定时任务开关,且写法不一。
实现方案:生成一个包含@Async和@Scheduled注解的Service基类,并配合ThreadPoolTaskExecutor配置。
生成的代码结构:
BaseAsyncService.java:定义@Async("taskExecutor")公共方法。OrderTimeoutTask.java:继承基类,使用@Scheduled(cron = "0 0/5 * * * ?")。
核心价值:将并发配置与业务代码解耦,生成的代码直接可运行,无需额外配置。
简易RESTful API文档与Mock数据生成器
痛点:前后端联调时,后端接口还没写好,前端只能干等。
实现方案:根据Controller的@RequestMapping和@RequestParam注解,生成一份JSON格式的Mock数据,并启动一个内置的Mock服务器(如WireMock)。
实现要点:
- 扫描所有
@RestController。 - 解析方法签名,生成
MockResponse(字段使用随机值填充)。 - 将映射关系写入
mappings.json。
高频问答(FAQ):关于代码生成器的5个灵魂拷问
Q1:代码生成器生成的代码扩展性差,后面需求变了怎么办?
A:关键在于“生成的代码不要二次修改”,正确做法是:生成的基类代码不可修改,扩展逻辑写在子类中(如UserServiceImpl继承GeneratedUserServiceImpl),所有案例均遵循此原则。
Q2:用代码生成器会不会让团队代码风格不统一?
A:恰恰相反,通过统一模板,强制约束了代码风格,建议将代码生成器项目作为团队内部公共组件,统一维护模板版本。
Q3:生成代码后,数据库字段变了,如何同步?
A:推荐“逆向工程”思路,案例一中的AutoGenerator支持每次重新生成,并覆盖基类(不覆盖子类),建议生成后对比Git Diff,人工确认变更。
Q4:是否支持生成复杂的多表关联查询代码? A:单表CRUD可以100%生成,多表关联建议采用案例二中的“动态SQL生成器”,由开发者定义SQL模板,生成器负责参数绑定,而非完全自动生成。
Q5:除了Java后端,能否生成前端代码?
A:可以,只要模板引擎支持,同理可生成Vue/React的表格页、表单页,但本文聚焦后端,前端生成案例可参考OpenAPI Generator,原理一致。
将代码生成嵌入你的CI/CD流水线
我们不只是讨论“一次性生成”,而是将其视为持续集成的工具,建议的落地流程如下:
- 数据库变更 -> 触发
Jenkins或GitHub Actions任务。 - 运行生成器 -> 执行上述案例中的Java代码或Maven插件。
- 自动提交 -> 生成代码后,自动创建Pull Request,由代码审查者合并。
- 自动化测试 -> 单元测试覆盖生成的Mapper与Service层。
推荐工具清单:
- 数据库逆向:
MyBatis Generator(MBG) 或MyBatis-Plus Generator - 模板引擎:
Freemarker/Velocity - IDE插件:
EasyCode(IntelliJ IDEA) - 通用代码生成API:
OpenAPI Generator(支持API Client/Server)
最后提醒:代码生成不是银弹,它解决的是“重复”问题,而非“复杂”问题。优秀的架构师,会把复杂留给自己,把简单留给生成器,把稳定留给业务。 如果你还没尝试过,建议从案例一做起,体验一次“机器替你敲键盘”的快感。