설명
이전 학습에서 Hibernate가 Entity 클래스의 이름을 저장하기 위해 특별한 DTYPE VARCHAR 열을 사용하는 것을 보았습니다. 이러한 열을 discriminator 라고 합니다 . 데이터베이스의 주어진 행에 대해 생성할 클래스를 명확하게 결정하는 데 사용됩니다.
@DiscriminatorColumn 주석을 사용하여 이 열을 조작할 수 있습니다 . 예:
@DiscriminatorColumn(name="column_name", discriminatorType = DiscriminatorType.INTEGER)
JPA 사양에 따르면 판별자는 다음 유형을 가질 수 있습니다.
- 끈
- 숯
- 정수
그러나 Hibernate를 사용하면 이 목록을 약간 확장할 수 있습니다. String, char, int, byte, short, boolean과 같은 Java 유형을 지원합니다.
INTEGER 유형을 사용하는 경우 Entity 클래스의 이름을 인코딩하는 방법은 무엇입니까? 이를 위해 @DiscriminatorValue 라는 다른 주석이 사용됩니다 .
예를 살펴보십시오.
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="user_type", discriminatorType = DiscriminatorType.INTEGER)
@Entity
class User {
int id;
String name;
LocalDate birthday;
}
@Entity
@DiscriminatorValue("1")
class Employee extends User {
String occupation;
int salary;
LocalDate join;
}
@Entity
@DiscriminatorValue("2")
class Client extends User {
String address;
}
위의 예에서 우리는 판별자가 숫자를 저장할 user_type 열을 사용할 것이라고 Hibernate에 알렸습니다. 값 1을 저장하면 행 유형이 Employee이고 2가 저장되면 행 유형이 Client임을 의미합니다. 간단하고 아름답습니다.
@DiscriminatorValue
하지만 그게 다가 아닙니다. 판별자가 NULL일 때 문자열의 유형을 해석하는 방법을 Hibernate에게 알릴 수 있습니다.
실제로 매우 간단합니다. @DiscriminatorValue 주석 에 대해 null 값을 지정합니다 . 예를 들면 다음과 같습니다.
@DiscriminatorValue("null")
수업 예시:
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="user_type", discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorValue("null")
@Entity
class User {
int id;
String name;
LocalDate birthday;
}
우리는 Hibernate에게 user_type 열에 NULL이 있는 모든 테이블 행은 User 유형의 객체로 해석되어야 한다고 말했습니다.
하지만 그게 다가 아닙니다. @DiscriminatorValue 주석에 대한 또 다른 흥미로운 값이 있습니다.
다음은 다음과 같습니다.
@DiscriminatorValue("not null")
수업 예시:
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="user_type", discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorValue("not null")
@Entity
class User {
int id;
String name;
LocalDate birthday;
}
이 주석으로 우리는 Hibernate에게 user_type 열에 NULL이 아닌 값을 가진 테이블 행은 User 유형의 객체로 해석되어야 한다고 말했습니다. 그러나 이는 필요한 번호가 명시적으로 지정된 클래스를 찾을 수 없는 경우에만 해당됩니다.
이것은 discriminators의 다른 값에 대해 작동하는 방식입니다.
- 0 - 사용자 유형의 객체 생성
- 1 - Employee 유형의 객체 생성
- 2 - 클라이언트 유형의 객체 생성
- 3 - 사용자 유형의 객체 생성
- 4 - 사용자 유형의 객체 생성
@DiscriminatorFormula
하지만 그게 다가 아닙니다. 판별자의 경우 @DiscriminatorValue 주석의 값을 계산하는 정수 공식을 지정할 수 있습니다 .
이를 위한 특별한 주석이 있는데 @DiscriminatorFormula 입니다 .
예:
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="user_type", discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorFormula("case when ‘join’ is not null then 1 else 2 end")
@Entity
class User {
int id;
String name;
LocalDate birthday;
}
@Entity
@DiscriminatorValue("1")
class Employee extends User {
String occupation;
int salary;
LocalDate join;
}
@Entity
@DiscriminatorValue("2")
class Client extends User {
String address;
}
@DiscriminatorFormula 에 의해 반환된 값은 Hibernate에 의해 @DiscriminatorValue 주석 에 지정된 값과 비교됩니다 . 이를 통해 매우 복잡한 시나리오를 작성할 수 있습니다.
@DiscriminatorFormula(
"case when address is not null " +
"then 'Client' " +
"else (" +
" case when occupation is not null " +
" then 'Employee' " +
" else 'Unknown' " +
" end) " +
"end "
)