如何使用jOOQ将单表数据映射为嵌套结构的Catalog POJO
如何使用jOOQ将单表数据映射为嵌套结构的Catalog POJO
没问题,这个场景完全可以用jOOQ的multiset来实现,而且非常合适!咱们一步步来拆解怎么做:
你的核心需求是把单表中同一作者的所有书籍条目嵌套成List<BookEntry>,再和作者名一起封装到Catalog POJO里。jOOQ的multiset(包括multisetAgg聚合函数)刚好就是用来处理这种行转嵌套集合的场景,不管是跨表关联还是单表分组都适用。
1. 先调整POJO(确保有可映射的构造方法)
jOOQ的Records.mapping工具类需要POJO有对应参数的构造方法,我们给两个类加上构造方法(用Lombok的@AllArgsConstructor替代也可以):
import java.util.Date; import java.util.List; public class Catalog { private String author; private List<BookEntry> bookEntries; // 用于jOOQ映射的构造方法 public Catalog(String author, List<BookEntry> bookEntries) { this.author = author; this.bookEntries = bookEntries; } // 可选:getter/setter public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public List<BookEntry> getBookEntries() { return bookEntries; } public void setBookEntries(List<BookEntry> bookEntries) { this.bookEntries = bookEntries; } } public class BookEntry { private String bookName; private Date publicationDate; // 用于jOOQ映射的构造方法 public BookEntry(String bookName, Date publicationDate) { this.bookName = bookName; this.publicationDate = publicationDate; } // 可选:getter/setter public String getBookName() { return bookName; } public void setBookName(String bookName) { this.bookName = bookName; } public Date getPublicationDate() { return publicationDate; } public void setPublicationDate(Date publicationDate) { this.publicationDate = publicationDate; } }
2. 用multisetAgg实现单表分组嵌套(推荐)
jOOQ 3.15+提供的multisetAgg是专门的聚合函数,能直接在GROUP BY后聚合当前分组的字段为嵌套集合,代码更简洁:
// 假设你已经初始化好DSLContext实例,命名为dsl // 给表起别名,避免字段冲突 var c = CATALOG.as("c"); List<Catalog> catalogList = dsl.select( c.AUTHOR, // 聚合当前作者的所有书籍字段,转换为List<BookEntry> multisetAgg(c.BOOK_NAME, c.PUBLICATION_DATE) .convertFrom(records -> records.map(Records.mapping(BookEntry::new))) ) .from(c) .groupBy(c.AUTHOR) // 按作者分组 // 把查询结果映射为Catalog对象 .fetch(Records.mapping(Catalog::new));
3. 用关联子查询+multiset的实现方式
如果你更习惯用关联子查询的方式(和你之前跨表用multiset的逻辑更像),也可以这么写:
var c = CATALOG.as("c"); List<Catalog> catalogList = dsl.select( c.AUTHOR, // 用multiset包裹关联子查询,获取当前作者的所有书籍 multiset( select( CATALOG.BOOK_NAME, CATALOG.PUBLICATION_DATE ) .from(CATALOG) .where(CATALOG.AUTHOR.eq(c.AUTHOR)) // 关联外层的作者 ).convertFrom(records -> records.map(Records.mapping(BookEntry::new))) ) .from(c) .groupBy(c.AUTHOR) .fetch(Records.mapping(Catalog::new));
关键说明
- 两种方式最终效果完全一致,
multisetAgg是更针对聚合场景的简化写法,推荐使用。 - jOOQ会自动处理数据库字段名到POJO属性的映射(比如
BOOK_NAME对应bookName,遵循驼峰转下划线的默认规则),如果字段名规则不一致,可以用@Column注解指定,或者在查询里给字段加别名。 - 关于日期类型:如果你的数据库用的是
DATE/TIMESTAMP,jOOQ会自动映射到Java的Date;如果推荐用Java 8+的时间API(比如LocalDate),只需要把POJO里的Date改成LocalDate,jOOQ也会自动适配。
这样就能完美把单表的数据按作者分组,转换成你需要的嵌套结构POJO啦!
备注:内容来源于stack exchange,提问作者Conner
相关产品推荐
相关产品推荐

