DevBoi

[JPA] Querydsl & Paging 본문

Develop/[JPA]

[JPA] Querydsl & Paging

HiSmith 2023. 9. 2. 17:42
반응형

Querydsl 처리 중 페이징처리 관련 정리

 

컨트롤러

@GetMapping("/member")
  @Operation(description = "회원 상세 조회")
  public PageImpl<Member> getAllMember( MemberReadDto memberReadDto,PageRequest pageRequest) {
    Pageable pageable = pageRequest.of();
    PageImpl<Member> result = memberService.getAllMember(memberReadDto,pageable);
    return result;
  }

 

커스텀 페이징 객체 구현

package com.boiler.core.backend.member.dto.paging;

import org.springframework.data.domain.Sort;

public class PageRequest {

    private int page = 1;
    private int size = 10;
    private Sort.Direction direction = Sort.Direction.DESC;

    public void setPage(int page) {
        this.page = page <= 0 ? 1 : page;
    }

    public void setSize(int size) {
        int DEFAULT_SIZE = 10;
        int MAX_SIZE = 50;
        this.size = size > MAX_SIZE ? DEFAULT_SIZE : size;
    }

    public void setDirection(Sort.Direction direction) {
        this.direction = direction;
    }

    public org.springframework.data.domain.PageRequest of() {
        return org.springframework.data.domain.PageRequest.of(page - 1, size, direction, "create_date");
    }
}

 

서비스

public PageImpl<Member> getAllMember(MemberReadDto memberReadDto, Pageable pageable) {
    QueryResults<Member> results =  queryFactory.select(member)
      .from(member)
      .where(
        MemberQuery.eqAuthCode(memberReadDto.authCode()),
        MemberQuery.eqStatus(memberReadDto.status()),
        MemberQuery.eqkeyword(memberReadDto.keyword())
      )
      .offset(pageable.getOffset())
      .limit(pageable.getPageSize())
      .fetchResults();
    return new PageImpl<>(results.getResults(), pageable, results.getTotal());
  }

QueryDsl QueryResult 와 FetchResult 방식이 사라짐

QueryDsl 5.0 부터는 Deprecated됨...

count(*)이 복잡한 쿼리에서는 동작하지 않아서 결론은 그냥 니들이 count 쿼리로 해라 라는 입장이다

무튼 그래서 아래와 같이 카운트 쿼리를 별도로 호출하는 방식으로 변경했다.

 

변경된 서비스

public PageImpl<Member> getAllMember(MemberReadDto memberReadDto, Pageable pageable) {
    int count = this.getAllMemberCount(memberReadDto);
    List<Member> results =  queryFactory.select(member)
      .from(member)
      .where(
        MemberQuery.eqAuthCode(memberReadDto.authCode()),
        MemberQuery.eqStatus(memberReadDto.status()),
        MemberQuery.eqkeyword(memberReadDto.keyword())
      )
      .offset(pageable.getOffset())
      .limit(pageable.getPageSize())
      .fetch();
    return new PageImpl<>(results, pageable, count);
  }
  public Integer getAllMemberCount(MemberReadDto memberReadDto) {
    return Math.toIntExact(queryFactory
      .select(member.count())
      .from(member)
      .where(
        MemberQuery.eqAuthCode(memberReadDto.authCode()),
        MemberQuery.eqStatus(memberReadDto.status()),
        MemberQuery.eqkeyword(memberReadDto.keyword())
      )
      .fetchFirst());
  }

 

 

 

결과

{
  "content": [
    {
      "createDate": "2023-09-02T08:25:36.729Z",
      "modifiedDate": "2023-09-02T08:25:36.729Z",
      "id": 0,
      "memberId": "string",
      "memberPw": "string",
      "memberIdImageUrl": "string",
      "nickname": "string",
      "name": "string",
      "gender": "string",
      "introduce": "string",
      "birth": "string",
      "phone": "string",
      "address": "string",
      "email": "string",
      "authCode": "string",
      "snsCode": "string",
      "status": "string",
      "memo": "string"
    }
  ],
  "pageable": {
    "offset": 0,
    "sort": {
      "empty": true,
      "unsorted": true,
      "sorted": true
    },
    "pageNumber": 0,
    "pageSize": 0,
    "paged": true,
    "unpaged": true
  },
  "last": true,
  "totalPages": 0,
  "totalElements": 0,
  "first": true,
  "size": 0,
  "number": 0,
  "sort": {
    "empty": true,
    "unsorted": true,
    "sorted": true
  },
  "numberOfElements": 0,
  "empty": true
}

 

 

반응형