jooq单一查询与一对多关系

时间:2015-11-21 15:37:52

标签: java mysql sql jooq

我有一个表格实验和一个表格标签。一个实验可能有许多标签。 架构:

--------                  --------
|Table1|  1           n   |Table2|
|      | <--------------> |      |
|      |                  |      |
--------                  --------
(experiment)              (tags)

是否可以使用jooq创建查询,返回实验和相应的标签列表。 类似于结果,其中记录是一个experimentRecord和一个标签或地图列表。

我还有一个只返回一个结果的查询,那里有什么方便吗?

编辑:java8,最新的jooq。

2 个答案:

答案 0 :(得分:5)

有许多方法可以使用SQL和/或使用jOOQ来实现嵌套集合。我只是经历了其中一些:

使用联接

如果你没有深度嵌套这些集合,用JOIN对结果进行非规范化(展平)可能会为你做到这一点,而不会在复制数据时增加太多开销。基本上,你会写:

Map<ExperimentRecord, Result<Record>> map =
DSL.using(configuration)
   .select()
   .from(EXPERIMENT)
   .join(TAGS)
   .on(...)
   .fetchGroups(EXPERIMENT);

上面的地图包含实验记录作为键,以及包含所有标记作为值的嵌套集合。

创建两个查询

如果要实现复杂对象图,则使用连接可能不再是最佳选择。相反,您可能希望从两个不同的查询中收集客户端中的数据:

Result<ExperimentRecord> experiments = 
DSL.using(configuration)
   .selectFrom(EXPERIMENT)
   .fetch();

Result<TagsRecord> tags =
DSL.using(configuration)
   .selectFrom(TAGS)
   .where(... restrict to the previous experiments ...)
   .fetch();

现在,将两个结果合并到客户端的内存中,例如

experiments.stream()
           .map(e -> new ExperimentWithTags(
                e, 
                tags.stream()
                    .filter(t -> e.getId().equals(t.getExperimentId()))
                    .collect(Collectors.toList())
           ));

答案 1 :(得分:0)

现在,您可以使用SimpleFlatMapper将结果映射到Tuple2&gt;。你需要做的就是。

1 - 创建一个映射器,指定键列,假设它是id     JdbcMapper mapper =         JdbcMapperFactory          .newInstance()          .addKeys(EXPERIMENT.ID.getName())          .newMapper(new TypeReference&gt;&gt;(){});

2 - 在查询的ResultSet上使用映射器

dependsOn

有关详细信息,请参阅here