3.1 映射依賴實體

在 SQL 中,您可以使用 JOIN 編寫查詢。可以在 HQL 中做同樣的事情嗎?簡短的回答是肯定的。但完整的答案會更有趣。

首先,當我們在 SQL 中編寫 JOIN 時,通常意味著一個表引用另一個表。例如,task 表包含一個 employee_id 列,該列引用 employee 表的 id 列。

這種依賴性可以在 Hibernate 中使用註解來描述。首先,讓我們為表創建實體。首先,讓我們描述一下員工表:

@Entity
@Table(name="employee")
class Employee {
   @Column(name="id")
   public Integer id;

   @Column(name="name")
   public String name;

   @Column(name="salary")
   public Integer salary;

   @Column(name="join_date")
   public Date joinDate;
}

任務的 EmployeeTask類:

@Entity
@Table(name="task")
class EmployeeTask {
   @Column(name="id")
   public Integer id;

   @Column(name="name")
   public String name;

   @Column(name="employee_id")
   public Integer employeeId;

   @Column(name="deadline")
   public Date deadline;
}

一切都很好,但有一個建議。我們來看最後一個例子中的employeeId字段:

@Column(name="employee_id")
public Integer employeeId;

你注意到什麼奇怪的事了嗎?如果沒有,那麼這意味著你已經形成了SQL語言的思維方式。

問題是,在 Java 語言中,我們通常對這種依賴關係的描述略有不同:

public Employee employee;

我們不需要指定id,我們通常只指定一個包含對Employee對象的引用的變量。如果沒有這樣的對象,則存儲null 。

而 Hibernate 允許我們使用註解來描述這樣的情況:

@ManyToOne
@JoinColumn(name="employee_id", nullable=true)
public Employee employee;

註釋@ManyToOne告訴 Hibernate 許多EmployeeTask實體可以引用一個Employee實體。

並且註釋指定了將從中獲取id@JoinColumn的列的名稱。所有其他必要的信息將從 Employee 類的註釋中獲取。

最終結果將如下所示:

@Entity
@Table(name="task")
class EmployeeTask
{
   @Column(name="id")
   public Integer id;

   @Column(name="name")
   public String name;

   @ManyToOne
   @JoinColumn(name="employee_id", nullable=true)
   public Employee employee;

   @Column(name="deadline")
   public Date deadline;
}

3.2 在HQL中使用join

現在讓我們看看如何在 HQL 中編寫對相關實體的查詢。

第一種情況。

我們有一個員工(Employee),我們想得到他的任務列表。下面是該查詢在 SQL 中的樣子:

SELECT task.* FROM task JOIN employee ON task.employee_id = employee.id
WHERE employee.name = "Ivan Ivanovich";

現在讓我們用 HQL 編寫相同的查詢:

from EmployeeTask where employee.name = "Ivan Ivanovich"

EmployeeTask類有一個employee字段,還有一個name字段,所以這個查詢會起作用。

情況二。

返回有逾期任務的員工列表。下面是該查詢在 SQL 中的樣子:

SELECT DISTINCT employee.*
FROM task JOIN employee ON task.employee_id = employee.id
WHERE task.deadline < CURDATE();

DISTINCT之所以使用,是因為可以將許多任務分配給一個用戶。

現在讓我們用 HQL 編寫相同的查詢:

select distinct employee from EmployeeTask where deadline < CURDATE();

此查詢中的員工是EmployeeTask類的一個字段

情況三。

將所有未分配的任務分配給主管。SQL 查詢將如下所示:

UPDATE task SET employee_id = 4 WHERE employee_id IS NULL

現在讓我們用 HQL 編寫相同的查詢:

update EmployeeTask set employee = :user where employee is null

最後一個查詢是最難的。我們需要傳遞 ID,director,但是 EmployeeTask 類不包含可以寫入 id 的字段,而是包含一個 Employee 字段,您需要在該字段中分配對 Employee 類型對象的引用。

在 Hibernate 中,這個問題是在傳遞給 Query 對象的查詢參數的幫助下解決的。而在 HQL 本身中,此類參數是通過冒號編寫的::user。但我們稍後會討論這個。