Spring/QueryDsl

태태개발일지 -Querydsl

태태코 2024. 9. 24. 12:12
반응형

QueryDsl

 

 

결과값의 종류

1. 단일 결과 조회

fetchOne(): 하나의 결과만 반환.

fetchFirst(): 결과 중 첫 번째 것만 반환.

Member member = queryFactory
    .selectFrom(QMember.member)
    .where(QMember.member.username.eq("user1"))
    .fetchOne();

 

주의사항: 결과가 없으면 null을 반환하고, 두 개 이상의 결과가 있으면 NonUniqueResultException이 발생합니다.

 

2. 다중 결과 조회

fetch(): 리스트 형태로 여러 결과를 반환.

List<Member> members = queryFactory
    .selectFrom(QMember.member)
    .where(QMember.member.age.gt(20))
    .fetch();

 

 

3. 페이징 결과 조회

fetchResults(): 결과 리스트와 전체 개수를 함께  반환.

fetchCount(): 전체 결과 개수만 반환.

 

QueryResults<Member> results = queryFactory
    .selectFrom(QMember.member)
    .offset(0)
    .limit(10)
    .fetchResults();

long total = results.getTotal();
List<Member> members = results.getResults();

 

 

4. 튜플(Tuple) 조회

여러 필드를 선택하여 Tuple 형태로 반환.

List<Tuple> result = queryFactory
    .select(QMember.member.username, QMember.member.age)
    .from(QMember.member)
    .fetch();

for (Tuple tuple : result) {
    String username = tuple.get(QMember.member.username);
    Integer age = tuple.get(QMember.member.age);
}

 

 

5. DTO 조회

원하는 DTO 형태로 결과를 매핑하여 반환합니다.

방법:

프로퍼티 접근: Projections.bean()

필드 직접 접근: Projections.fields()

생성자 사용: Projections.constructor()

@QueryProjection 사용: 컴파일 시 타입 체크 가능

 

List<MemberDto> result = queryFactory
    .select(Projections.bean(MemberDto.class,
        QMember.member.username,
        QMember.member.age))
    .from(QMember.member)
    .fetch();

 

1. 프로퍼티 접근: Projections.bean()

 

사용 시기

 

DTO에 Getter와 Setter 메서드가 있을 때 사용.

필드명과 DTO의 프로퍼티명이 정확히 일치할 때 효과적.

 

장점

 

코드 가독성이 높습니다.

DTO의 프로퍼티에 값을 설정하므로, 객체 지향 원칙에 부합함.

Setter 메서드를 통해 값을 주입하므로, 캡슐화를 유지할 수 있다.

 

단점

 

DTO에 기본 생성자와 Setter 메서드가 필요하다.

필드명이 일치하지 않으면 매핑이 되지 않는다.

런타임 시에만 오류를 발견할 수 있으며, 컴파일 시 타입 체크가 불가능하다.

 

List<MemberDto> result = queryFactory
    .select(Projections.fields(MemberDto.class,
        QMember.member.username,
        QMember.member.age))
    .from(QMember.member)
    .fetch();

 

2. 필드 직접 접근: Projections.fields()

 

사용 시기

 

DTO의 필드가 public이거나 접근 가능할 때 사용.

Getter와 Setter가 없거나 사용하기 어려운 경우에 유용.

 

장점

 

Setter 메서드 없이도 값을 주입할 수 있다.

필드명만 일치하면 되므로, 프로퍼티 접근보다 유연하다.

 

단점

 

캡슐화가 약화됩니다. 필드에 직접 접근하므로, 객체 지향 원칙에 어긋날 수 있다.

필드명이 일치하지 않으면 매핑이 되지 않는다.

마찬가지로 컴파일 시 타입 체크가 불가능하다.

 

List<MemberDto> result = queryFactory
    .select(Projections.constructor(MemberDto.class,
        QMember.member.username,
        QMember.member.age))
    .from(QMember.member)
    .fetch();

 

3. 생성자 사용: Projections.constructor()

 

사용 시기

 

DTO에 원하는 필드를 받는 생성자가 있을 때 사용.

**불변 객체(Immutable Object)**를 생성하고자 할 때 유용.

 

장점

 

Setter나 필드 접근 없이도 값을 주입할 수 있다.

DTO를 불변 객체로 유지할 수 있다.

생성자를 통해 객체 생성이 이루어지므로, 객체의 일관성을 보장.

 

단점

 

파라미터의 타입과 순서가 정확히 일치해야 한다.

필드명이 달라도 타입과 순서로 매핑되므로, 실수할 가능성이 있다.

런타임 시에만 오류를 발견할 수 있으며, 컴파일 시 타입 체크가 불가능하다.

 

List<MemberDto> result = queryFactory
    .select(new QMemberDto(QMember.member.username, QMember.member.age))
    .from(QMember.member)
    .fetch();

 

4. @QueryProjection 사용

 

사용 시기

 

컴파일 시 타입 체크를 통해 안전한 코드를 작성하고자 할 때 사용.

QueryDSL에 의존성이 허용되는 DTO에 적용 가능.

 

장점

 

컴파일 시점에 타입 체크가 가능하여, 오류를 사전에 방지할 수 있다.

코드 자동 완성 등 IDE의 지원을 받을 수 있다.

생성자 파라미터의 타입과 순서를 정확히 맞출 필요가 없다.

 

단점

 

DTO에 QueryDSL 어노테이션을 추가해야 하므로, QueryDSL에 의존성이 생긴다.

Q파일 생성을 위해 추가적인 빌드 설정이 필요하다.

프로젝트 규모가 커질수록 빌드 시간이 증가할 수 있다.

 

반응형

'Spring > QueryDsl' 카테고리의 다른 글

태태개발일지 - QueryDSL  (1) 2024.09.29