본문 바로가기
JPA/JPQL

[JPQL] 프로젝션(SELECT)

by yoon_seon 2023. 4. 25.

📌 프로젝션(SELECT)

  • SELECT 절에 조회할 대상을 지정하는 것
  • 프로젝션 대상: 엔티티, 임베디드 타입, 스칼라 타입(숫자, 문자등 기본 데이터 타입)
  • SELECT m FROM Member m → 엔티티 프로젝션
  • SELECT m.team FROM Member m  엔티티 프로젝션
  • SELECT m.address FROM Member m 임베디드 타입 프로젝션
  • SELECT m.username, m.age FROM Member m 스칼라 타입 프로젝션
  • DISTINCT로 중복 제거 사용 가능

 

엔티티 프로젝션 - 묵시적 조인

em.createQuery("select m.team from Member m", Team.class).getResultList();

 

JPQL에는 JOIN절이 없지만  JOIN을 해서 Team 엔티티를 조회한다.

 

 

엔티티 프로젝션 - 명시적 조인

em.createQuery("select t from Member m join m.team t", Team.class).getResultList();

실행되는 SQL은 동일하다. 명시적으로 JPQL에 적어줬기에 가독성이 높아지고 JOIN  예측이 가능하다.

묵시적 조인보다는 명시적 조인을 사용하는것이 좋다.

 

 

임베디드 타입 프로젝션

em.createQuery("select o.address from Order o", Address.class).getResultList();
//SQL: SELECT o.city, o.street, o.zipcode FROM ORDERS o

임베디드 타입은 엔티티에 소속되어 있기때문에 엔티티로 조회해야한다는 한계가 있다.

 

 

스칼라 타입 프로젝션

여러 값을 가지고 오는것을 스칼라 타입 프로젝션이라고 한다.

em.createQuery("select distinct m.address, m.age from Member m").getResultList();

스칼라 타입으로 조회 시 타입 다른 데이터는 어떻게 가져와야할까?

  • Query 타입으로 조회
  • Object[] 타입으로 조회
List resultList = em.createQuery("select m.username, m.age from Member m")
		.getResultList();
Object obj = resultList.get(0);
Object[] result = (Object[]) obj;
System.out.println("username : "+result[0]);
System.out.println("age      : "+result[1]);

Query 타입으로 조회하면 타입이 다르기 때문에 Object로 데이터를 조회하고 Object[]로 캐스팅해서 값을 조회할 수 있다.

 

  • new 명령어로 조회
    • 단순 값을 DTO로 바로 조회. 데이터 조회를 위한 DTO를 생성해야 한다.
    • SELECT new jpql.MemberDTO(m.username, m.age) FROM Member m
    • 패키지 명을 포함한 전체 클래스명을 적어줘야 한다.
    • 순서와 타입이 일치하는 생성자 필요.
@Getter
public class MemberDTO {
    private String username;
    private int age;

    public MemberDTO(String username, int age) {
        this.username = username;
        this.age = age;
    }
}
List<MemberDTO> resultList = em.createQuery("select new jpql.MemberDTO(m.username, m.age) from Member m", MemberDTO.class)
		.getResultList();
MemberDTO memberDTO = resultList.get(0);
System.out.println("memberDTO : "+memberDTO.getUsername());
System.out.println("memberDTO : "+memberDTO.getAge());

 

 

 


해당 글은 인프런의 [자바 ORM 표준 JPA 프로그래밍 - 기본편] 강의를 정리한 내용입니다.

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 강의

JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., - 강의 소개 | 인프런

www.inflearn.com

댓글