3 回答

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

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

TA贡献1891条经验 获得超3个赞
如果您将@oneToOne映射设置为FetchType.LAZY并使用第二个查询(因为需要将Department对象作为Employee对象的一部分加载)Hibernate会执行的操作,它将发出查询以获取每个单个Employee对象的Department对象它从数据库获取。在代码的后面,您可能会通过Employee到Department单值关联来访问Department对象,并且Hibernate将不会发出任何查询以获取给定Employee的Department对象。请记住,Hibernate仍然会发出等于已获取的Employees数量的查询。如果您希望访问所有Employee对象的Department对象,则Hibernate将在上述两个查询中发出相同数量的查询
添加回答
举报