스프링데이터 + JPA/QueryDSL

34. QueryDSL 페이지 컨트롤러

sdafdq 2023. 12. 4. 07:45
@GetMapping("/v3/members")
public Page<MemberTeamDto> searchMemberV3(MemberSearchCondition condition, Pageable pageable){
    return memberRepository.searchPageComplex(condition,pageable);
}

여기서 볼 점은, Pageable 인자 정도?

 

참고로, ArgumentsResolver에 의해서, 알아서 저 객체들에 다 바인딩 해 준다.

객체의 필드명과, 클라이언트가 요청할 때 보내는 파라미터명이 같아야 바인딩이 제대로 된다.

 

Pageable의 인자로는

page : 몇번째 페이지

size : 한 페이지 당 사이즈

가 있다.

 

예를 들어

http://localhost:8080/v3/members?page=3&size=5&teamName=teamB

이렇게 요청할 경우, Pageable의 필드명 page와 size,

condition의 필드명 teamName을 넣어줬다.

 

/* select
    member1.id,
    member1.username,
    member1.age,
    team.id,
    team.name 
from
    Member member1   
left join
    member1.team as team 
where
    true 
    and team.name = ?1 
    and true 
    and true */ select
        m1_0.member_id,
        m1_0.username,
        m1_0.age,
        m1_0.team_id,
        t1_0.name 
    from
        member m1_0 
    left join
        team t1_0 
            on t1_0.team_id=m1_0.team_id 
    where
        true 
        and t1_0.name=? 
        and true 
        and true 
    offset
        ? rows 
    fetch
        first ? rows only

쿼리가 잘 나간다.

and true 저거는 https://qwefdg3.tistory.com/942 이거 참조

 

페이지에 관한 파라미터가 Pageable에 잘 묶여 인자로 잘 받아서 활용 했고,

@Override
public Page<MemberTeamDto> searchPageComplex(MemberSearchCondition condition, Pageable pageable) {
    List<MemberTeamDto> result = query.select(new QMemberTeamDto(
                    member.id, member.username, member.age, team.id, team.name
            )).from(member).leftJoin(member.team, team)
            .where(
                    usernameEq(condition.getUsername()),
                    teamNameEq(condition.getTeamName()),
                    ageGoe(condition.getAgeGoe()),
                    ageLoe(condition.getAgeLoe())
            )
            .offset(pageable.getOffset())
            .limit(pageable.getPageSize())
            .fetch();

    JPAQuery<Long> countQuery= query.select(member.count()).from(member).leftJoin(member.team, team)
            .where(
                    usernameEq(condition.getUsername()),
                    teamNameEq(condition.getTeamName()),
                    ageGoe(condition.getAgeGoe()),
                    ageLoe(condition.getAgeLoe())
            );

    return PageableExecutionUtils.getPage(result, pageable, countQuery::fetchOne);
}

teamName 저것도 객체의 필드명 보고 잘 묶여서(아마 setter일 듯) 쿼리보면 제대로 조건으로 들어갔다.

 

 

또, 정렬 기능이 따로 있긴 있다.

그런데, orderBy로 직접 하는 게 더 편할거다.

 

스프링 데이터 JPA의 정렬 기능을 QueryDSL의 OrderSpecifier로 바꿔야 하는데, 

그냥 order by로 하는게 나음.

루트 엔티티 범위 넘어가면 스프링 데이터 JPA의 Sort 기능 보다는 직접 쿼리로 하거나 파라미터를 받아서 직접 처리하라고 하는데..

 

뒤에서 따로 추가적으로 설명을 한다고 함.