我应该何时支持JOIN而不是单数属性中的属性访问?

时间:2011-11-18 13:18:23

标签: sql join jpa-2.0 jpql criteria-api

考虑以下实体:

@Entity
public class Employee {

    @Id
    @GeneratedValue
    private Long id;

    private String name;

    // Assume that Project has a 'name' property
    @OneToMany(mappedBy = "manager")
    private List<Project> projects;

    @OneToOne
    private Department department;

    // Assume that Computer has a 'model' property
    @ManyToOne
    private Computer computer;

    //...
}

我希望获得给定Project的所有Employee个名称。

为了做到这一点,我需要做一个JOIN,所以:

// JPQL query
SELECT p.name FROM Employee e JOIN e.projects p

// Criteria API equivalent (pseudo-code)
Root<Employee> emp = CriteriaQuery#from(Employee.class);
CriteriaQuery#select(emp.get(Employee_.projects).get(Project_.name));

这些查询很好。

但是,我不能这样做:

// JPQL query
SELECT e.projects.name FROM Employee e

// Criteria API equivalent (pseudo-code)
Root<Employee> emp = CriteriaQuery#from(Employee.class);
Join<Employee, Project> empProj = emp.join(Employee_.projects);
CriteriaQuery#select(empProj.get(Project_.name));

由于JPA 2.0规范禁止使用非奇异识别变量。

但是,对于单数属性,我可以使用JOIN访问它们或只是使用标识变量导航到它们,因此以下所有查询都有效并返回同样的结果:

SELECT e.computer.model FROM Employee e
SELECT c.model FROM Employee e JOIN e.computer c

// Criteria API equivalents of the above JPQL (pseudo-code)
Root<Employee> emp = CriteriaQuery#from(Employee.class);
Join<Employee, Computer> empComp = emp.join(Employee_.computer);
CriteriaQuery#select(empComp.get(Computer_.model));

Root<Employee> emp = CriteriaQuery#from(Employee.class);
CriteriaQuery#select(emp.get(Employee_.computer).get(Computer_.model));

我的问题是:
- 什么时候应该使用显式JOIN(在JPQL或Criteria API的join( - )方法中)? - 两种方法的优点/缺点是什么? - 被认为比其他人效率更高的人之一吗? - 如果只是风格问题 - 您更喜欢哪一个?为什么?

1 个答案:

答案 0 :(得分:2)

  1. 我只考虑属性的类型。 e.computer是一台计算机,因此我可以在其上调用getModel(),因此e.computer.model可以。 e.projects是一个列表,我无法在列表上调用getName(),因此e.projects.name不正常。每次需要访问集合的成员时,您都需要加入。

  2. 使用e.computer.id时,不需要SQL连接(至少不是Hibernate生成的),因为计算机的ID在employee表中,作为外键。因此,使用它比使用显式连接更有效。 e.computer.model生成SQL连接,这只是风格和偏好的问题。

  3. 见2.

  4. 我通常更喜欢显式连接,因为......它使它们显式化。如果需要,也可以更容易地将它们转换为左连接。