
本文介绍如何在 jooq 代码生成中实现 pojo 的选择性生成(仅针对特定表),解决“数百张表中只需为约 10 张表生成 pojo”的实际需求,并提供双阶段生成、maven 配置复用及 xml 序列化替代方案等专业实践。
本文介绍如何在 jooq 代码生成中实现 pojo 的选择性生成(仅针对特定表),解决“数百张表中只需为约 10 张表生成 pojo”的实际需求,并提供双阶段生成、maven 配置复用及 xml 序列化替代方案等专业实践。
jOOQ 默认对所有启用的表统一生成 Record 和 POJO 类,但官方尚未支持「仅对部分表生成 POJO」的细粒度配置(相关功能请求 GitHub #5263 仍处于待办状态,短期内 unlikely 被实现)。不过,无需等待官方支持——通过两次独立执行 jOOQ 代码生成器,即可精准达成目标。
✅ 推荐方案:分阶段生成(Two-Pass Generation)
核心思路:将生成任务拆分为两个逻辑阶段:
-
第一阶段:生成全部 Record 类(排除不需参与业务的表,沿用现有
excludes); -
第二阶段:仅生成 POJO 类,且通过
includes显式限定目标表(如user,order,product等共 10 张表)。
这样既复用原有配置,又实现 POJO 的按需生成,避免冗余类污染源码。
? Maven 配置示例(推荐使用 <pluginmanagement></pluginmanagement> 复用公共配置)
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.jooq</groupId>
<artifactId>jooq-codegen-maven</artifactId>
<version>3.18.7</version>
<executions>
<!-- 阶段一:生成 Records(含 excludes) -->
<execution>
<id>generate-records</id>
<phase>generate-sources</phase>
<goals><goal>generate</goal></goals>
<configuration>
<generator>
<database>
<includes>.*</includes>
<excludes>audit_log|schema_history|temp_.*</excludes> <!-- 复用现有排除规则 -->
</database>
<generate>
<pojos>false</pojos> <!-- 关键:禁用 POJO -->
<records>true</records>
</generate>
<target>
<packageName>com.example.db.records</packageName>
</target>
</generator>
</configuration>
</execution>
<!-- 阶段二:仅生成指定表的 POJO -->
<execution>
<id>generate-pojos</id>
<phase>generate-sources</phase>
<goals><goal>generate</goal></goals>
<configuration>
<generator>
<database>
<!-- 仅匹配需 POJO 的表名(支持正则) -->
<includes>user|order|product|customer|invoice|payment|address|category|tag|setting</includes>
<excludes>.*</excludes> <!-- 兜底排除其余所有表 -->
</database>
<generate>
<pojos>true</pojos> <!-- 关键:仅启用 POJO -->
<records>false</records>
</generate>
<target>
<packageName>com.example.db.pojos</packageName>
</target>
</generator>
</configuration>
</execution>
</plugins>
</plugin>
</plugins>
</pluginManagement>
</build>⚠️ 注意事项:
- 两次执行必须使用不同
target.packageName,防止类名冲突;includes和excludes均支持正则表达式,确保精确匹配表名(区分大小写需与数据库一致);- 若使用 Gradle,可借助
jooqCodegentask 的多配置实现类似逻辑(通过configurationName隔离)。
? 替代思路:利用 jOOQ 内置 XML 导出能力(降低 POJO 依赖)
你提到需将历史数据序列化为 XML 并与新数据统一展示。值得强调:jOOQ 原生支持高性能、类型安全的 XML 导出/导入,无需额外 POJO 即可完成:
// 导出历史记录为 XML(直接基于 Record)
Result<Record> history = create.selectFrom(USERS).where(USERS.CREATED_AT.lt("2023-01-01")).fetch();
String xml = history.formatXML(); // 一行生成标准 XML
// 反向导入(适用于轻量场景)
Result<Record> imported = Result.intoXML(xml);完整文档见:jOOQ XML Exporting。该方式规避了手动维护 POJO 的开销,且与 Record 完全兼容,适合过渡期快速落地。
✅ 总结
- ❌ 不要等待
pojoIncludes这类专属配置(短期无望); - ✅ 推荐采用 双阶段生成策略 —— 灵活、稳定、零侵入;
- ✅ 善用
includes/excludes正则 + 独立packageName实现物理隔离; - ? 评估 jOOQ 原生 XML 功能,可能比引入 POJO 更简洁高效;
- ? 此方案完美支撑“渐进式重构”:先为关键表生成 POJO,后续逐步扩展,不影响存量 Record 使用。

















