如何使用jooq连接3个表并迭代结果?

问题描述 投票:0回答:1

我有课程表、学生表、时间表表。

table course(id, name, ....), 
table student(id, name, ...), 
table schedule(id, c_id, s_id).

现在我想将时间表表与课程和学生表进行左连接。

问题(1):

在 jooq 中连接这 3 个表的最佳方法是什么?我认为它就像:

TableLike<?> firstjoin = sql
    .select()
    .from(Tables.SCHEUDLE)
    .leftOuterJoin(Tables.COURSE)
    .on(Tables.SCHEDULE.CID.eq(Tables.COURSE.ID))
    .asTable();

Result<?> result = sql
    .select()
    .from(firstjoin)
    .leftOuterJoin(Tables.STUDENT)
    .on(Tables.SCHEDULE.SID.eq(Tables.STUDENT.ID))
    .fetch();

问题(2):

当我得到结果时,将结果拆分为 Student 对象和 Course 对象的最佳方法是什么?我的意思是,既然类型是结果?,有什么方法我们可以将结果映射到学生、课程实体,而不是像这样乏味地做一些事情:

for(Record r: result){
   Student s = new Student(r.filed(), r.filed()...);
   Course c = new Course(r.filed(), r.filed()....)
}
java join mapping jooq
1个回答
21
投票

答案1

在 jooq 中连接这 3 个表的最佳方法是什么?我认为这就像[...]

虽然您的查询是正确,但我不会像您一样加入。您的方法创建了一个派生表,其中

  1. 增加了没有价值的 SQL 语句的复杂性,例如维持声明时
  2. 防止某些对派生表处理不当的数据库进行优化

相反,只需在一条语句中连接两个表即可:

Result<?> result = sql
    .select()
    .from(SCHEUDLE)
    .leftOuterJoin(COURSE)
    .on(SCHEDULE.CID.eq(COURSE.ID))
    .leftOuterJoin(STUDENT)
    .on(SCHEDULE.SID.eq(STUDENT.ID))
    .fetch();

答案2

您可以使用各种

Record.into()
方法之一,例如
Record.into(Table)

for (Record r : result) {
    StudentRecord s = r.into(STUDENT);
    CourseRecord c = r.into(COURSE);
}

关于替代方法的一般性评论

从 jOOQ 3.15 开始,jOOQ 允许使用其标准 SQL

MULTISET
值构造函数 运算符来嵌套集合,可以在各种 RDBMS 上使用 SQL/JSON 或 SQL/XML 进行模拟。这种方法可能会更好地解决您遇到的根本问题。

sql.select(
        SCHEDULE,
        multiset(
            select(
                SCHEDULE.course(),
                multiset(
                    selectFrom(SCHEDULE.course().student())
                )
            )
            .from(SCHEDULE.course())
        )
    )
   .from(SCHEDULE)
   .fetch();

上面的方法还使用了:

此外,为了将 jOOQ 记录映射到您自己的 DTO,您可能需要使用 jOOQ 3.15 的临时转换 可能性

© www.soinside.com 2019 - 2024. All rights reserved.