목차
프로젝션과 결과 반환
프로젝션(Projection) 은 쿼리 결과를 가져올 때 반환할 필드를 지정하는 것
프로젝션 : select 대상 지정
- 프로젝션 대상이 하나면 타입을 명확하게 지정할 수 있다.
- 프로젝션 대상이 둘 이상이면 튜플 이나 DTO 로 조회한다.
List<String> result = queryFactory .select(member.username.concat("_").concat(member.age.stringValue())) .from(member) .where(member.username.eq("member1")) .fetch();
|
튜플 조회
@Test public void tupleProjection(){ List<Tuple> result = queryFactory .select(member.username, member.age) .from(member) .fetch();
for (Tuple tuple : result){ String username = tuple.get(member.username); Integer age = tuple.get(member.age);
System.out.println("username = " + username); System.out.println("age = " + age); } }
|
select member0_.username as col_0_0_, member0_.age as col_1_0_ from member member0_
|
DTO 를 이용한 결과 반환
Projections
를 사용하면 쿼리 결과를 DTO 로 변환할 수 있다.
Projections 을 이용한 DTO 반환 방식은 3가지 방법을 지원한다.
- Setter 를 이용한 방식
- Field 에 직접 접근하는 방식
- 생성자를 이용한 방식
Setter 를 활용하는 방법
setter 를 이용한 방식은 Projections.bean
메소드를 이용해 쿼리 결과를 반환하도록 한다.
@Test public void findDtoBySetter(){ List<MemberDto> result = queryFactory .select(Projections.bean(MemberDto.class, member.username, member.age)) .from(member) .fetch();
for (MemberDto memberDto : result) { System.out.println("memberDto = " + memberDto); } }
|
필드 직접 접근
field 를 이용한 방식은 Projections.fields
메소드를 이용해 쿼리 결과를 반환하도록 한다.
@Test public void findDtoByField(){ List<MemberDto> result = queryFactory .select(Projections.fields(MemberDto.class, member.username, member.age)) .from(member) .fetch();
for (MemberDto memberDto : result) { System.out.println("memberDto = " + memberDto); } }
|
생성자 사용
생성자를 이용한 방식은 Projections.constructor
메소드를 이용해 쿼리 결과를 반환하도록 한다.
@Test public void findDtoByConstructor(){ List<MemberDto> result = queryFactory .select(Projections.constructor(MemberDto.class, member.username, member.age)) .from(member) .fetch();
for (MemberDto memberDto : result) { System.out.println("memberDto = " + memberDto); } }
|
DTO 와 Entity 의 Attribute 의 alias 가 서로 다를 경우
@Test public void findUserDto(){ List<UserDto> result = queryFactory .select(Projections.fields(UserDto.class, member.username.as("name"), member.age)) .from(member) .fetch();
for (UserDto userDto : result) { System.out.println("userDto = " + userDto); } }
|
서브 쿼리에 alias 사용
ExpressionUtils.as
@Test public void findUserDto(){ QMember memberSub = new QMember("memberSub");
List<UserDto> result = queryFactory .select(Projections.fields(UserDto.class , member.username.as("name") , ExpressionUtils.as(JPAExpressions .select(memberSub.age.max()) .from(memberSub), "age"))) .from(member) .fetch();
for (UserDto userDto : result) { System.out.println("userDto = " + userDto); } }
|
@Test public void findDtoByConstructor(){ List<MemberDto> result = queryFactory .select(Projections.constructor(MemberDto.class, member.username, member.age)) .from(member) .fetch();
for (MemberDto memberDto : result) { System.out.println("memberDto = " + memberDto); } }
|