[스프링부트+JPA+타임리프] 게시물 최신순 + 좋아요순 + 조회수순 정렬 기준 조회 + 페이징

jyleever·2022년 6월 1일
3
post-thumbnail
post-custom-banner

카테고리별 & 최신순/좋아요순/조회수순 & 페이징 게시물 조회할 수 있다.

스프링 데이터 JPA Pageable 포스팅 링크
스프링 데이터 JPA 쿼리 메서드 포스팅 링크

해당 포스팅은 페이징에 관련된 설명은 생략한다.

개발 순서

  1. PostController로 카테고리명, 정렬 기준 파라미터를 넘겨받고 PostService를 호출한다.
  2. PostService에서 정렬 기준 파라미터를 이용해 정렬한 Pageable 객체를 생성하고 PostRepository를 호출하여 카테고리명과 Pageable을 넘겨 PostDto 타입의 page 객체를 받아 반환한다.
  3. PostController에서 page 객체를 뷰로 반환한다.

Post-all.html

게시글 목록을 보여주는 뷰

<div class="col-auto">
     <a class="btn btn-primary" 
        th:href="@{/community/post/{category_name}(category_name=${category_name}, orderby=viewCount)}">조회수 순</a>
     <a class="btn btn-primary" 
        th:href="@{/community/post/{category_name}(category_name=${category_name}, orderby=likeCount)}">좋아요 순</a>
     <a class="btn btn-primary" 
        th:href="@{/community/post/{category_name}(category_name=${category_name}, orderby=id)}">최신 순</a>
</div>

현재 카테고리명 category_name과 정렬 기준인 orderby=정렬할 칼럼명 에 맞는 컨트롤러를 호출한다.
이때 정렬할 순서 변수명은 현재 Post 엔티티의 칼럼명 (예 - viewCount, likeCount, id) 과 일치해야 한다.

PostController

글 전체를 카테고리별/페이징별/정렬기준별 조회하는 컨트롤러

    /** 글 전체 조회 (카테고리별 & 페이징) **/
    /* /{category_name}/page={pageNo}&orderby={orderCriteria} */
    @GetMapping("/{category_name}")
    public String readAllPost(@PathVariable(required = false) String category_name,
                          @RequestParam(required = false, defaultValue = "0", value = "page") int pageNo,
                          @RequestParam(required = false, defaultValue = "id", value = "orderby") String orderCriteria,
                          Pageable pageable,
                          @AuthenticationPrincipal UserAdapter user,
                          Model model){

        /** ========== 페이징 처리 ========== **/

		...
        Page<PostDto.ResponsePageDto> postPageList =
                postService.getPageList(pageable, pageNo, category_name, orderCriteria); // 페이지 객체 생성
		...

        model.addAttribute("postPageList", postPageList);
		
        ...

        return "community/post-all";
    }
  • 컨트롤러는 RequestParam 방식으로 orderby에 해당하는 orderCriteria 변수를 받을 수 있다.
  • 이 때 orderCriteria를 required=false, defaultValue = "id"로 설정하여 뷰에서 정렬 순서 파라미터를 보내주지 않아도 기본적으로 id(최신순) 으로 정렬할 수 있도록 한다.
    즉, 처음 전체 게시물 리스트를 조회할 때 최신순으로 정렬된다
  • PostService 에서 getPageList 메서드를 호출하여 원하는 category_name, orderCriteria 기준으로 정렬된 게시물 페이징 리스트를 반환해온다

PostService

컨트롤러에서 넘겨받은 카테고리명과 정렬 기준을 이용해 게시물 페이징 객체를 반환한다.


    private static final int PAGE_POST_COUNT = 10; // 한 화면에 보일 컨텐츠 수

    /** 게시물 리스트 페이징 **/
    @Override
    public Page<PostDto.ResponsePageDto> getPageList(Pageable pageable, int pageNo,
    						String category_name, String orderCriteria) {

        /* 넘겨받은 orderCriteria 를 이용해 내림차순하여 Pageable 객체 반환 */
        pageable = PageRequest.of(pageNo, PAGE_POST_COUNT, Sort.by(Sort.Direction.DESC, orderCriteria));
        /* category_name에 해당하는 post 페이지 객체 반환 */
        Page<Post> page = postRepository.findByCategory_Name(category_name, pageable);

        /* Dto로 변환 */
        Page<PostDto.ResponsePageDto> postPageList = page.map(
                post -> new PostDto.ResponsePageDto(
                        post.getId(),
                        post.getMember().getId(),
                        post.getTitle(),
                        post.getMember().getNickname(),
                        post.getViewCount(),
                        post.getLikeCount(),
                        post.getCreatedDate(),
                        post.getCategory().getViewName(),
                        post.getCategory().getName()
                )
        );

        return postPageList;
    }
  • 넘겨받은 orderCriteria 를 이용해 Sort.Direction.DESC(내림차순)하여 Pageable 객체 반환
    pageable = PageRequest.of(pageNo, PAGE_POST_COUNT, Sort.by(Sort.Direction.DESC, orderCriteria));
  • 스프링 데이터 JPA 이용해서 category_name에 해당하는 post page 객체 반환

PostRepository

카테고리명으로 Post 타입인 Page 객체를 반환한다.

    /** 카테고리 name 으로 post 찾기 **/
    Page<Post> findByCategory_Name(String category_name, Pageable pageable);

스프링 데이터 JPA 쿼리 메소드를 이용하면 파라미터로 Pageable 인터페이스를 넘겨 페이징을 사용할 수 있게 된다.

post-search.html

게시물 검색 시에도 정렬을 설정할 수 있다

<div class="col-auto">
        <a class="btn btn-primary" th:href="@{/community/post/search/{category_name}(category_name=${category_name}, keyword=${keyword}, orderby=viewCount)}">조회수 순</a>
        <a class="btn btn-primary" th:href="@{/community/post/search/{category_name}(category_name=${category_name}, keyword=${keyword}, orderby=likeCount)}">좋아요 순</a>
        <a class="btn btn-primary" th:href="@{/community/post/search/{category_name}(category_name=${category_name}, keyword=${keyword}, orderby=id)}">최신 순</a>
</div>

컨트롤러로 현재 카테고리명 category_name(PathVariable), keyword(RequestParam), orderby=정렬할 칼럼명 파라미터를 보낸다.

PostController

검색 조건에 맞는 글 전체를 카테고리별/페이징별/정렬기준별 조회하는 컨트롤러

    /** 글 검색 (카테고리별) 페이지 **/
    /* /{category_name}/search/keyword={keyword}&page={pageNo}&orderby={orderCriteria} */
    @GetMapping("/search/{category_name}")
    public String searchByCategory(@PathVariable("category_name") String category_name,
                                   @RequestParam("keyword") String keyword,
                                   @RequestParam(required = false, defaultValue = "0", value = "page") int pageNo,
                                   @RequestParam(required = false, defaultValue = "id", value = "orderby") String orderCriteria,
                                   Pageable pageable,
                                   @AuthenticationPrincipal UserAdapter user,
                                   Model model){

		...

        /** ========== 페이징 처리 ========== **/


        pageNo = (pageNo == 0) ? 0 : (pageNo - 1);

        // 페이지 객체 생성
        Page<PostDto.ResponsePageDto> postResponsePageDto =
                postService.searchPageList(pageable, pageNo, keyword, category_name, orderCriteria);
		
        ...

        return "community/post-search";
    }
  • 카테고리명은 @PathVariable 방식으로 받고, keyword, pageNo, orderCriteria는 @RequestParam 방식으로 받는다.
  • PostServicesearchPageList 메서드를 호출하여 Page 객체 생성

PostService

컨트롤러에서 넘겨받은 검색 키워드, 카테고리명, 정렬 기준을 이용해 게시물 페이징 객체를 반환

     /** 게시물 검색 리스트 페이징 **/
    @Override
    public Page<PostDto.ResponsePageDto> searchPageList(Pageable pageable, int pageNo, String keyword, String category_name, String orderCriteria) {

        /* 넘겨받은 orderCriteria 를 이용해 내림차순하여 Pageable 객체 반환 */
        pageable = PageRequest.of(pageNo, PAGE_POST_COUNT, Sort.by(Sort.Direction.DESC, orderCriteria));

        /* category_name에 해당하면서 keyword를 포함하는 post 페이지 객체 반환 */
        Page<Post> page = postRepository.findByCategory_NameAndTitleContaining(category_name, keyword, pageable);
        ...
  	}
  • PostRepositoryfindByCategory_NameAndTitleContaining 쿼리 메서드를 이용하여 keyword를 포함하는 데이터 반환

PostRepository

/** 카테고리 name 으로 keyword를 포함하고 있는 post 찾기 - 카테고리별 키워드 검색 **/
Page<Post> findByCategory_NameAndTitleContaining(String category_name, String keyword, Pageable pageable);



post-custom-banner

0개의 댓글