코딩/sparta TIL

Paging 공부중

americanoallday 2025. 4. 9. 17:16

필터를 쓰기 위해서는

1 FilterRestrationBean 등록 필요

2 doFilter 오버라이드 

 

페이징 구현하기

1. 현재 몇 페이지(page)인가?

2. 한 페이지당 몇개의 게시글(size)을 보여주는가?

Page page = PageRequest.of(page, size)
Page<Schedule> se = ScheduleRepository.findAll(page);

 

이런식으로 쓴다고 하는데, 나는 페이지라는게 뭔지 궁금하다-_-

 

✅ 1. Page<T>란?

Page<T>Spring Data JPA에서 제공하는 페이징 결과 타입

단순히 리스트만 담고 있는 게 아니라, 페이지 번호, 전체 페이지 수, 총 데이터 개수, 현재 페이지의 데이터 목록 등도 같이 담겨 있음.

{
  "content": [ {일정1}, {일정2}, ... ],
  "totalPages": 10,
  "totalElements": 100,
  "number": 0,
  "size": 10,
  ...
}

 

// controller
// 일정 페이지 API 
    @GetMapping("/schedules/page")
    public ResponseEntity<Page<SchedulePageResponseDto>> findAllPage(
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size
    ) {
        Page<SchedulePageResponseDto> result = scheduleService.findAllPage(page, size);
        return ResponseEntity.ok(result);
    }

✅ 2. ResponseEntity<Page<SchedulePageResponseDto>> 의미

ResponseEntity는 HTTP 상태코드응답 본문(body)같이 리턴할 수 있는 클래스인데

여기에 Page<SchedulePageResponseDto>를 담았다는 건:

“페이징 정보와 함께 일정 리스트를 클라이언트에 내려주겠다!” 라는 뜻. 🙌

 

//service
@Transactional(readOnly = true)
    public Page<SchedulePageResponseDto> findAllPage(int page, int size) {
        // 클라이언트에서 1부터 전달된 페이지 번호를 0 기반으로 조정
        int adjustedPage = (page > 0) ? page - 1 : 0;
        PageRequest pageable = PageRequest.of(adjustedPage, size, Sort.by("updatedAt").descending());
        // 1. Schedule Page 조회
        Page<Schedule> schedulePage = scheduleRepository.findAll(pageable);
        //Page<SchedulePageResponseDto> schedulePage2 = scheduleRepository.findSchedulePageWithCommentCount(pageable);
        // 2. 일정 ID 리스트 추출
        List<Long> scheduleIds = schedulePage.stream()
                .map(Schedule::getId)
                .collect(Collectors.toList());
        // 3. 별도 쿼리로 댓글 수 조회
        List<CommentCountDto> countResults = commentRepository.countByScheduleIds(scheduleIds);
        Map<Long, Long> commentCountMap = countResults.stream()
                .collect(Collectors.toMap(CommentCountDto::getScheduleId, CommentCountDto::getCount));
        // 4. 각 Schedule을 SchedulePageResponseDto로 변환 (댓글 수는 Long을 int로 변환)
        return schedulePage.map(schedule -> new SchedulePageResponseDto(
                schedule.getId(),
                schedule.getTitle(),
                schedule.getContent(),
                commentCountMap.getOrDefault(schedule.getId(), 0L).intValue(),
                schedule.getCreatedAt(),
                schedule.getUpdatedAt(),
                schedule.getUser().getUserName()
        ));
    }

✅ 3. int adjustedPage = (page > 0) ? page - 1 : 0;

Spring의 페이징은 0부터 시작함.

클라이언트가 1페이지라고 보내면 → 내부적으로는 0으로 바꿔줘야 맞음.

이게 바로 “0-based index” 조정.

 

✅ 4. PageRequest란?

PageRequest.of(adjustedPage, size, Sort.by("updatedAt").descending());

페이징 처리에 필요한 정보를 담는 Spring에서 제공하는 객체

of() 메서드를 이용해서:

몇 페이지를 볼 건지 (adjustedPage)

한 페이지에 몇 개를 볼 건지 (size)

어떤 기준으로 정렬할 건지 (여기선 최신순)

➡️ Pageable이라는 인터페이스의 구현체 중 하나

 

✅ 5. .map()을 쓰는 이유?

return schedulePage.map(schedule -> new SchedulePageResponseDto(...));

Page<Schedule>Page<SchedulePageResponseDto>변환(mapping) 하기 위해 사용

Page 자체가 stream()map() 같은 메서드를 제공해줘서, 이렇게 간단하게 쓸 수 있음.

'코딩 > sparta TIL' 카테고리의 다른 글

TIL 35 : 예외처리 복습  (1) 2025.04.15
TIL 34 : HttpMessageConverter  (0) 2025.04.15
CH3 Schedule Project  (0) 2025.04.04
TIL 32 : JPA, Spring Data JPA  (0) 2025.04.01
TIL 31 - 2 : Token, JWT, Filter  (0) 2025.03.31