해결된 질문
작성
·
1.3K
답변 1
4
안녕하세요. S-J L님, 공식 서포터즈 y2gcoder입니다.
no-offset 방식으로 페이지네이션이 구현 가능할까요 ?
에 대해 질문해주셨습니다. 일단 당연히 가능합니다. 제가 개발했던 프로젝트에서 no-offset 페이징 구현 코드를 간단한 코드로 변형해서 보여드리겠습니다.
@RequiredArgsConstructor
@Repository
public class PostQueryPepository {
private final JPAQueryFactory queryFactory;
...
public Slice<PostResponse> findPostsWithNoOffset(Long lastPostId, Pageable pageable) {
List<Post> fetch = queryFactory.selectFrom(post)
.where(getWhereLastPostIdLowerThan(lastPostId))
.orderBy(post.id.desc())
.limit(pageable.getPageSize() + 1)
.fetch();
List<PostResponse> content = fetch.stream()
.map(p -> new PostResponse(p))
.collect(Collectors.toList());
boolean hasNext = false;
if (content.size() > pageable.getPageSize()) {
content.remove(pageable.getPageSize());
hasNext = true;
}
return new SliceImpl<>(content, pageable, hasNext);
}
}
Spring Data JPA의 Slice 방식을 따라서 한 번에 조회해야 하는 데이터 개수 + 1만큼 조회한 뒤에 hasNext 값을 구했습니다. 한 번에 조회해야 하는 개수보다 더 많은 수를 조회해왔다면 다음 페이지가 있는 것이니 hasNext 값을 true로 바꾸고 마지막에 추가로 조회 해온 데이터를 삭제 하고 SliceImpl에 담아서 반환해주고 해당 반환 값을 적절한 DTO로 변경하여 응답해주었습니다. 첫 번째 조회가 아닌 N번째 조회 때는 lastPostId에 값이 들어올테니 where 조건문에서 lastPostId 보다 더 작은 id를 가진 post들을 기준으로 데이터들을 페이징하여 들고오도록 구현했습니다. 해당 방식으로 응답한 값을 앱(React Native)에서는 React Query의 useInfiniteQuery()를 사용해서 화면에 뿌려주었습니다.
이대로 똑같이 하라는 말씀은 절대 아닙니다. 단지 이렇게 구현할 수 있다는 것을 보여드리고자 했고, 아마 S-J L님께서는 더 깔끔한 방법으로 하실 수 있을 것 같습니다.
감사합니다.
대충 흐름만 봐도 정성이 느껴집니다 감사합니다