我有一个桌子实验和一个桌子标签。一个实验可能有许多标签。架构:
-------- --------
|Table1| 1 n |Table2|
| | <--------------> | |
| | | |
-------- --------
(experiment) (tags)
是否可以使用返回实验和相应标签列表的jooq创建查询?
类似Result之类的东西
我也有一个只返回一个结果的查询,有什么方便的吗?
编辑:java8,最新的jooq。
您现在可以使用SimpleFlatMapper将结果映射到Tuple2
1-创建映射器,指定键列,假设它是id
JdbcMapper mapper =
JdbcMapperFactory
.newInstance()
.addKeys(EXPERIMENT.ID.getName())
.newMapper(new TypeReference<Tuple2<ExperimentRecord, List<TagRecord>>>() {});
2-在查询的结果集上使用映射器
try (ResultSet rs = DSL.using(configuration)
.select()
.from(EXPERIMENT)
.join(TAGS)
.on(...)
.fetchResultSet()) {
Stream<Tuple2<ExperimentRecord, List<TagRecord>>> stream = mapper.stream(rs);
....
}
请参阅此处了解更多详细信息
有许多方法可以使用SQL和/或jOOQ实现嵌套集合。我只是讲了其中的一些:
如果您没有深度嵌套这些集合,那么使用连接对结果进行非规范化(展平)可能会帮到您,而不会在复制数据时增加太多开销。基本上,你会写:
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())
));
这个问题不需要它,但是其他人可能会在寻找与jOOQ嵌套多关系的方法时找到这个问题。我在这里提供了一个答案。从jOOQ 3.14开始,您可以使用RDBMS的SQL /XML或SQL /JSON功能,然后使用Jackson、Gson或JAXB嵌套集合,如下所示:
List<Experiment> experiments =
ctx.select(
EXPERIMENT.asterisk(),
field(
select(jsonArrayAgg(jsonObject(TAGS.fields())))
.from(TAGS)
.where(TAGS.EXPERIMENT_ID.eq(EXPERIMENT.ID))
).as("tags")
)
.from(EXPERIMENT)
.fetchInto(Experiment.class);
其中,实验是这样一个自定义Java类:
class Experiment {
long id;
String name;
List<Tag> tags;
}
class Tag {
long id;
String name;
}
甚至比上述更好的是,您可以使用SQL/XML或SQL/JSON隐藏在jOOQ 3.15新的MULTISET运算符支持后面。假设上述Java类是Java 16记录(或任何其他不可变类),您甚至可以将嵌套集合类型安全地映射到DTO中:
List<Experiment> experiments =
ctx.select(
EXPERIMENT.ID,
EXPERIMENT.NAME,
multiset(
select(TAGS.ID, TAGS.NAME)
.from(TAGS)
.where(TAGS.EXPERIMENT_ID.eq(EXPERIMENT.ID))
).as("tags").convertFrom(r -> r.map(Records.mapping(Tag::new)))
)
.from(EXPERIMENT)
.fetch(Records.mapping(Experiment::new));
其中,实验是这样一个自定义Java类:
record Experiment(long id, String name, List<Tag> tags) {}
record Tag(long id, String name) {}
有关更多信息,请参阅此博客文章。
我正在努力理解如何处理与JOOQ的一对多和多对多关系的Pojo。 我存储玩家创建的位置(一对多关系)。一个位置可以容纳多个可能访问它的其他玩家(多对多)。数据库布局可归结为以下内容: 在我的java应用程序中,所有这些信息都存储在一个pojo中。请注意,玩家和受邀玩家列表可以从应用程序中更新,也需要在数据库中更新: 我可以使用JOOQ的pojo映射将这三个记录映射到单个pojo吗?我可以使用这个p
问题内容: 有三个表:,并且,医院能提供的医疗服务和语言服务。因此,存在两个多对多关系。 简单ERD 现在,我想使用和搜索医院数据。 DaoImpl: 而且,如果我想从三个表中按邮政编码,医疗类型和语言进行搜索,那么如何编写一个jsql。 警告: 错误:org.hibernate.hql.internal.ast.ErrorCounter- 预期加入的路径!希望加入的路径!在org.hiberna
我是新来laravel的,所以原谅我可能的愚蠢问题。此外,我确实研究了所有其他“类似”的问题,但要么它们没有重现正确的解决方案,要么我真的很难理解。 情景: 我有一个帖子模型和一个主题模型。这就是他们现在的样子。 在岗位上。php 在主题上。php 现在,我需要实现的是: 如果将查询参数传递给请求(即q=Food),我只想返回在主题关系中包含主题食物的帖子,而不返回其他帖子。如果什么都没有通过,那
实现了一对多的关系,它运行良好。 我的问题是当我运行下面的查询时,如果表有100个员工行,每个员工有两个部门。数据库查询被调用了101次,因为对每个员工都是调用部门查询,要完成调用全部100行需要很长时间,有没有人可以提出替代的解决方案? 输出XML:
问题内容: 我在Hibernate中具有以下一对一关系(可能为null): 我正在尝试使用HQL选择所有具有非空详细信息的实体: 但这会返回所有实体,无论详细信息是否为空。 那么正确的HQL是什么? 问题答案: 好的,我找到了解决方案:
问题内容: 因此,我有以下实体: 因此,没有对的引用,这意味着我们具有单向一对多关系。我需要寻找一个by 和。也就是说,找到具有指定posId的供应商,然后在供应商的pos列表中找到一个pos。如何为此编写条件查询? 我尝试使用子查询。我的想法是创建一个子查询,该子查询将获取具有给定条件的a的所有内容。然后,主查询将那些中搜索的一个给定。 问题是我无法编写查询来获取s的s列表。显然,您不能编写以下