01. 프로젝션
프로젝션이란?
SELECT 절에 조회할 대상을 지정하는 것을 말한다.
프로젝션 대상으로는 엔티티, 임베디드 타입, 스칼라 타입 (숫자, 문자 등 기본 데이터 타입) 이 있다.
관계형 데이터베이스 같은 경우, 스칼라 타입(숫자, 문자 등 기본 데이터 타입)만 넣을 수 있다.
엔티티 프로젝션
다음 쿼리의 예시를 보자. SELECT m FROM Member m
이렇게 가져온 쿼리의 결과는 영속성 컨텍스트에 관리가 될까? 된다.
아래는 예시 코드이다.
아래 실행 결과와 같이 영속성 컨텍스트에서 관리되고 있음을 볼 수 있다.
다음 쿼리의 예시를 보자. SELECT m.team FROM Member m
Member를 통해 Team을 조회하고 싶다면 다음과 같이 작성하면 된다.
List result = em.createQuery("select m.team from Member m", Team.class)
.getResultList();
이렇게 작성하면 조인 쿼리가 나가는 것을 볼 수 있다. (이건 묵시적 조인이라고 하는데, 나중에 배운다고 한다.)
JPQL 입장에서는 select문이지만 실제 실제 SQL문은 select 할 때 join도 한다. 아래와 같이 join 된다.
다음과 같이 작성하는 것이 더 바람직하다.
List result = em.createQuery("select t from Member m join m.team t", Team.class)
.getResultList();
임베디드 타입 프로젝션
다음 쿼리의 예시를 보자. SELECT m.address FROM Member m
임베디드 타입의 한계는 어디에 소속되어 있는지 엔티티를 작성해야 한다는 것이다. 아래는 예시 코드이다.
em.createQuery("select o.address from Order o", Address.class)
.getResultList();
아래와 같이 Address 관련된 것만 쿼리해 오는 것을 볼 수 있다.
스칼라 타입 프로젝션
다음 쿼리를 보자. SELECT m.username, m.age FROM Member m
내가 원하는 것을 가져온다. 아래는 예시 코드이다.
em.createQuery("select distinct m.username, m.age from Member m")
.getResultList();
아래와 같이 잘 가져오는 것을 볼 수 있다.
02. 프로젝션 - 여러 값 조회
Query 타입으로 조회
별로 권장되지 않는다. 아래는 예시코드이다.
List resultList = em.createQuery("select distinct m.username, m.age from Member m")
.getResultList();
Object o = resultList.get(0);
Object[] result = (Object[]) o;
System.out.println("username = " + result[0]);
System.out.println("age = " + result[1]);
아래와 같은 결과가 나온다.
Object[] 타입으로 조회
별로 권장되지 않는다. 타입 캐스팅이 생략된다.
아래는 예시 코드이다.
List <Object[]> resultList = em.createQuery("select distinct m.username, m.age from Member m")
.getResultList();
Object[] result = resultList.get(0);
System.out.println("username = " + result[0]);
System.out.println("age = " + result[1]);
new 명령어로 조회
단순 값을 DTO로 바로 조회한다.
패키지 명을 포함한 전체 클래스 명을 입력해야한다.
순서와 타입이 일치하는 생성자가 필요하다.
예시를 테스트하기 위해 MemberDTO 클래스를 만든다.
public class MemberDTO {
private String username;
private int age;
public MemberDTO(String username, int age) {
this.username = username;
this.age = age;
}
// getter, setter..
}
아래는 예시 코드이다.
List result = em.createQuery("select new jpql.MemberDTO(m.username, m.age) from Member m", MemberDTO.class)
.getResultList();
MemberDTO memberDTO = result.get(0);
System.out.println("memberDTO username= " + memberDTO.getUsername());
System.out.println("memberDTO age = " + memberDTO.getAge());
아래와 같은 결과가 나온다.
'JPA' 카테고리의 다른 글
JPQL - 경로 표현식 (0) | 2024.02.09 |
---|---|
엔티티 작성 시 주의사항 (2) | 2024.01.30 |
객체지향 쿼리 언어1 - 기본 문법과 쿼리 API (0) | 2024.01.18 |
값 타입 컬렉션 (0) | 2024.01.18 |
값 타입의 비교 (0) | 2024.01.16 |