2.1 테이블 수준에서 연결
우리는 Hibernate가 보조 테이블에 컬렉션을 저장하는 방법을 보았습니다. 이제 실제 Entity 클래스를 저장하는 본격적인 테이블 간의 관계를 구성하는 방법을 알아보겠습니다.
Hibernate의 Entity 클래스 사이에는 네 가지 유형의 관계가 있습니다.
- 일대일 _ _
- 일대 다 _
- 다 대일 _
- 다 대다 _
그리고 가장 간단한 옵션 인 다 대일 분석을 시작하겠습니다 .
SQL에서 테이블 간의 이러한 관계를 이미 접했습니다. 일반적으로 다음과 같이 표시됩니다.
ID | 이름 | 직업 | 샐러리 | 나이 | 가입 날짜 |
---|---|---|---|---|---|
1 | 이바노프 이반 | 프로그램 제작자 | 100000 | 25 | 2012-06-30 |
2 | 페트로프 페트르 | 프로그램 제작자 | 80000 | 23 | 2013-08-12 |
삼 | 이바노프 세르게이 | 시험 장치 | 40000 | 서른 | 2014-01-01 |
4 | 라비노비치 모이샤 | 감독 | 200000 | 35 | 2015-05-12 |
5 | 키리엔코 아나스타샤 | 사무실 관리자 | 40000 | 25 | 2015년 10월 10일 |
6 | 바스카 | 고양이 | 1000 | 삼 | 2018-11-11 |
직원 테이블:
이 테이블에는 다음 열이 있습니다.
- ID INT
- 이름 VARCHAR
- 직업 VARCHAR
- 급여 INT
- 나이 INT
- 가입 날짜 날짜
직원의 작업이 포함된 작업 테이블은 다음과 같습니다 .
ID | employee_id | 이름 | 마감 시간 |
---|---|---|---|
1 | 1 | 프런트엔드의 버그 수정 | 2022-06-01 |
2 | 2 | 백엔드의 버그 수정 | 2022-06-15 |
삼 | 5 | 커피를 사다 | 2022-07-01 |
4 | 5 | 커피를 사다 | 2022-08-01 |
5 | 5 | 커피를 사다 | 2022-09-01 |
6 | (없는) | 사무실을 청소하다 | (없는) |
7 | 4 | 즐거운 삶 | (없는) |
8 | 6 | 즐거운 삶 | (없는) |
이 테이블에는 4개의 열만 있습니다.
- id – 고유한 작업 번호(및 테이블의 행)
- employee_id – 작업이 할당된 직원 테이블의 직원 ID입니다.
- 이름 - 작업의 이름과 설명
- 기한 - 작업을 완료해야 하는 시간입니다.
작업 테이블의 많은 행이 직원 테이블의 단일 항목을 참조할 수 있음을 알 수 있습니다. 이러한 테이블 수준 관계를 다대일 이라고 합니다 .
2.2 Java 클래스 레벨과의 관계
테이블 수준에서의 통신 외에도 Hibernate의 Entity 클래스 수준에서 통신을 구성할 수도 있습니다. 이것은 주석으로 수행됩니다 @ManyToOne
.
그러나 먼저 Employee 및 EmployeeTask 라는 두 개의 클래스를 생성해 보겠습니다 .
@Entity
@Table(name="employee")
class Employee {
@Column(name="id")
public Integer id;
@Column(name="name")
public String name;
@Column(name="occupation")
public String occupation;
@Column(name="salary")
public Integer salary;
@Column(name="join_date")
public Date join;
}
직원 작업을 저장하는 두 번째 클래스:
@Entity
@Table(name="task")
class EmployeeTask {
@Column(name="id")
public Integer id;
@Column(name="name")
public String description;
@Column(name="employee_id")
public Integer employeeId;
@Column(name="deadline")
public Date deadline;
}
이러한 클래스는 모두 문제가 없지만 EmployeeTask 클래스의 employeeId 필드가 Employee 클래스의 id 필드를 참조한다는 사실을 반영하는 관계가 없습니다. 고칠 시간이야
2.3 @ManyToOne 주석.
첫째, Java에서 우리는 객체(및 객체 참조)에 대한 작업에 익숙합니다. 먼저 EmployeeTask 클래스의 employeeId 필드 대신 Employee 유형의 개체를 가리키도록 하겠습니다. 새 클래스는 다음과 같습니다.
@Entity
@Table(name="task")
class EmployeeTask {
@Column(name="id")
public Integer id;
@Column(name="name")
public String description;
@ManyToOne
@JoinColumn(name = "employee_id")
public Employee employee;
@Column(name="deadline")
public Date deadline;
}
주석 의 도움으로 @ManyToOne
많은 EmployeeTask 개체가 Employee 유형의 개체 하나를 참조할 수 있음을 나타냅니다. 또한 주석을 @JoinColumn
사용하여 직원 개체의 ID가 저장된 테이블의 열을 표시했습니다.
2.4 요청 예시
이제 Hibernate가 그러한 관련 클래스와 함께 작동할 수 있는 방법에 대한 몇 가지 예를 보여드리겠습니다.
시나리오 1
특정 사용자에게 할당된 모든 작업을 찾는 쿼리를 작성해 보겠습니다. 다음은 이 쿼리가 HQL에서 어떻게 보이는지 보여줍니다.
from EmployeeTask where employee.name = "Ivan Ivanovich"
단순히 점을 통해 종속 클래스의 필드를 참조할 수 있습니다. 매우 편안합니다. 하지만 여전히 이 쿼리를 Java 코드 형식으로 작성해 보겠습니다.
String hql = "from EmployeeTask where employee.name = :username";
Query<EmployeeTask> query = session.createQuery( hql, EmployeeTask.class);
query.setParameter("username", "Ivan Ivanovich");
List<EmployeeTask> resultLIst = query.list();
시나리오 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
마지막 쿼리가 가장 어려운 쿼리입니다. director의 ID를 전달해야 하지만 EmployeeTask 클래스에는 ID를 작성할 수 있는 필드가 포함되어 있지 않고 Employee 유형의 개체에 대한 참조를 할당해야 하는 Employee 필드가 포함되어 있습니다.
Employee director = session.get(Employee.class, 4);
String hql = "update EmployeeTask set employee = :user where employee is null";
Query<EmployeeTask> query = session.createQuery(hql, EmployeeTask.class);
query.setParameter("user", director);
query.executeUpdate();