Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
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 31
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

프로젝션과 결과 반환 - DTO 조회 본문

인프런/[인프런] QueryDsl

프로젝션과 결과 반환 - DTO 조회

Seung__ 2021. 9. 3. 21:20

1. MemberDto


  • projection할 때 member의 username, age만 projection 하고 싶음.
@Data
public class MemberDto {

    private String username;
    private int age;

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

 

 

 

2. JPQL 사용하여 DTO로 조회


  • 순수 JPA에서 DTO를 조회할 때는 new 명령어를 사용
  • DTO의 package이름을 다 적어줘야해서 귀찮음......
  • 생성자 방식만 지원함
    @Test
    public void findDtoByJPQL(){
        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);
        }
    }

 

 

 

 

3. Querydsl사용 DTO 조회


  • 프로퍼티 접근-setter
    • setter를 통해 값이 생성.
    • Projections.bean(타입, 데이터...) : Projectoin을 구성하는 bean을 생성, 
    • 타입과 데이터를 받아 setter활용하여  DTO로 반환
    public static <T> QBean<T> bean(Class<? extends T> type, Expression<?>... exprs) {
        return new QBean<T>(type, exprs);
    }
    @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);
        }
    }
  • 필드 직접 접근
    • Projections.fields : DTO field에 직접 넣어서 반환.(setter 필요 없음)
    @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()
    • DTO의 생성자와 대응되어야 함.
    @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);
        }
    }

 

 

 

4. entity와 DTO의 필드 이름이 다른 경우?


  • 예를들어 UserDto를 생성하고 
  • username이 아니라 name으로 변경했다고 해보자.
  • username이 name에 들어갈까???
    @Test
    public void findUserDtoBy(){
        List<UserDto> result = queryFactory
                .select(Projections.fields(UserDto.class,
                        member.username,
                        member.age))
                .from(member)
                .fetch();

        for (UserDto userDto : result) {
            System.out.println("userDto = " + userDto);
        }
    }
  • 대응이 안되니 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 findUserDtoBy(){
        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);
        }
    }
userDto = UserDto(name=member1, age=10)
userDto = UserDto(name=member2, age=20)
userDto = UserDto(name=member3, age=30)
userDto = UserDto(name=member4, age=40)

 

 

 

5. 서브쿼리 별칭 적용


  • ExpressionUtils.as(JPAExpressions.~~~)
    @Test
    public void findUserDtoBy(){
        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);
        }
    }
userDto = UserDto(name=member1, age=40)
userDto = UserDto(name=member2, age=40)
userDto = UserDto(name=member3, age=40)
userDto = UserDto(name=member4, age=40)

 

 

6. GitHub : 210903 Projection, DTO


 

GitHub - bsh6463/Querydsl

Contribute to bsh6463/Querydsl development by creating an account on GitHub.

github.com

 

Comments