我有一些带有链接链的Spring实体和存储库:
Root-> Foo-> Bar-> Qux-> ...
类似这样的东西:
class Root {
private String rootData;
@OneToOne
private Foo foo;
}
class Foo {
private String fooData;
@OneToOne
private Bar bar;
}
class Bar {
private String barData;
@OneToOne
private Qux qux;
}
class Qux {
private String quxData;
@OneToOne
private GoesOn goesOn;
}
有数十万个Root对象,并且所有关联都是惰性的。
我需要创建一个报告,列出所有包含以下数据的Root对象:
如果我尝试填充在关联中导航的报表,则对于每个Root对象,数据库将有N个查询。
是否有一种方法可以通过使用联接的单个查询来检索所有数据,而无需将关联更改为渴望的?
答案 0 :(得分:0)
您可以使用实体图来指定应直接获取的属性(以ea的方式)
您用
注释您的实体之一@NamedEntityGraph(
name = "report-eg",
attributeNodes = {
@NamedAttributeNode("foo"),
@NamedAttributeNode(value = "bar", subgraph = "bar-eg"),
},
subgraphs = {
@NamedSubgraph(
name = "bar-eg",
attributeNodes = {
@NamedAttributeNode("qux")
}
)
}
)
然后在获取中使用它
EntityGraph entityGraph = entityManager.getEntityGraph("report-eg");
Map<String, Object> properties = new HashMap<>();
properties.put("javax.persistence.loadgraph", entityGraph);
Post post = entityManager.find(Foo.class, id, properties);
很显然,您可能必须根据需要调整一些该图,但是它为您提供了帮助。
或者,您可以使用Criteria API。它可以直接指定应该建立fetched
的关系(与join相反)
答案 1 :(得分:0)
您可以使用HQL或JOINS 从表1 t1,表2 t2中选择t1,t2,其中t1.x = t2.x
答案 2 :(得分:0)
@Antoniossss答案为我解决了。
经过更多测试后,基于此article,我设法使用了一个没有NamedEntityGraph的简单解决方案。我在RootRepository界面中使用以下命令创建了一个函数:
@EntityGraph(attributePaths = {"foo.bar.qux"})
List<Root> findAllEagerJoin(Specification<Root> spec);
在关联链末尾寻求属性会强制所有表联接。