• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

Quarydsl 로 no-offset 페이지네이션이 구현가능할까요?

22.11.12 08:39 작성 조회수 1.11k

0


[질문 내용]
여기에 질문 내용을 남겨주세요.

김영한님 로드맵중 실전로드맵 패키지 듣고있는데,

restapi설계중에 무한스크롤을 구현해야하는 시점에

강의 내용에 Quarydsl로 페이지네이션 강의가 나와서 여쭤봅니다

no-offset 방식으로 페이지네이션이 구현 가능할까요 ?

 

가능하다면 어떤식으로 구현해야할까요..

답변 1

답변을 작성해보세요.

4

y2gcoder님의 프로필

y2gcoder

2022.11.12

안녕하세요. 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님께서는 더 깔끔한 방법으로 하실 수 있을 것 같습니다.


감사합니다.

S-J L님의 프로필

S-J L

질문자

2022.11.13

대충 흐름만 봐도 정성이 느껴집니다 감사합니다

y2gcoder님의 프로필

y2gcoder

2022.11.13

도움이 되셨으면 좋겠습니다. 감사합니다!