본문 바로가기

JPA

2월 13일 JPA JPQL 프로젝션(받는값 매핑)

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로 중복제거

 

프로젝션 - 여러 값 조회

select m.username , m.age from Member m

1.query 타입으로 조회

2.object[] 타입으로 조회

3.new 명령어로 조회 (이 경우 new 메소드로 DTO를 생성한다는 느낌으로 생성자를 불러서 사용하면 된다.)

단순 값을 DTO로 바로 조회

select new jpabook.jpql.userDto(m.username , m.age)

from Member m 

패키지 명을 포함한 전체클래스명 입력

순서와 타입이 일치하는 생성자가 필요

 

List<Member> result = em.createQuery(

"select m from Member m" , Member.class

).getResultList()

위 형태로 Member를 여러개 가져와서 List에 넣으면 그 모든 Membre를 영속성 관리하게 된다.

만약 member에 있는  team객체 필드를 검색해 Team만을 받게되면 반환타입도 Team 이어야 한다.

List<Team> result = em.createQuery(

"select m.team from Member m " , Team.class

).getResultList()

이 쿼리를 실행하면 Join 쿼리가 사용되게 된다.

그 이유는 Member 가 저장된 엔티티와 Team 이 저장된 엔티티가 서로 다르기 때문에 

Member를 베이스로 Team을 불러와야 하기 때문

그런데 위 쿼리만 보고 Join이 사용될거라 생각하기 힘들다

"select m.team from Member m Join m.team t" , Team.class

이런 식으로 작성해야 Join이 사용되는지 바로 알 수 있다.

 

임베디드 타입을 결과로 받을 경우 

em.createQuery(

"select o.address from Order o" , Address.class

)

위 경우 

1. from 절의 엔티티는 꼭 임베디드 타입가 속해있는 엔티티 여야 한다.

2. 반환 타입을 임베디드 타입으로 해준다

 

스칼라 , 일반 타입 SQL처럼 가져오기

em.createQuery(

"select distinct m.username , m.age from Member m"

)

스칼라에 경우는 리턴값을 예측할 수 없어서 반환타입을 명시하지 않는다.

 

타입을 넣는 방법은

1.배열 지정이 없으니 Object로 들어가게 된다.

2.List<Object[]> 와 타입코드 Member.class를 넣는방법

3.new 명령어로 DTO를 생성

-1.데이터를 받을 DTO를 생성 

이때 DTO에 필드로는 받을수 있는 예상값을 넣어준다. 

-2.쿼리작성 List<MemberDTO> result = em.createQuery("select new jpql.MemberDto(m.username , m.age) from Member m" , MemberDTO.class).getResultList();

이 방법은 select에 프로젝션에 DTO생서자를 넣어 반환타입을 DTO로 받는 방법

꼭 new 생성자 형식으로 생성해준다.

또한 생성자는 풀 패키지 명을 넣어야 한다.