猿问

Hibernate中JOIN和JOIN FETCH之间的区别

请帮助我了解在哪里使用常规JOIN和JOIN FETCH。


例如,如果我们有这两个查询


FROM Employee emp

JOIN emp.department dep


FROM Employee emp

JOIN FETCH emp.department dep

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


忽然笑
浏览 1276回答 3
3回答

人到中年有点甜

在这两个查询中,您正在使用JOIN查询与至少一个部门关联的所有员工。但是,不同之处在于:在第一个查询中,您仅返回休眠的Employes。在第二个查询中,您将返回员工和所有关联的部门。因此,如果您使用第二个查询,则无需执行新查询即可再次命中数据库以查看每个员工的部门。当您确定需要每个员工的部门时,可以使用第二个查询。如果不需要部门,请使用第一个查询。如果您需要应用一些WHERE条件(您可能需要),我建议您阅读此链接:如何正确地将JPQL“ join fetch”和“ where”子句表示为JPA 2 CriteriaQuery?更新资料如果您不使用fetch且继续返回部门,是因为您在雇员和部门(a @OneToMany)之间的映射设置为FetchType.EAGER。在这种情况下,任何带有fetch或不带有HQL的查询FROM Employee都会带到所有部门。请记住,默认情况下所有映射* ToOne(@ManyToOne和@OneToOne)均为EAGER。

HUH函数

在我之前在评论中提到的此链接中,请阅读此部分:“获取”联接允许使用单个选择将值的关联或集合及其父对象初始化。这在集合的情况下特别有用。它有效地覆盖了关联和集合的映射文件的外部联接和惰性声明。如果您在实体内部的集合中具有(fetch = FetchType.LAZY)属性(例如波纹管),则此“ JOIN FETCH”将起作用。它仅影响“何时应进行查询”的方法。而且您还必须知道这一点:休眠有两个正交的概念:何时获取关联以及如何获取关联。不要混淆它们,这一点很重要。我们使用访存来调整性能。我们可以使用lazy来定义一个契约,该契约规定在特定类的任何分离实例中哪些数据始终可用。何时获取关联->您的“ FETCH”类型如何获取->加入/选择/子选择/批处理在您的情况下,仅当您在Employee内部将部门设置为集合时,FETCH才会生效,在实体中是这样的:@OneToMany(fetch = FetchType.LAZY)private Set<Department> department;当你使用FROM Employee empJOIN FETCH emp.department dep你会得到emp和emp.dep。当您不使用fetch时,您仍然可以获取,emp.dep但是hibernate将处理另一个选择到数据库以获取该部门集合。因此,这只是性能调整的问题,您想要在单个查询中获取所有结果(是否需要)(渴望获取),或者您想在需要时稍后查询(懒惰获取)。当您需要通过一次选择(一次大查询)来获取小数据时,请使用渴望获取。或使用延迟获取来查询稍后需要的内容(许多较小的查询)。在以下情况下使用访存:您将要获得的实体内部没有大量不需要的集合/集从应用程序服务器到数据库服务器的通信距离太长,需要很长时间当您无法访问该集合时(在事务方法/类之外),可能需要后者

万千封印

如果您将@oneToOne映射设置为FetchType.LAZY并使用第二个查询(因为需要将Department对象作为Employee对象的一部分加载)Hibernate会执行的操作,它将发出查询以获取每个单个Employee对象的Department对象它从数据库获取。在代码的后面,您可能会通过Employee到Department单值关联来访问Department对象,并且Hibernate将不会发出任何查询以获取给定Employee的Department对象。请记住,Hibernate仍然会发出等于已获取的Employees数量的查询。如果您希望访问所有Employee对象的Department对象,则Hibernate将在上述两个查询中发出相同数量的查询
随时随地看视频慕课网APP

相关分类

Java
我要回答