使用JPA和Hibernate时JOIN和JOIN FETCH有什么区别

新手上路,请多包涵

请帮助我了解在何处使用常规 JOIN 以及在何处使用 JOIN FETCH。例如,如果我们有这两个查询

FROM Employee emp
JOIN emp.department dep

FROM Employee emp
JOIN FETCH emp.department dep

它们之间有什么区别吗?如果是,什么时候使用哪一个?

原文由 abbas 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.4k
2 个回答

在这两个查询中,您使用 JOIN 来查询至少关联了一个部门的所有员工。

但是,区别在于:在第一个查询中,您只返回 Hibernate 的 Employes。在第二个查询中,您将返回雇员 所有关联的部门。

因此,如果您使用第二个查询,您将不需要执行新的查询来再次访问数据库来查看每个员工的部门。

当您确定需要每个员工的部门时,您可以使用第二个查询。如果不需要部门,请使用第一个查询。

如果您需要应用某些 WHERE 条件(您可能需要),我建议阅读此链接: How to properly express JPQL “join fetch” with “where” clause as JPA 2 CriteriaQuery?

更新

如果您不使用 fetch 并且 Departments 继续返回,是因为您在 Employee 和 Department 之间的映射(a @OneToMany )设置为 FetchType.EAGER 在这种情况下,任何 HQL(带 fetch 或不带)查询 FROM Employee 将带来所有部门。请记住,所有映射 *ToOne( @ManyToOne@OneToOne )默认情况下都是 EAGER。

原文由 Dherik 发布,翻译遵循 CC BY-SA 3.0 许可协议

在我之前在评论中提到的 这个链接 中,阅读这一部分:

“获取”联接允许关联或值集合与其父对象一起使用单个选择进行初始化。这在集合的情况下特别有用。 它有效地覆盖了关联和集合映射文件的外连接和惰性声明

如果实体内部的集合具有 (fetch = FetchType.LAZY) 属性(示例如下),此“JOIN FETCH”将生效。

而且它只影响“查询何时发生”的方法。你还必须知道 这一点

hibernate 有两个正交的概念:何时获取关联以及如何获取关联。重要的是不要混淆它们。我们使用 fetch 来调整性能。我们可以使用 lazy 来定义在特定类的任何分离实例中始终可用的数据的契约。

什么时候获取关联 –> 您的“FETCH”类型

它是如何获取的 –> Join/select/Subselect/Batch

在您的情况下,FETCH 只有在您将部门作为 Employee 内部的集合时才会生效,实体中的内容如下所示:

 @OneToMany(fetch = FetchType.LAZY)
private Set<Department> department;

当你使用

FROM Employee emp
JOIN FETCH emp.department dep

你会得到 empemp.dep 。当您不使用 fetch 时,您仍然可以获得 emp.dep 但是 hibernate 将处理另一个对数据库的选择以获取那组部门。

所以这只是性能调整的问题,关于你想在单个查询(急切获取)中获得所有结果(你是否需要它),或者你想在需要它时查询它(延迟获取)。

当您需要通过一次选择(一个大查询)获取小数据时,请使用急切获取。或者使用延迟获取来查询你需要的东西(许多更小的查询)。

在以下情况下使用 fetch:

  • 您将要获得的实体中没有大量 不需要 的集合/集合

  • 从应用服务器到 数据库服务器的通信太远,需要很长时间

  • 当您无法访问它时( 事务 方法/类之外),您可能稍后需要该集合

原文由 Angga 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题