0. 개요
- 이번 포스팅에서는 유용한 JPA의 기능 몇 가지를 알아보도록 하자.
1. 다형성 쿼리
a) 다형성 쿼리란?
- 다형성 쿼리는 상속 관계에서 사용할 수 있는 기능이다.
- 부모 객체를 통해 특정 자식 객체를 조회할 때 사용하는 기능이다.
b) 다형성 쿼리 사용 방법
- 예를 들어, Food라는 부모 객체가 있고 하위에 Beverage, Snack이 있다고 해보자.
- Food 객체를 통해 Snack 객체를 조회하고 싶은 경우, 다음과 같은 JPQL을 작성할 수 있다.
SELECT f FROM Food f WHERE TYPE(f) IN(Snack);
- 위의 JPQL은 다음과 같은 SQL로 번역되어 DB에게 전달된다.
SELECT f FROM Food f WHERE f.DTYPE IN ('Snack');
c) TREAT()
- 다형성 쿼리와 연계되는 개념으로, 타입 다운 캐스팅 기능이다.
- 상속 관계에서 부모 객체를 특정 자식 객체의 타입으로 캐스팅할 때 사용한다.
- FROM, WHERE, SELECT 절에서 사용할 수 있다.
d) TREAT 사용 방법
- 예를 들어, Food라는 부모 객체가 있고 하위에 Beverage, Snack이 있다고 해보자.
- Snack 하위 객체의 이름이 '칙촉'과 일치하는 상위 객체 Food를 조회하려고 한다.
- 다음과 같이 JPQL을 작성할 수 있다.
SELECT f FROM Food f
WHERE TREAT(f as Snack).NAME = '칙촉';
- 위에서 작성한 JPQL은 다음과 같은 SQL로 번역되어 DB에게 전달된다.
SELECT f.* FROM Food f
WHERE f.DTYPE = 'Snack' AND f.NAME = '칙촉';
2. Entity 직접 사용
- 지금까지 JPQL을 작성할 때, 다음과 같이 Entity를 직접 명시하여 사용하였다.
SELECT COUNT(p) FROM Player p;
- 그렇다면 매개변수로 사용된 p는 어떤 값이 들어가는 것일까?
- 위의 JPQL은 다음과 같은 SQL로 번역되어 DB에게 전달된다.
SELECT COUNT(p.ID) FROM Player p;
- 다른 예시를 하나 더 살펴보자.
String query = "SELECT p FROM Player p WHERE p =: player";
List<Player> resultList = em.createQuery(query)
.setParameter("player", player);
.getResultList();
- 위에서 작성된 JPQL은 다음과 같은 SQL로 번역된다.
SELECT p.* FROM Player p WHERE p.ID = ?;
- 이처럼 JPQL에서 Entity를 직접 명시하면 해당 Entity의 기본 키(= Primary key)가 전달된다.
3. Named 쿼리
a) Named 쿼리란?
- Named 쿼리란, 미리 정의하여 메서드처럼 재사용이 가능한 정적 JPQL이다.
- Named 쿼리는 Annotation을 이용하여 정의할 수 있다.
- 또는 XML에 정의하여 global 레벨로 사용할 수도 있다.
b) Named 쿼리의 장점
- Named 쿼리는 Application 로딩 시점에서 쿼리가 검증된다는 장점이 있다.
- 또한 Application 로딩 시점에서 초기화되어 재사용이 가능하다는 장점이 있다.
c) Named 쿼리 설정 및 사용 방법 - Annotation
- Annotation을 사용하여 Named 쿼리를 정의할 때에는 Entity에 직접 정의한다.
- 다음 예시를 살펴보자.
@Entity
@NamedQuery(
name = "Player.findPlayerName",
query = "select p.name from Player p where p.id = :playerId")
public class Player {...}
- 위의 예시처럼, Annotation을 사용하여 Entity 레벨에 Named 쿼리를 정의할 수 있다.
- 정의된 Named 쿼리는 다음과 같이 사용할 수 있다.
String result = em.createQuery("Player.findPlayerName", Player.class)
.setParameter("playerId", 1L)
.getSingleResult();
d) Named 쿼리 설정 및 사용 방법 - XML
- XML에 정의할 때에는 다음과 같이 작성한다.
[META-INF/namedQueryPlayer.xml]
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm" version="2.1">
<named-query name="Player.findPlayerName">
<query><![CDATA[
select p
from Player p
where p.id = :playerId
]]></query>
</named-query>
<named-query name="Player.findAllPlayer">
<query>select p from Player p</query>
</named-query>
</entity-mappings>
- 작성한 XML 파일을 적용하기 위해서 persistence.xml에 다음과 같이 등록한다.
[META-INF/persistence.xml]
<persistence-unit name = "hellojpql">
<mapping-file> META-INF/namedQueryPlayer.xml</mapping-file>
</persistence-unit>
e) Named 쿼리 사용 시 주의사항
- Named 쿼리는 XML이 항상 우선권을 가진다.
- Application 환경에 따라 다른 XML을 배포할 수 있다.
'Back-end > JPA 개념' 카테고리의 다른 글
JPA 개발 꿀팁 (0) | 2022.05.25 |
---|---|
35. JPQL - 벌크 연산 (0) | 2022.05.08 |
33. JPQL - Fetch Join의 한계 (0) | 2022.05.06 |
32. JPQL - Collection Fetch Join과 Distinct (0) | 2022.05.05 |
31. JPQL - Fetch Join 개념 (0) | 2022.05.04 |
댓글