개인 프로젝트를 하다 보니 Query DSL로 페이징을 구현해야 하는 상황에 직면하여 JPA와 QueryDSL 페이징 처리 방법에 대해 포스팅 하고자 합니다.
// Pageable 객체 생성, Service or Controller단
public Page<Question> getList(int page) {
Pageable pageable = PageRequest.of(page, 10);
return this.questionRepository.findAll(pageable);
}
// Repository
Page<Question> findAll(Pageable pageable);
.offset으로 페이지 번호, .limit으로 한 페이지당 갯수 지정public Page<Expenditure> searchExpenditure(Member member, SearchRequestDTO searchRequestDTO, Pageable pageable) {
// 기존의 쿼리 로직...
// 페이지에 맞춘 데이터 추출
List<Expenditure> results = jpaQueryFactory.selectFrom(expenditure)
.where(/* 조건들... */)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
// 전체 데이터 개수 추출
long total = jpaQueryFactory.selectFrom(expenditure)
.where(/* 동일한 조건들... */)
.fetchCount();
return new PageImpl<>(results, pageable, total);
}
/*
페이지별 지출 데이터 조회
*/
@Override
public Page<Expenditure> searchExpenditure(Member member, SearchRequestDTO searchRequestDTO) {
LocalDate startDate = searchRequestDTO.getStartDate();
LocalDate endDate = searchRequestDTO.getEndDate();
Long categoryId = searchRequestDTO.getCategoryId();
Integer minPrice = searchRequestDTO.getMinPrice();
Integer maxPrice = searchRequestDTO.getMaxPrice();
Integer pageNumber = searchRequestDTO.getPageNumber();
Integer pageLimit = searchRequestDTO.getPageLimit();
Pageable pageable = PageRequest.of(pageNumber, pageLimit);
// 여러 조건을 동적으로 추가할 수 있도록 도와주는 BooleanBuilder 도입
BooleanBuilder builder = createBooleanBuilder(categoryId, minPrice, maxPrice);
// 조건에 맞는 목록 구하기
List<Expenditure> expenditures = jpaQueryFactory.selectFrom(expenditure)
.where(
expenditure.member.eq(member),
expenditure.spendDate.between(startDate, endDate),
builder // 조건 동적 추가
)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
// 전체 데이터 개수 추출
long total = jpaQueryFactory.selectFrom(expenditure)
.where(
expenditure.member.eq(member),
expenditure.spendDate.between(startDate, endDate),
builder // 조건 동적 추가
)
.fetchCount();
return new PageImpl<>(expenditures, pageable, total);
}
/*
페이지별 지출 데이터 조회
*/
@Override
public Page<Expenditure> searchExpenditure(Member member, SearchRequestDTO searchRequestDTO) {
LocalDate startDate = searchRequestDTO.getStartDate();
LocalDate endDate = searchRequestDTO.getEndDate();
Long categoryId = searchRequestDTO.getCategoryId();
Integer minPrice = searchRequestDTO.getMinPrice();
Integer maxPrice = searchRequestDTO.getMaxPrice();
Integer pageNumber = searchRequestDTO.getPageNumber();
Integer pageLimit = searchRequestDTO.getPageLimit();
Pageable pageable = PageRequest.of(pageNumber, pageLimit);
// 여러 조건을 동적으로 추가할 수 있도록 도와주는 BooleanBuilder 도입
BooleanBuilder builder = createBooleanBuilder(categoryId, minPrice, maxPrice);
// 조건에 맞는 목록 구하기
List<Expenditure> expenditures = jpaQueryFactory.selectFrom(expenditure)
.where(
expenditure.member.eq(member),
expenditure.spendDate.between(startDate, endDate),
builder // 조건 동적 추가
)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
// 전체 데이터 개수 추출
Long total = jpaQueryFactory.select(expenditure.count())
.from(expenditure)
.where(
expenditure.member.eq(member),
expenditure.spendDate.between(startDate, endDate),
builder // 조건 동적 추가
)
.fetchOne();
return new PageImpl<>(expenditures, pageable, total != null ? total : 0L);
}