jOOQ 我可以将两个表的联接提取到各自的POJO中吗?

2022-09-01 22:42:41

在jOOQ中,如果我想将表的一行提取到jOOQ自动生成的POJO中,我会这样做,例如:

dsl.selectFrom(USER)
                .where(USER.U_EMAIL.equal(email))
                .fetchOptionalInto(User.class);

现在,假设我想在两个表之间进行联接,例如 和 ,如何将结果提取到这两个表的 POJO 中?USERROLE


答案 1

将 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 JOINNULL

确保您已激活生成和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);

请注意,将空集聚合到 中,而不是聚合到空集 。如果这是一个问题,请使用 COALESCE()JSON_ARRAYAGG()NULL[]


答案 2

卢卡斯·埃德尔(Lukas Eder)继续很好的答案:

如果您需要列表结构作为回报,或者您无法在POJO中省略等于或哈希码,则可以将其提取到List<Pair>

               List<Pair<UserPojo, 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))
       .fetch(record -> {
                UserPojo userPojo = r.into(USER).into(UserPojo.class);
                RolePojo rolePojo = r.into(ROLE).into(RolePojo.class);
                return new ImmutablePair<>(zoneEntity, userEntity);
            });

推荐