在 jOOQ 中,如果我想将表格的一行提取到 jOOQ 自动生成的 POJO 中,我会这样做,例如:
dsl.selectFrom(USER)
.where(USER.U_EMAIL.equal(email))
.fetchOptionalInto(User.class);
现在,假设我想在两个表之间进行连接,例如USER
和 ROLE
,如何将结果提取到这两个表的 POJO 中?
最佳答案
使用嵌套集合
对于较新版本的 jOOQ,您通常会使用一组 ORDBMS 功能,包括:
您将编写类似这样的内容来生成 jOOQ 类型:
Result<Record2<UserRecord, Result<Record1<RoleRecord>>>> result =
dsl.select(
USER,
multiset(
selectFrom(USER_ROLE.role())
.where(USER_ROLE.USER_ID.eq(USER.ID))
))
.from(USER)
.where(USER.U_EMAIL.equal(email))
.fetch();
或者,通过使用所述 ad-hoc converters , 生成您自己的类型:
List<User> result =
dsl.select(
USER.U_ID,
USER.U_EMAIL,
...
multiset(
selectFrom(USER_ROLE.role())
.where(USER_ROLE.USER_ID.eq(USER.ID))
).convertFrom(r -> r.map(Records.mapping(Role::new))))
.from(USER)
.where(USER.U_EMAIL.equal(email))
.fetch(Records.mapping(User::new));
历史答案/备选方案
为了完整起见,还有其他方法可以实现上述内容:
将 POJO 提取到 Map
这是一个使用 ResultQuery.fetchGroups(RecordMapper, RecordMapper)
的解决方案
Map<UserPojo, List<RolePojo>> result =
dsl.select(USER.fields())
.select(ROLE.fields())
.from(USER)
.join(USER_TO_ROLE).on(USER.USER_ID.eq(USER_TO_ROLE.USER_ID))
.join(ROLE).on(ROLE.ROLE_ID.eq(USER_TO_ROLE.ROLE_ID))
.where(USER.U_EMAIL.equal(email))
.fetchGroups(
// Map records first into the USER table and then into the key POJO type
r -> r.into(USER).into(UserPojo.class),
// Map records first into the ROLE table and then into the value POJO type
r -> r.into(ROLE).into(RolePojo.class)
);
请注意,如果您想改用 LEFT JOIN
(以防用户不一定具有任何角色,并且您希望为每个用户获取一个空列表),则必须翻译NULL
角色自己清空列表。
确保您已激活在 POJO 上生成 equals()
和 hashCode()
以便能够将它们放入 HashMap
作为键:
<pojosEqualsAndHashCode>true</pojosEqualsAndHashCode>
使用自定义的分层 POJO 并将它们提取到嵌套集合中
一个经常重复出现的问题是如何在 jOOQ 中获取嵌套集合,即如果您的结果数据结构如下所示怎么办:
class User {
long id;
String email;
List<Role> roles;
}
class Role {
long id;
String name;
}
从 jOOQ 3.14 开始,如果您的 RDBMS 支持它,您现在可以使用 SQL/XML 或 SQL/JSON 作为中间格式来嵌套集合,然后使用 Jackson、Gson 或 JAXB 将文档映射回您的Java 类(或者保留 XML 或 JSON,如果这是您首先需要的)。例如:
List<User> users =
ctx.select(
USER.ID,
USER.EMAIL,
field(
select(jsonArrayAgg(jsonObject(ROLE.ID, ROLE.NAME)))
.from(ROLES)
.join(USER_TO_ROLE).on(ROLE.ROLE_ID.eq(USER_TO_ROLE.ROLE_ID))
.where(USER_TO_ROLE.USER.ID.eq(USER.ID))
).as("roles")
)
.from(USER)
.where(USER.EMAIL.eq(email))
.fetchInto(User.class);
请注意,JSON_ARRAYAGG()
将空集合聚合到 NULL
中,而不是聚合到空的 []
中。 If that's a problem, use COALESCE()
关于java - jOOQ 我可以将两个表的连接提取到各自的 POJO 中吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38222957/