我正在使用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标准的基础。
它不适用于普通联接的原因是默认值为内部联接。