Jooq 实体映射

fil*_*zyk 5 java sql jooq

我有以下架构:

项目 (ID, NAME) Projects_Users (PROJECT_ID, USERS_ID) 用户 (NAME, ID)

实体如下

public class Projects {

    private String name;
    private long id;
    private List<User> users;

    public Projects() {
    }
}


public class User {

    private String name;
    private Long id;
}
Run Code Online (Sandbox Code Playgroud)

如此明显的一对多。项目可以有多个用户。

现在我的目标是编写 jooq 查询,我可以在其中获取已与相应用户一起使用的项目对象。

.select(PROJECT.NAME, PROJECT.ID, USERS)
.from(PROJECT)
.join(USERS_PROJECT).on(USERS_PROJECT.PROJECT_ID=PROJECT.ID)
.join(USERS).on(USERS.ID=USERS_PROJECT.USER_ID)
.fetchInto(Project.class);
Run Code Online (Sandbox Code Playgroud)

但是查询会在期望 ~15 时返回 thousends 结果

Luk*_*der 7

你在做两件事:

运行一个 jOOQ 查询:

.select(PROJECT.NAME, PROJECT.ID, USERS)
.from(PROJECT)
.join(USERS_PROJECT).on(USERS_PROJECT.PROJECT_ID.eq(PROJECT.ID))
.join(USERS).on(USERS.ID.eq(USERS_PROJECT.USER_ID))
.fetch();
Run Code Online (Sandbox Code Playgroud)

这很简单。jOOQ 将上述表达式转换为 SQL 字符串,将其发送到 JDBC,接收结果集并为您提供一个 jOOQ Result。显然,结果是非规范化的(因为您编写了连接),因此您有很多行(大约与USERS_PROJECT表中的行数一样多)。

映射Result到您的 POJO

现在,这就是让你困惑的地方。你调用了fetchInto(Project.class),这只是调用的语法糖fetch()into(Class). 这是两个独立的步骤,特别是,该into(Class)步骤不了解您的查询,也不了解您的意图。因此,它不“知道”您期待大约 15 个独特的项目和嵌套的用户集合。

但是有一些方法可以更明确地映射事物。例如通过使用intoGroups(Class, Class). 这可能不会像您设计的那样返回嵌套类型,而是像

Map<Person, List<User>> map = query.fetch().intoGroups(Person.class, User.class);
Run Code Online (Sandbox Code Playgroud)

您可以从那里手动取出它。或者,您可以编写一个RecordMapper并使用它:

List<Person> list = query.fetch().map(record -> new Person(...));
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用任何推荐的第三方映射器,例如: