2011-11-18 45 views
2

考慮下面的實體:我應該何時偏愛JOIN而不是單數屬性的屬性訪問?

@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; 

    //... 
} 

我想給定Employee所有Project名。

爲了做到這一點,我需要做一個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規範禁止使用非奇異標識變量。

然而,奇異的屬性,我可以用要麼加入,或者乾脆利用標識變量導航到他們訪問它們,所以下面所有的查詢都是有效和返回相同的結果:

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( - )方法中)?
- 這兩種方法的優點和缺點是什麼?
- 是其中一個被認爲比另一個更有效嗎?
- 如果它只是一個風格問題 - 你更喜歡哪一個?爲什麼?

回答

2
  1. 我只想到屬性的類型。 e.computer是一臺計算機,因此我可以在它上面調用getModel(),所以e.computer.model就可以。 e.projects是一個列表,我不能在列表上調用getName(),所以e.projects.name不正確。每次需要訪問集合的成員時,都需要加入。

  2. 使用e.computer.id時,由於計算機的ID在僱員表中作爲外鍵,因此SQL連接不是必需的(至少不是由Hibernate生成的)。因此使用它比使用顯式連接更有效。 e.computer.model生成SQL連接,這只是樣式和首選項的問題。

  3. 請參閱第2

  4. 我通常喜歡明確連接,因爲...這讓他們明確。如果需要,將它們轉換爲左連接也更容易。

+0

謝謝JB。我只是觀察到,沒有做JOIN顯式生成的SQL如下所示:'...從tbl1交叉連接tbl2交叉連接tbl3 WHERE ...'而顯式連接它是:'...從tbl1,tbl2,tbl3哪裏。 ..「這看起來和我很相像。不知道這只是一個巧合,或者它在某些情況下有所作爲。 –

+0

我不認爲這有什麼區別。用你自己的數據庫來衡量它是確定的。 –