【问题标题】:Join 3 tables and map one to many relation加入 3 个表并映射一对多关系
【发布时间】:2020-12-13 09:24:42
【问题描述】:

如何映射具有一对多关系的记录。说下面的查询返回每个时间表的课程列表和学生列表,我想查询多个时间表的

List<Record> result = sql
    .select()
    .from(SCHEUDLE)
    .innerJoin(COURSE)
    .on(SCHEDULE.ID.eq(COURSE.SID))
    .leftJoin(STUDENT)
    .on(SCHEDULE.ID.eq(STUDENT.SID))
    .where(SCHEUDLE.ID.in(List.of(10,11,12)))
    .fetch();

如何将记录列表映射到时间表列表,每个时间表都有课程列表和学生列表?

将域视为

public class Scheudule{
 String scheuduleName;
 List<Course> courses;
 List<Student> students 
}

【问题讨论】:

    标签: java sql jooq


    【解决方案1】:

    在 jOOQ 3.14 之前

    从历史上看,jOOQ 不提供广泛的对象图映射功能,因此建议使用诸如 SimpleFlatMapper 之类的第三方工具来完成此类映射任务。

    最大的警告是认为连接(包括左连接)是创建嵌套集合的适当方式是错误的。在您的情况下,连接的 COURSESTUDENT 表之间存在笛卡尔积,这几乎不可能(更不用说效率低下)再次进行重复数据删除。如果你想用连接解决这个问题,你必须运行至少 2 个查询:

    • 获取SCHEDULE / COURSE 关系的查询
    • 获取SCHEDULE / STUDENT 关系的查询

    jOOQ 3.14 之后

    幸运的是,jOOQ 3.14 现在可以解决这些问题。从jOOQ 3.14's SQL/XML and SQL/JSON support 开始,可以实现一种更加SQL 风格的映射嵌套集合的方法。例如,使用 JSON:

    List<Schedule> result =
    sql.select(
         jsonEntry("scheduleName", SCHEDULE.NAME),
         jsonEntry("courses", field(
           select(jsonArrayAgg(jsonObject(COURSE.fields())))
           .from(COURSE)
           .where(COURSE.SID.eq(SCHEDULE.ID))
         )),
         jsonEntry("students", field(
           select(jsonArrayAgg(jsonObject(STUDENT.fields())))
           .from(STUDENT)
           .where(STUDENT.SID.eq(SCHEDULE.ID))
         ))
       )
       .from(SCHEDULE)
       .where(SCHEDULE.ID.in(10, 11, 12))
       .fetchInto(Schedule.class);
    

    如果您在此查询中调用fetch(),您将获得一组具有所需结构的JSON 文档。如果您的类路径中有JacksonGson,jOOQ 的DefaultConverterProvider 可以使用这些库将JSON 文档映射到您自己的类。它们的映射规则适用。

    使用 XML 和 JAXB 也可以做到这一点。

    请注意,JSON_ARRAYAGG() 将空集聚合到 NULL,而不是空集 []If that's a problem, use COALESCE()

    注意

    未来的 jOOQ 版本可能会在不依赖第三方映射库的情况下提供此功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-17
      相关资源
      最近更新 更多