gpt4 book ai didi

java - 获取所有属性是否会在幕后进行左连接?

转载 作者:行者123 更新时间:2023-11-30 07:34:24 27 4
gpt4 key购买 nike

我的实体如下所示:为了简化,我只显示两个字段。我们决定使用 fetch all 来一次性加载所有属性。

    @Entity     
public class Person{
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<PhoneNumber> phoneNumbers = new HashSet<>(0);
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "AGENCY_ID")
private Agency agency;

左连接:(这会返回重复的记录。)

select person
from Person person left join person.agency ag left join person.phoneNumbers
where upper(person.name) LIKE '%SU%' and upper(person.status.rcode) = 'ACTIVE'
order by person.agency.name asc, person.id asc

左连接与不同:这给出了“ORA-01791:不是选择的表达式”,因为我在订单子(monad)句中使用代理字段。

select distinct person
from Person person left join person.agency ag left join person.phoneNumbers
where upper(person.name) LIKE '%SU%' and upper(person.Status.rcode) = 'ACTIVE'
order by person.agency.name asc, person.id asc

左连接获取:这工作正常,没有重复。但由于打破了 2000 人记录,性能受到了巨大打击。与仅左连接的 1 相比,大约需要 15 秒。

select  person
from Person person left join fetch person.agency ag left join fetch person.phoneNumbers
where upper(person.name) LIKE '%SU%' and upper(person.Status.rcode) = 'ACTIVE'
order by person.agency.name asc, person.id asc

获取所有属性:无重复项。表现更好。但是..当我尝试查询如下所示的人(此人没有任何代理机构)时:它返回人员记录(这意味着它正在执行左连接)。

 select person
from Person person
fetch all properties
where upper(person.name) LIKE '%SU%' and upper(person.status) = 'ACTIVE'
order by person.id asc

但是当我执行以下操作时,我没有取回人员记录。 (区别在于order by子句中添加了agency字段,看来本例中没有做左连接。)

select person
from Person person
fetch all properties
where upper(person.name) LIKE '%SU%' and upper(person.status) = 'ACTIVE'
order by person.agency.name asc, person.id asc

我想要的是避免重复,可以按表现良好的人员的所有领域进行排序。

最佳答案

导航路径语法 (person.agency) 始终会转换为内部联接,这就是没有代理的人员不包含在结果集中的原因。

您必须显式编写外连接以避免隐式内连接:

select person
from Person person left outer join person.agency a
where upper(person.name) LIKE '%SU%' and upper(person.status) = 'ACTIVE'
order by a.name asc, person.id asc

编辑

distinctleft join 情况下不起作用,因为按 select 中提到的列中未包含的列进行排序是没有意义的不同的子句。

如果您想在查询中急切地加载惰性关联,那么您别无选择,只能执行left join fetch。但重复的也会被返回。要消除它们,只需将返回的列表添加到 LinkedHashSet 以保留返回的顺序:

List<Persons> result = new ArrayList(new LinkedHashSet(list))

对于这种方法的糟糕性能,Hibernate 与它无关。您可能在左连接获取的实体中有一些急切加载的实体(因此遭受 n+1 选择问题),或者重复的实体非常大(因此生成并传输很大的结果集)。

您可能想使用@BatchSize而不是左连接获取集合以避免性能问题。

关于java - 获取所有属性是否会在幕后进行左连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35613472/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com