41. 객체지향 쿼리 언어(8)
41. 객체지향 쿼리 언어(8)
2. JPQL
11. 다형성 쿼리
JPQL로 부모 엔티티를 조회하면 그 자식 엔티티도 함께 조회한다. 아래 예제를 보면 Item의 자식으로 Book, Album, Movie가 있다.
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "DTYPE")
public abstract class Item {...}
@Entity
@DiscriminatorValue("B")
public class Book extends Item {
...
private String author;
}
// Album, Movie 생략
다음과 같이 조회하면 Item의 자식도 같이 조회한다.
List resultList = em.createQuery("select i from Item i").getResultList();
단일 테이블 전략(InheritanceType.SINGLE_TABLE)을 사용할 때 실행되는 SQL은 다음과 같다.
// SQL
SELECT * FROM ITEM
조인 전략(InheritanceType.JOINED)을 사용할 때 실행되는 SQL은 다음과 같다.
// SQL
SELECT
i.ITEM_ID, i.DTYPE, i.name, i.price, i.stockQuantity,
b.author, b.isbn,
a.artist, a.etc,
m.actor, m.director
FROM
Item i
left outer join
Book b on i.ITEM_ID=b.ITEM_ID
left outer join
Album a on i.ITEM_ID=a.ITEM_ID
left outer join
Movie m on i.ITEM_ID=m.ITEM_ID
TYPE
TYPE은 엔티티의 상속 구조에서 조회 대상을 특정 자식 타입으로 한정할 때 주로 사용한다.
예시) Item 중에 Book, Movie를 조회하라.
// JPQL
select i from Item i
where type(i) IN (Book, Movie)
// SQL
SELECT i FROM Item i
WHERE i.DTYPE in ('B', 'M')
TREAT(JPA 2.1)
TREAT는 JPA 2.1에 추가된 기능인데 자바의 타입 캐스팅과 비슷하다. 상속 구조에서 부모 타입을 특정 자식 타입으로 다룰 때 사용한다. JPA 표준은 FROM, WHERE 절에서 사용할 수 있지만 하이버네이트는 SELECT 절에서도 TREAT를 사용할 수 있다.
예시) 부모인 Item과 자식 Book이 있다.
// JPQL
select i from Item i where treat(i as Book).author = 'kim'
// SQL
select i.* from Item i
where
i.DTYPE='B'
and i.author='kim'
JPQL을 보면 treat를 사용해서 부모 타입인 Item을 자식 타입인 Book으로 다룬다. 따라서 author 필드에 접근할 수 있다.
12. 사용자 정의 함수 호출(JPA 2.1)
JPA 2.1부터 사용자 정의 함수를 지원한다.
문법 :
function_invocation::=FUNCTION(function_name {, function_args}*)
예시
select function('group_concat', i.name) from Item i
하이버네이트 구현체를 사용하면 아래 예제와 같이 방언 클래스를 상속해서 구현하고 사용할 데이터베이스 함수를 미리 등록해야 한다.
public class MyH2Dialect extends H2Dialect {
public MyH2Dialect() {
registerFunction("group_concat", new StandardSQLFunction
("group_concat", StandardBasicTypes.STRING));
}
}
그리고 아래 예제와 같이 hibernate.dialect에 해당 방언을 등록해야 한다.
- persistence.xml
<property name="hibernate.dialect" value="hello.MyH2Dialect" />
하이버네이트 구현체를 사용하면 다음과 같이 축약해서 사용할 수 있다.
select group_concat(i.name) from Item i
13. 기타 정리
- enum은 = 비교 연산만 지원한다.
- 임베디드 타입은 비교를 지원하지 않는다.
EMPTY STRING
JPA 표준은 ''을 길이 0인 Empty String으로 정했지만 데이터베이스에 따라 ''를 NULL로 사용하는 데이터베이스도 있으므로 확인하고 사용해야 한다.
NULL 정의
- 조건을 만족하는 데이터가 하나도 없으면 NULL이다.
- NULL은 알 수 없는 값(unknown value)이다. NULL과의 모든 수학적 계산 결과는 NULL이 된다.
- Null == Null은 알 수 없는 값이다.
- Null is Null은 참이다.
JPA 표준 명세는 NULL(U) 값과 TRUE(T), FALSE(F)과의 논리 계산을 다음과 같이 정의했다.
아래 표는 AND 연산을 정리했다.
AND | T | F | U |
T | T | F | U |
F | F | F | F |
U | U | F | U |
아래 표는 OR 연산을 정리했다.
OR | T | F | U |
T | T | T | T |
F | T | F | U |
U | T | U | U |
아래 표는 NOT 연산을 정리했다.
NOT | |
T | F |
F | T |
U | U |
참고
- 자바 ORM 표준 JPA 프로그래밍
Author And Source
이 문제에 관하여(41. 객체지향 쿼리 언어(8)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jsj3282/41.-객체지향-쿼리-언어8저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)