좌충우돌 개발공부

TIL(20240611) [뉴스피드프로젝트: 페이지네이션 Pageable]


📌 Spring

💡 뉴스피드 프로젝트 : 페이지네이션 Pageable

  • 페이지네이션
    • 10개씩 페이지네이션하여, 각 페이지 당 뉴스피드 데이터가 10개씩 나오게 합니다.
  • 정렬 기능
    • 생성일자 기준 최신순
    • 좋아요 많은 순
  • 기간별 검색 기능
    • 예) 2024.05.01 ~ 2024.05.27 동안 작성된 뉴스피드 게시물 검색

사실 프로젝트 발표와 마감제출까지 완료한 상태라 구지 할 필요는 없었지만 한번 도전을 해보고 싶어서 구현해보았다.

블로그에서 간단하게 하는 방식이 있어서 한번 따라해보았는데, 구현하고 보니.. 문제가 있었다.

// PostController


  // 생성일자 최신순 페이징처리
  @GetMapping("/posts/paging")
  public Page<PostResponseDto> getPostAll(
      @PageableDefault(size = 10, sort = "id", direction = Sort.Direction.DESC) Pageable pageable) {
    return postService.getPostAll(pageable);
  }

  // 좋아요 최신순 페이징 처리
  @GetMapping("/posts/bylikescount/paging")
  public Page<PostResponseDto> getPostByLikesCount(
      @PageableDefault(size = 10, sort = "id", direction = Sort.Direction.DESC) Pageable pageable) {
    return postService.getPostsByPostLikesCount(pageable);
  }

  // 기간별 검색 페이징 처리
  @GetMapping("/posts/search/{start}/{end}")
  public Page<PostResponseDto> searchPost(
      @PathVariable LocalDate start,
      @PathVariable LocalDate end,
      @PageableDefault(size = 10, sort = "id", direction = Sort.Direction.DESC) Pageable pageable) {
    LocalDateTime startDate = start.atStartOfDay(); // LocalDate -> LocalDateTime 변환
    LocalDateTime endDate = end.atTime(23, 59, 59);
    return postService.searchPost(startDate, endDate, pageable);
  }


// PostService

  // 생성일자 최신순 정렬 페이징 처리
  @Transactional(readOnly = true)
  public Page<PostResponseDto> getPostAll(
      @PageableDefault(size = 10, sort = "id", direction = Sort.Direction.DESC) Pageable pageable) {
    Page<Post> posts = postRepository.findAllByOrderByCreatedAtDesc(pageable);
    return posts.map(PostResponseDto::fromEntity);
  }

  // 좋아요 많은순 정렬 페이징 처리
  @Transactional(readOnly = true)
  public Page<PostResponseDto> getPostsByPostLikesCount(
      @PageableDefault(size = 10, sort = "id", direction = Sort.Direction.DESC) Pageable pageable) {
    Page<Post> postsByPostCountLikes = postRepository.findAllByOrderByPostLikesCountDesc(pageable);
    return postsByPostCountLikes.map(PostResponseDto::fromEntity);
  }

  // 기간별 검색 및 페이징
  @Transactional(readOnly = true)
  public Page<PostResponseDto> searchPost(LocalDateTime start, LocalDateTime end,
      Pageable pageable) {
    Page<Post> searchedPosts = postRepository.findByCreatedAtBetween(start, end, pageable);
    return searchedPosts.map(PostResponseDto::fromEntity);
  }


// PostRepository

public interface PostRepository extends JpaRepository<Post, Long> {

  Page<Post> findAllByOrderByCreatedAtDesc(Pageable pageable);

  Page<Post> findByCreatedAtBetween(LocalDateTime start, LocalDateTime end, Pageable pageable);

  Page<Post> findAllByOrderByPostLikesCountDesc(Pageable pageable);


}



// PostResponseDto

  public static PostResponseDto fromEntity(Post post) {
    PostResponseDto postResponseDto = new PostResponseDto();
    postResponseDto.postId = post.getId();
    postResponseDto.userId = post.getUser().getId();
    postResponseDto.title = post.getTitle();
    postResponseDto.contents = post.getContents();
    postResponseDto.createAt = post.getCreatedAt();
    postResponseDto.modifiedAt = post.getModifiedAt();
    postResponseDto.postLikesCount = post.getPostLikesCount();

    return postResponseDto;
  }

반환타입을 Post에서 -> PostResponseDto으로 바꿔주기 위해 해당 내용을 추가했고, PostEntity에서는 생성일자나 수정일자 같은 경우에는 timestamp로 LocalDateTime 형태로 저장이 되어있기 때문에 입력값을 Pathvariable로 LocalDate로 받아서 LocalDateTime형태로 형변환 해준 후 repository에서 DB내용을 찾을 수 있도록 해야했다. 생성일자 최신순 Page findAllByOrderByCreatedAtDesc(Pageable pageable); 부분을 구현 후에는 좋아요 많은순 구현은 금방 감을 잡았던 것 같다. 아직까진 SQL 쿼리문에 대한 이해도가 부족해서 조금 더 깊이있게 공부를 하면 JpaRepository에서 SQL쿼리문을 활용하여 찾으려고 하는 부분에 대한 정확한 이해가 생길 것 같다.

해당 기능을 구현하기 위해 아래 블로그를 참고 했습니다.

스프링부트 검색,페이징처리

🏁 뉴스피드 프로젝트 피드백

🔅 잘한 점

  • 스웨거 적용
  • 기술 스택 작성한 것
  • 리드미 깔끔하게 작성한 것
  • 깃허브 Git Flow 전략 사용한 것
  • 코드리뷰하며 팀원들간의 의사소통한 것 (인상깊었다하심)

✔ 아쉬운 점

  • Response header 작성 (이 부분은 팀원 중 한 분이 작성하셨다가 지우셨다고 한다..😂)

이번 프로젝트를 통해서 정말 느낀 것들이 많았다. 초기세팅 및 기획설계가 정말 중요하다고 생각했고, 1)초기세팅 : 코드컨벤션에 대한 공부가 필요 코드명에 대한 불일치, 불명확성 .. 등등 2)기획설계 : 각자의 해석에 따라 구현을 해서 나중에 의견이 달라서 재구현해야하는 상황이 발생 다음 프로젝트에서는 기획설계 부분에 신경을 많이 써야겠다고 생각했다. 그리고 테마(주제)를 정했지만 의도대로는 구현이 되지 않은 듯한 느낌.. 사실 기능 구현이 서툴다 보니 이런 부분을 많이 놓쳤던 것 같다. 개인적으로 기능 구현부분에서는 이메일 인증 부분에서 많이 아쉬웠다…다음 번에는 더 공부를 해서 멋지게 구현해보고싶다! (최종프로젝트에…?ㅎㅎ;;;)

이번 프로젝트를 통해서 아쉬움도 많이 남기도 하지만 정말 많이 배우고, 깨닫을 수 있는 계기가 생겨서 좋았고 팀원들이랑 트러블 없이 순조롭게 잘 진행되어서 정말 감사하게 생각한다. 다음 프로젝트에도 모두들 화이팅!!!! 🥰