使用Spring和Hibernate从多个表联接中检索数据

时间:2019-06-28 19:11:46

标签: java spring hibernate spring-data-jpa

我有一些带有链接链的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对象:

  • rootData
  • fooData
  • barData
  • quxData

如果我尝试填充在关联中导航的报表,则对于每个Root对象,数据库将有N个查询。

是否有一种方法可以通过使用联接的单个查询来检索所有数据,而无需将关联更改为渴望的?

3 个答案:

答案 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);

在关联链末尾寻求属性会强制所有表联接。