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
. 그러나 이것에 대해서는 나중에 이야기하겠습니다.
GO TO FULL VERSION