Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |
Tags
- html #css #부트스트랩 #웹사이트 #개발 #초보 #til #내일배움캠프 #스파르타코딩클럽
- java #문법
- sql #부트캠프 #내일배움캠프 #웹관리자 #도전 #학습
- sql #내일배움캠프 #스파르타코딩클럽
- java
Archives
- Today
- Total
Hyeok의 웹 개발 블로그
<2025.05.19> 페이지네이션, 무한스크롤 본문
🔎 페이지네이션(Pagination)
- 많은 데이터를 한 번에 다 보여주면 느려지니까, 적당히 나눠서 보여주는 방법
🔎 무한스크롤(Infinite Scroll)
- 스크롤을 내릴 때마다 자동으로 데이터를 더 보여주는 방식
🔎 커서 기반 페이지네이션(Cursor Pagination)
- "어디까지 봤는지 표시"해서 그 다음 데이터를 보여주는 방식
🔎 오프셋 기반
- 페이지 번호로 데이터를 나눠 보여줌
SELECT * FROM item ORDER BY created_at DESC LIMIT 10 OFFSET 100000000;
이런 쿼리는 앞에 1억 개 데이터를 먼저 읽고 그 다음 10개를 준다.
→ 점점 느려진다.
커서 기반
"마지막으로 본 아이디(ID)"를 기억하고, 그 다음부터 보여준다.
예:
- 1페이지: id 1~10 → 마지막은 id 10
- 2페이지: WHERE id > 10 → id 11부터 다시 10개 보여줌!
즉, 이미 본 데이터는 건너뛰고 바로 다음 것만 보여줍니다. 훨씬 빠름
Spring에서 커서 기반 무한스크롤 구현 방법
1. 헬퍼 클래스 만들기 (ScrollPaginationCollection)
public class ScrollPaginationCollection<T> {
private final List<T> itemsWithNextCursor; // 데이터 + 다음 거 1개
private final int countPerScroll;
public boolean isLastScroll() {
return this.itemsWithNextCursor.size() <= countPerScroll;
}
public List<T> getCurrentScrollItems() {
return isLastScroll() ? itemsWithNextCursor : itemsWithNextCursor.subList(0, countPerScroll);
}
public T getNextCursor() {
return itemsWithNextCursor.get(countPerScroll - 1);
}
}
- 이 클래스는 다음 스크롤이 있는지 확인하고, 현재 보여줄 데이터만 잘라주는 역할을 합니다.
2. 서비스 로직에서 사용
public GetFeedsResponse getFeeds(String userEmail, Long roomId, int size, Long lastFeedId) {
PageRequest pageRequest = PageRequest.of(0, size + 1); // 다음 페이지 있는지 확인하려고 +1
Page<Feed> page = feedRepository.findAllByRoomAndIdLessThanOrderByIdDesc(room, lastFeedId, pageRequest);
ScrollPaginationCollection<Feed> feedsCursor = ScrollPaginationCollection.of(page.getContent(), size);
return GetFeedsResponse.of(feedsCursor, ..., ...);
}
- lastFeedId는 "지금까지 본 마지막 게시글 ID"
- size + 1은 다음 페이지가 있는지 없는지 확인하려고 하나 더 가져온 것
3. 클라이언트 응답용 DTO
public class GetFeedsResponse {
private List<FeedsInfoResponse> contents;
private long totalElements;
private long nextCursor;
public static GetFeedsResponse of(...) {
if (feedsScroll.isLastScroll()) {
return newLastScroll(...); // 다음 거 없음
}
return newScrollHasNext(...); // 다음 커서 포함
}
}
- nextCursor == -1 → 마지막 페이지라는 뜻
- 프론트에서는 이 값 보고 "더 이상 요청 안 함"
예시 요청
- 최초 요청:
GET /feed?roomId=1&size=1&lastFeedId=9223372036854775807
- 응답:
{
"contents": [ { "feedId": 20, ... } ],
"nextCursor": 20
}
- 다음 요청:
GET /feed?roomId=1&size=1&lastFeedId=20
→ 이런 식으로 nextCursor → lastFeedId 로 계속 요청하며 무한 스크롤이 된다.
'TIL > Spring' 카테고리의 다른 글
| <2025.06.04> 임베딩 (0) | 2025.06.04 |
|---|---|
| <2025.05.08> TestCode - 단위 테스트 (0) | 2025.05.08 |
| <2025.05.07> 연관관계 N+1 (0) | 2025.05.07 |
| <2025.05.01> 영속성 컨텍스트 (2) | 2025.05.01 |
| <2025.04.22> 배달 기능 프로젝트 피드백 (1) | 2025.04.22 |