3.1 종속 엔터티 매핑

SQL에서는 JOIN을 사용하여 쿼리를 작성할 수 있습니다. HQL에서도 동일한 작업을 수행할 수 있습니까? 짧은 대답은 '예'입니다. 그러나 전체 답변이 더 흥미로울 것입니다.

첫째, SQL에서 JOIN을 작성할 때 대부분 한 테이블이 다른 테이블을 참조한다는 의미입니다. 예를 들어 작업 테이블에는 직원 테이블의 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많은 EmployeeTask 엔터티가 하나의 Employee 엔터티를 참조할 수 있음을 Hibernate에 알려줍니다 .

그리고 주석은 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에서 조인 사용

이제 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 클래스 에는 직원 필드 와 이름 필드가 있으므로 이 쿼리가 작동합니다.

상황 2.

기한이 지난 직원 목록을 반환합니다. 해당 쿼리는 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 클래스 의 필드입니다.

상황 3.

할당되지 않은 모든 작업을 감독에게 할당합니다. 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. 그러나 이것에 대해서는 나중에 이야기하겠습니다.