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
。但我們稍後會討論這個。
GO TO FULL VERSION