점프 투 스프링부트 추가 기능 구현 - 답변 페이징 및 정렬 기능 구현

박철현·2023년 8월 4일
0

점프투스프링부트

목록 보기
8/14
post-thumbnail
  • 점프투스프링부트 추가기능 구현 일곱번째, 답변 페이징 및 정렬 기능 구현

  • 질문 리스트 페이징 코드 조금 변경하여 구현하였습니다.

  • question detail 뷰를 보여줄 때 페이징 결과를 같이 넘겨주는 형식으로 구현하였습니다!

  • 구현 결과

    • '최신순' 버튼 누를 시 가장 마지막 맨위
    • '추천순' 버튼 누를 시 추천 수가 높은것이 맨위, 동등할 경우 createDate 기준
  • 정렬 기준은 sort 파라미터로 받고, page도 파라미터로 받습니다!
  	@GetMapping("/detail/{id}")
	public String detail(Model model, @PathVariable Integer id, AnswerForm answerForm,
		@RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "") String sort) {
		Question question = questionService.getQuestion(id);
		Page<Answer> paging = answerService.getAnswerPage(question, page, sort);
		model.addAttribute("question", question);
		model.addAttribute("paging", paging);
		return "question/question_detail";
	}
  • AnswerService 에서 질문에 해당하는 답변 가져오도록 아래 메서드를 구현했습니다.

    • 서비스 위에 @Transactional(readOnly=true) 적용되어 있어 트랜잭션 달지 않았습니다.
    • 파라미터 sort로 넘어온 값에 따라 if문으로 구현했는데, return answerRepository.findAllByQuestion(question, pageable); 부분이 겹쳐 개선이 필요할 것 같습니다.
    • 아무 값도 안오면, 기본 정렬로서 답변 createDate 기준으로 하려고 정렬 기준 추가하지 않았습니다.
    • 컬렉션을 정렬 기준으로 바로 넣을 수 없어서 findAllByQuestionOrderByVoter 메서드를 따로 만들었습니다.
    public Page<Answer> getAnswerPage(Question question, int page, String sort) {
    			Pageable pageable;
    
    			// 최신순
    			if (sort.equals("createDate")) {
    				List<Sort.Order> sorts = new ArrayList<>();
    				sorts.add(Sort.Order.desc("createDate"));
    				pageable = PageRequest.of(page, 10, Sort.by(sorts)); //페이지 번호, 개수
    				return answerRepository.findAllByQuestion(question, pageable);
    			}
    
    			// 추천순, 기본
    			else {
    				pageable = PageRequest.of(page, 10); // 페이지네이션 정보
    				// 추천순 : 10개에 페이지정보만 주면 알아서
    				if (sort.equals("voter"))
    					return answerRepository.findAllByQuestionOrderByVoter(question, pageable);
    				// 기본
    				return answerRepository.findAllByQuestion(question, pageable);
    			}
    		}
  • AnswerRepository

    • findAllByQuestion 메서드 : 페이지 정렬 기준 적용한 페이지 반환
    • findAllByQuestionOrderByVoter : Set의 size를 정렬 기준으로 삼기 위해 JPQL 사용, 두번째로는 생성일 기준 정렬
     Page<Answer> findAllByQuestion(Question question, Pageable pageable);
    
    		@Query("SELECT e "
    			+ "FROM Answer e "
    			+ "WHERE e.question = :question "
    			+ "ORDER BY SIZE(e.voters) DESC, e.createDate")
    		Page<Answer> findAllByQuestionOrderByVoter(@Param("question") Question question, Pageable pageable);
  • HTML의 경우 th:with로 정렬 조건 유지하도록 했고, th:appendclass로 버튼에 active 속성을 추가하였습니다.

  • th:appendclass로 String 조건을 처음 써봤는데 아래와 같습니다.

    • String 비교 시 th:classappend="${#strings.equals(param.sort, 'createDate')} ? 'active'" 형태입니다!
    • 참고
      <div>
              <ul class="nav d-flex align-items-baseline gap-2">
                  <span>정렬 기준</span>
                  <li class="nav-item">
                      <a class="nav-link btn btn-primary text-white" th:classappend="${#strings.equals(param.sort, 'createDate')} ? 'active'" th:href="@{|?sort=createDate&page=${paging.number}|}">최신순</a>
                  </li>
                  <li class="nav-item">
                      <a class="nav-link btn btn-primary text-white" th:classappend="${#strings.equals(param.sort, 'voter')} ? 'active'" th:href="@{|?sort=voter&page=${paging.number}|}">추천순</a>
                  </li>
              </ul>
          </div>
  • 상세 코드를 확인하고 싶은 분들은 Git-PR를 참조해주세요.
profile
비슷한 어려움을 겪는 누군가에게 도움이 되길

0개의 댓글