JOOQ 如何在不展平属性的情况下获取加入 POJO 的结果?
JOOQ Howto fetch a result of join into POJO without flattening properties?
我有一个以下查询,我加入 tables A
、B
和 C
:
C
通过 C.B_ID
与 B
相关
B
通过 B.A_ID
与 A
相关
我想检索一份报告,其中对于每个 C
,我还想从相应的 B
和 A
中检索字段。
如果只需要字段的子集,则投影和提取到 POJO(具有来自 C
、B
、A
的所需属性)是一种显而易见的方法。
class CReportDTO {
Long c_id;
Long c_field1;
Long c_bid;
Long b_field1;
// ...
CReportDTO(Long c_id, Long c_field1, Long c_bid, Long b_field1) {
// ...
}
// ..
}
public List<CReportDTO> getPendingScheduledDeployments() {
return dslContext.select(
C.ID,
C.FIELD1,
C.B_ID,
B.FIELD1,
B.A_ID
A.FIELD1,
A.FIELD2
)
.from(C)
.join(B)
.on(C.B_ID.eq(B.ID))
.join(A)
.on(B.A_ID.eq(A.ID))
.fetchInto(CReportDTO.class);
};
}
我的问题
如果需要所有字段,我希望我的报告 DTO 包含 A
、B
、C
POJO,而不会将它们展平:
class CReportDTO2 {
C c;
B b;
A a;
CReportDTO2(C c, B b, A a) {
// ...
}
// ..
}
是否可以将我的查询修改为:
- 包括每个 table
中的所有字段
- 将它按摩到
CReportDTO2
中,不要太冗长
您可以使用 jOOQ DefaultRecordMapper
的一个鲜为人知的功能,方法是使用表示 DTO 嵌套结构的点符号为您的字段添加别名:
public List<CReportDTO> getPendingScheduledDeployments() {
return dslContext.select(
// Add these vvvvvvvvvvvvvvvvvvvv
C.ID .as("c.c_id"),
C.FIELD1 .as("c.c_field1"),
C.B_ID .as("c.b_id"),
B.FIELD1 .as("b.b_field1"),
B.A_ID .as("b.a_id")
A.FIELD1 .as("a.a_field1"),
A.FIELD2 .as("a.a_field2")
)
.from(C)
.join(B)
.on(C.B_ID.eq(B.ID))
.join(A)
.on(B.A_ID.eq(A.ID))
.fetchInto(CReportDTO2.class);
}
If Field.getName() is MY_field.MY_nested_field (case-sensitive!), then this field's value will be considered a nested value MY_nested_field, which is set on a nested POJO
请注意,这不适用于您提供的构造函数。您还必须提供默认构造函数,并使您的字段成为非最终字段(以防万一)。
我有一个以下查询,我加入 tables A
、B
和 C
:
C
通过C.B_ID
与 B
通过B.A_ID
与
B
相关
A
相关
我想检索一份报告,其中对于每个 C
,我还想从相应的 B
和 A
中检索字段。
如果只需要字段的子集,则投影和提取到 POJO(具有来自 C
、B
、A
的所需属性)是一种显而易见的方法。
class CReportDTO {
Long c_id;
Long c_field1;
Long c_bid;
Long b_field1;
// ...
CReportDTO(Long c_id, Long c_field1, Long c_bid, Long b_field1) {
// ...
}
// ..
}
public List<CReportDTO> getPendingScheduledDeployments() {
return dslContext.select(
C.ID,
C.FIELD1,
C.B_ID,
B.FIELD1,
B.A_ID
A.FIELD1,
A.FIELD2
)
.from(C)
.join(B)
.on(C.B_ID.eq(B.ID))
.join(A)
.on(B.A_ID.eq(A.ID))
.fetchInto(CReportDTO.class);
};
}
我的问题
如果需要所有字段,我希望我的报告 DTO 包含 A
、B
、C
POJO,而不会将它们展平:
class CReportDTO2 {
C c;
B b;
A a;
CReportDTO2(C c, B b, A a) {
// ...
}
// ..
}
是否可以将我的查询修改为:
- 包括每个 table 中的所有字段
- 将它按摩到
CReportDTO2
中,不要太冗长
您可以使用 jOOQ DefaultRecordMapper
的一个鲜为人知的功能,方法是使用表示 DTO 嵌套结构的点符号为您的字段添加别名:
public List<CReportDTO> getPendingScheduledDeployments() {
return dslContext.select(
// Add these vvvvvvvvvvvvvvvvvvvv
C.ID .as("c.c_id"),
C.FIELD1 .as("c.c_field1"),
C.B_ID .as("c.b_id"),
B.FIELD1 .as("b.b_field1"),
B.A_ID .as("b.a_id")
A.FIELD1 .as("a.a_field1"),
A.FIELD2 .as("a.a_field2")
)
.from(C)
.join(B)
.on(C.B_ID.eq(B.ID))
.join(A)
.on(B.A_ID.eq(A.ID))
.fetchInto(CReportDTO2.class);
}
If Field.getName() is MY_field.MY_nested_field (case-sensitive!), then this field's value will be considered a nested value MY_nested_field, which is set on a nested POJO
请注意,这不适用于您提供的构造函数。您还必须提供默认构造函数,并使您的字段成为非最终字段(以防万一)。