오봉이와 함께하는 개발 블로그
JPA - 프로젝션(select) 본문
728x90
프로젝션
- select 절에 조회할 대상을 지정하는 것
- 프로젝션 대상 : 엔티티, 임베디드 타입, 스칼라 타입(숫자, 문자 등 기본 데이터 타입)
- SELECT m FROM Member m -> 엔티티 프로젝션
- 조회하는 대상이 영속성 컨텍스트에 관리된다.
- SELECT m.team FROM Member m -> 엔티티 프로젝션 (Member의 Team 엔티티 조회)
- SELECT t FROM Member m join Team t 라고 하는 것이 성능상 더 유리하다.
- Team을 조회하기 때문에 타입을 Team으로 받아야 하고, 조회도 Team.class로 해야 한다.
- SELECT m.address FROM Member m -> 임베디드 타입 프로젝션 (Member의 address 임베디드 타입 조회)
- address를 조회하기 때문에 타입을 Address로 받아야 하고, 조회도 Address.class로 해야 한다.
- 임베디드 타입은 소속되어 있기 때문에 단독 조회는 불가능하다.
- selelct a from Address a는 불가능하다.
- SELECT m.username, m.age FROM Member m -> 스칼라 타입 프로젝션 (Member의 스칼라 타입 조회)
- 원하는 컬럼만 가져오는 방식
- 조회는 값의 타입을 특정할 수 없기 때문에(username = String, age = int) 타입은 Query, Object[], new 명령어로 받아야 한다.
- 조회 클래스(Member.class)도 정할 수 없다.
- DISTINCT로 중복 제거
프로젝션 - 여러 값 조회
- SELECT m.username, m.age FROM Member m
- Query 타입으로 조회
- Object[] 타입으로 조회
- new 명령어로 조회
- 단순 값을 DTO로 바로 조회
- SELECT new jpabook.jpql.UserDTO(m.username, m.age) FROM Member m
- 패키지명을 포함한 전체 클래스명 입력
- 순서와 타입이 일치하는 생성자 필요
- 단순 값을 DTO로 바로 조회
Query 타입으로 조회
Query query = em.createQuery("SELECT m.username, m.age, FROM Member m");
List resultList = query.getResultList();
Iterator iterator = resultList.iterator();
while (iterator.hasNext()) {
Object[] row = (Object[]) iterator.next();
String username = (String) row[0];
Integer age = (Integer) row[1];
}
Object[] 타입으로 조회
List resultList = em.createQuery("select 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]);
// or
List<Object[]> resultList = em.createQuery("select 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 명령어로 조회
@Getter @Setter
public class MemberDTO {
private String username;
private int age;
// 순서와 타입이 일치하는 생성자 필요
public MemberDTO(String username, int age) {
this.username = username;
this.age = age;
}
}
// 패키지명을 포함한 전체 클래스명 입력
List<MemberDTO> 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.getUsername() = " + memberDTO.getUsername());
System.out.println("memberDTO.getAge() = " + memberDTO.getAge());
정리
Query 타입이나 Object[] 타입으로 조회하면 굉장히 불편하기 때문에 new 명령어 조회를 사용하자.
단, new 명령어도 패키지가 길어지면 불편할 수 있다.
출처 : 인프런 김영한 지식공유자님의 스프링 부트와 JPA 실무 완전 정복 로드맵 강의
728x90
'BE > JPA' 카테고리의 다른 글
JPA - 조인, 서브 쿼리 (0) | 2022.06.30 |
---|---|
JPA - 페이징 (0) | 2022.06.30 |
JPA - 기본 문법과 쿼리 API (0) | 2022.06.30 |
JPA - 객체 지향 쿼리 언어 소개 (0) | 2022.06.29 |
JPA - 실전 예제 6 - 값 타입 매핑 (0) | 2022.06.29 |
Comments