使用 JPA 和 Hibernate 时,JOIN 和 JOIN FETCH 有什么区别
请帮助我了解在何处使用常规 JOIN 以及 JOIN FETCH 的位置。例如,如果我们有这两个查询
FROM Employee emp
JOIN emp.department dep
和
FROM Employee emp
JOIN FETCH emp.department dep
它们之间有什么区别吗?如果是,什么时候使用哪一个?
请帮助我了解在何处使用常规 JOIN 以及 JOIN FETCH 的位置。例如,如果我们有这两个查询
FROM Employee emp
JOIN emp.department dep
和
FROM Employee emp
JOIN FETCH emp.department dep
它们之间有什么区别吗?如果是,什么时候使用哪一个?
在这两个查询中,您将使用 JOIN 查询至少关联了一个部门的所有员工。
但是,不同之处在于:在第一个查询中,您只返回休眠的 Employes。在第二个查询中,您将返回“雇员”和所有关联的部门。
因此,如果使用第二个查询,则无需执行新查询即可再次点击数据库以查看每个员工的部门。
当您确定需要每个员工的部门时,可以使用第二个查询。如果不需要部门,请使用第一个查询。
如果您需要应用一些 WHERE 条件(您可能需要什么),我建议您阅读此链接:如何将 JPQL “join fetch” 与 “where” 子句正确表示为 JPA 2 CriteriaQuery?
更新
如果不使用并且继续返回部门,则是因为员工和部门 (a) 之间的映射设置为 。在这种情况下,任何 HQL(带或不带)查询都将带来所有部门。请记住,默认情况下,所有映射 *ToOne ( 和 ) 都是 EAGER 的。fetch
@OneToMany
FetchType.EAGER
fetch
FROM Employee
@ManyToOne
@OneToOne
在我之前提到的这个链接上的评论,阅读这部分:
“fetch”联接允许使用单个选择来初始化值的关联或集合及其父对象。这在集合的情况下特别有用。它有效地覆盖了关联和集合的映射文件的外部联接和惰性声明。
这个“JOIN FETCH”将具有(fetch = FetchType.LAZY)属性用于实体内部的集合(示例波纹管)将具有效果。
它只影响“何时应该发生查询”的方法。您还必须知道这一点:
冬眠有两个正交的概念:什么时候获取关联以及如何获取。重要的是不要混淆它们。我们使用抓取来调整性能。我们可以使用 lazy 来定义一个协定,说明哪些数据在特定类的任何分离实例中始终可用。
何时获取关联 -->“FETCH”类型
它是如何获取的 --> 加入/选择/部分选择/批处理
在你的例子中,FETCH只有在员工内部将部门作为集合时才有效,在实体中如下所示:
@OneToMany(fetch = FetchType.LAZY)
private Set<Department> department;
当您使用时
FROM Employee emp
JOIN FETCH emp.department dep
你会得到和.当你没有使用fetch时,你仍然可以得到,但休眠将处理另一个选择到数据库,以获得那组部门。emp
emp.dep
emp.dep
所以它只是一个性能调优的问题,关于你想在单个查询中获取所有结果(你是否需要它)(eager fetching),或者你想在你需要的时候查询它(懒惰获取)。
当您需要通过一个选择(一个大查询)获取小数据时,请使用 eager fetch。或者使用惰性抓取来查询后期(许多较小的查询)需要什么。
在以下情况下使用抓取:
您即将获得的实体内没有大型不需要的集合/集合
从应用程序服务器到数据库服务器的通信太远,需要很长时间
当您无法访问该集合时,您可能需要该集合(在事务方法/类之外)