티스토리 뷰

MemberDTO

package study.querydsl.dto;


import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@NoArgsConstructor
public class MemberDTO {
    private String username;
    private int age;

    public MemberDTO(String username, int age) {
        this.username = username;
        this.age = age;
    }
}

JPQL에서 DTO로 조회하는 방법은 다음과 같다.

@Test
    public void findDtoByJPQL(){
//아래와 같이 생성자를 사용하는 것과 같은 문법으로 진행되는데, 매우 길다...
//쉼표 뒤에는 DTO의 클래스타입을 넣어주고, select 뒤에 새로운 생성자로 객체를 생성하듯 넣어준다.
//그러면 리턴 타입이 DTO로 나오게 된다.

        List<MemberDTO> resultList = em.createQuery("select new study.querydsl.dto.MemberDTO(m.username,m.age) from Member m", MemberDTO.class)
                                       .getResultList();
        for (MemberDTO memberDTO : resultList) {
            System.out.println("memberDTO = " + memberDTO);
        }

    }

이 테스트의 실행 결과는 다음과 같다.

memberDTO = MemberDTO(username=member1, age=10)
memberDTO = MemberDTO(username=member2, age=20)
memberDTO = MemberDTO(username=member3, age=30)
memberDTO = MemberDTO(username=member4, age=40)

위와 같이 DTO 타입으로 나오게 된다

위를 개선한 방식이 queryDsl에서 제공하는 방법이다.

총 세가지 방식이 있는데, setter 사용방식, fields 사용방식, 생성자 사용방식이 있다.

@Test
    public void findDtoBySetter() throws Exception{
        //given
        List<MemberDTO> fetch = queryFactory.select(Projections.
																										bean(MemberDTO.class,
																										member.username, member.age))
                                            .from(member)
                                            .fetch();
        for (MemberDTO memberDTO : fetch) {
            System.out.println("memberDTO = " + memberDTO);
        }


        //when

        //then
    }

@Test
    public void findDtoByFields() throws Exception{
        //given
        List<MemberDTO> fetch = queryFactory.select(Projections.
																									fields(MemberDTO.class,
                                                  member.username, member.age))
                                            .from(member)
                                            .fetch();
        for (MemberDTO memberDTO : fetch) {
            System.out.println("memberDTO = " + memberDTO);
        }
        //when

        //then
    }

@Test
    public void findDtoByConstructor() throws Exception{
        //given
        List<MemberDTO> fetch = queryFactory.select(Projections.
																								constructor(MemberDTO.class,
                                                member.username, member.age))
                                            .from(member)
                                            .fetch();
        for (MemberDTO memberDTO : fetch) {
            System.out.println("memberDTO = " + memberDTO);
        }
        //when

        //then
    }

setter방식이나, fields 방식의 경우, DTO와 Qtype에 있는 변수의 이름이 같으면 상관이 없지만, 다른 경우에는 값이 들어가지 않는 경우가 발생한다.

아래는 그 경우를 Test코드로 작성한 것이다.

QEntity의 변수명과 DTO의 변수명이 다를 때 Setter방식의 동작

UserDTO

package study.querydsl.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class UserDTO {
    private String name;//
    private int age;
}

@Test
    public void findUserDTO() throws Exception{
        //given
        List<UserDTO> fetch = queryFactory.select(Projections.bean(UserDTO.class,
                                                    member.username, member.age))
                                            .from(member)
                                            .fetch();
        for (UserDTO userDTO : fetch) {
            System.out.println("UserDTO = " + userDTO);
        }

        //when
        //then
    }

//name에 모두 null이 들어간 것을 볼 수 있다.
UserDTO = UserDTO(name=null, age=10)
UserDTO = UserDTO(name=null, age=20)
UserDTO = UserDTO(name=null, age=30)
UserDTO = UserDTO(name=null, age=40)

위와 같은 방식의 해결 방법은 다음과 같다.

as를 통한 해결방법

@Test
    public void findUserDTOAs() throws Exception{
        //given
        List<UserDTO> fetch = queryFactory.select(Projections.
																									bean(UserDTO.class,
																		//이곳에 as 를 붙이고 받고싶은 DTO의 변수명을 입력
																		//그럼 변수가 자동으로 DTO의 변수와 매칭이됨
                                    member.username.as("name"), member.age))
                                    .from(member)
                                    .fetch();
        for (UserDTO userDTO : fetch) {
            System.out.println("UserDTO = " + userDTO);
        }
    }

UserDTO = UserDTO(name=member1, age=10)
UserDTO = UserDTO(name=member2, age=20)
UserDTO = UserDTO(name=member3, age=30)
UserDTO = UserDTO(name=member4, age=40)

위와같이 결과가 나오게 된다.


Uploaded by N2T

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함