3.1 Ánh xạ các thực thể phụ thuộc

Trong SQL, bạn có thể viết truy vấn bằng cách sử dụng THAM GIA. Có thể làm điều tương tự trong HQL không? Câu trả lời ngắn gọn là có. Nhưng câu trả lời đầy đủ sẽ thú vị hơn.

Đầu tiên, khi chúng ta viết THAM GIA trong SQL, điều đó thường có nghĩa là một bảng tham chiếu đến một bảng khác. Ví dụ: bảng nhiệm vụ chứa cột employee_id tham chiếu đến cột id của bảng nhân viên.

Sự phụ thuộc này có thể được mô tả bằng cách sử dụng các chú thích trong Hibernate. Trước tiên, hãy tạo Thực thể cho các bảng của chúng ta. Đầu tiên, hãy mô tả bảng nhân viên:

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

Và lớp EmployeeTask cho bảng nhiệm vụ :

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

Mọi thứ đều ổn, nhưng có một gợi ý. Hãy xem trường employeeId trong ví dụ trước:

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

Bạn có nhận thấy điều gì lạ không? Nếu không, thì điều này có nghĩa là bạn đã hình thành cách suy nghĩ bằng ngôn ngữ SQL.

Vấn đề là trong ngôn ngữ Java, chúng ta thường mô tả sự phụ thuộc như vậy hơi khác một chút:

public Employee employee;

Chúng tôi không cần chỉ định id , chúng tôi thường chỉ định một biến chứa tham chiếu đến đối tượng Nhân viên . Hoặc lưu trữ null nếu không có đối tượng như vậy.

Và Hibernate cho phép chúng tôi mô tả tình huống như vậy bằng cách sử dụng các chú thích:

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

Chú thích @ManyToOnecho Hibernate biết rằng nhiều thực thể EmployeeTask có thể tham chiếu đến một thực thể Employee .

Và chú thích @JoinColumnchỉ định tên của cột mà từ đó id sẽ được lấy . Tất cả các thông tin cần thiết khác sẽ được lấy từ các chú thích của lớp Nhân viên.

Kết quả cuối cùng sẽ như thế này:

@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 Sử dụng tham gia trong HQL

Và bây giờ hãy xem cách viết truy vấn cho các thực thể liên quan trong HQL.

Tình huống đầu tiên.

Chúng tôi có một nhân viên (Employee) và chúng tôi muốn lấy danh sách các nhiệm vụ của anh ấy. Đây là giao diện của truy vấn đó trong SQL:

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

Và bây giờ hãy viết truy vấn tương tự trong HQL:

from EmployeeTask where employee.name = "Ivan Ivanovich"

Lớp EmployeeTask có trường nhân viên và có trường tên nên truy vấn này sẽ hoạt động.

Tình huống hai.

Trả về danh sách nhân viên có nhiệm vụ quá hạn. Đây là giao diện của truy vấn đó trong SQL:

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

DISTINCTđược sử dụng vì có thể có nhiều nhiệm vụ được giao cho một người dùng.

Và bây giờ hãy viết truy vấn tương tự trong HQL:

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

nhân viên trong truy vấn này là một trường của lớp EmployeeTask

Tình huống ba.

Giao tất cả các nhiệm vụ chưa được giao cho giám đốc. Truy vấn SQL sẽ trông như thế này:

UPDATE task SET employee_id = 4 WHERE employee_id IS NULL

Và bây giờ hãy viết truy vấn tương tự trong HQL:

update EmployeeTask set employee = :user where employee is null

Truy vấn cuối cùng là truy vấn khó nhất. Chúng ta cần chuyển ID, giám đốc, nhưng lớp EmployeeTask không chứa trường để bạn có thể viết id, thay vào đó nó chứa trường Nhân viên nơi bạn cần gán tham chiếu đến đối tượng kiểu Nhân viên.

Trong Hibernate, vấn đề này được giải quyết với sự trợ giúp của các tham số truy vấn được truyền cho đối tượng Truy vấn. Và trong chính HQL, các tham số như vậy được viết thông qua dấu hai chấm: :user. Nhưng chúng ta sẽ nói về điều này một chút sau.