我正在使用Hibernate的JPA实现,并且由于为每个获取的实体发出多个SQL查询,因此看到的性能很差。如果我使用联接的JPA查询,它将仅生成一个SQL查询,但找不到行将导致关系为空。

例如,考虑这个简单的模式。一个人住在一个​​地址并被公司雇用。地址和雇主都是可选的,因此可以为空。

@Entity
public  class Person {
    public name;

    @ManyToOne
    @Column(nullable=true)
    public Address address

    @ManyToOne
    @Column(nullable=true)
    public Company employer
}

@Entity
public  class Address {
    address attributes ...
}

@Entity
public  class Company {
    company attributes ...
}

上面没有显示的是,每个JPA实体都有某种ID(密钥):
@Id
public Integer id;

我看到的问题是,对Person的单个JPA查询导致对数据库的多个SQL查询。例如,以下JPA查询:
select p from Person p where ...

结果在SQL查询中:
select ... from Person where ...

以及以下每个对检索到的人的的SQL查询:
select ... from Address a where a.id=xxx
select ... from Company c where c.id=yyy

这对性能有巨大影响。如果查询结果集是1000个人,则它将生成1 + 1000 + 1000 = 2001 SQL查询。

因此,我尝试通过强制其加入来优化JPA查询:
select p from Person p join p.address a join p.employer e where ...

要么:
select p, a, e from Person p join p.address a join p.employer e where ...

这将导致一个带有多个联接的单个SQL查询。问题是,如果地址或雇主为空,则联接的查询将找不到它。

因此,我要么使用缓慢的无连接查询,要么不检索行的快速连接查询将使关系为空。我一定在这里想念什么。当然,有一种方法可以进行快速而完整的查询。

最佳答案

我的猜测是您需要左联接,即

SELECT p FROM Person p LEFT JOIN p.address a LEFT JOIN p.employer e WHERE...

参见this blog entry for an example

请注意,我实际上并未使用JPA尝试过此操作,但它在HQL中可以正常工作,这在许多方面都是JPA标准的基础。

它不适用于普通联接的原因是默认值为内部联接。

10-08 08:48
查看更多