[Springboot] 게시판 프로젝트-1

조히고닝·2023년 3월 31일
0

점프 투 스프링부트를 보고 게시판을 따라 만드는 프로젝트이다.

3-15의 추가기능을 모두 구현하는 것을 목표로 한다.

초보자라서 코드컨벤션이나 클린코드보다는 기능 구현을 목적으로 작성하였습니다.

Github : Joyfulgwon🕺

💡 수정해야 할 부분 : 질문 상세창에서 답변을 띄워주므로 질문 상세 관련, 답변 관련 컴포넌트 수정필요

고려해야 하는 부분 : 답변의 정렬 기준. 추천순으로 정렬하고 추천수가 같은 경우 최신순으로 정렬할 수 있다.

주의해야 하는 부분 : 답변을 페이징해서 넘겨 줄 때 올바른 질문과 잘 매핑되어서 넘어와야 이상한 질문 상세에 뜨는 걸 막을 수 있다.

QuestionController : 기존엔 question 객체만 id로 검색해서 넘겨주면 답변 출력 가능.

question이 answerList를 가지고 있음. → answer서비스에서 질문을 기준으로 페이지단위로 받아서 모델에 담아서 같이 질문 상세창으로 보내줘야함

@GetMapping(value = "/detail/{id}")
    public String detail(Model model, @PathVariable ("id")Integer id, AnswerForm answerForm , CommentForm commentForm, @RequestParam(value="answerPage",defaultValue="0")int answerPage){
        Question question = this.questionService.getQuestion(id);
        Page<Answer> answerPaging= this.answerService.getList(question,answerPage);
        questionService.Count(question);
        model.addAttribute("question",question);
        model.addAttribute("answerPaging",answerPaging);
        return "question_detail";
    }

AnswerService: 메서드 추가

question을 기준으로 Page 단위로 answer 를 받아서 첫번째 정렬기준 : 추천인 , 두번째 정렬기준: 생성일 기준으로 정렬해서 넘겨줌.

public Page<Answer> getList(Question question, int page) {
        List<Sort.Order> sorts=new ArrayList<>();
        sorts.add(Sort.Order.desc("voter"));
        sorts.add(Sort.Order.desc("createTime"));
        Pageable pageable= PageRequest.of(page,5,Sort.by(sorts));
        return this.answerRepository.findByQuestion(question,pageable);
    }

AnswerRepository :findByQuestion 메서드 추가

Spring-Data-JPA 가 손쉬운 페이징을 구현해주는 클래스를 제공하고 있다.

  • org.springframework.data.domain.Page
  • org.springframework.data.domain.PageRequest
  • org.springframework.data.domain.Pageable

pageble 객체를 입력으로 받아서 answer가 담긴 Page 형태로 리턴해준다.

Page<Answer> findByQuestion (Question question,Pageable pageable);

question_detail.html : 기존의 질문리스트 가져다가 변수 변경

<!-- 답변 페이징처리 시작 -->
    <div th:if="${!answerPaging.isEmpty()}">
        <ul class="pagination justify-content-center">
            <li class="page-item" th:classappend="${!answerPaging.hasPrevious} ? 'disabled'">
                <a class="page-link" href="javascript:void(0)" th:data-page="${answerPaging.number - 1}">
                    <span>이전</span>
                </a>
            </li>
            <li th:each="page: ${#numbers.sequence(0, answerPaging.totalPages-1)}"
                th:if="${page >= answerPaging.number-3 and page <= answerPaging.number+3}"
                th:classappend="${page == answerPaging.number} ? 'active'"
                class="page-item">
                <a th:text="${page}" class="page-link" href="javascript:void(0)" th:data-page="${page}"></a>
            </li>
            <li class="page-item" th:classappend="${!answerPaging.hasNext} ? 'disabled'">
                <a class="page-link" href="javascript:void(0)" th:data-page="${answerPaging.number+1}">
                    <span>다음</span>
                </a>
            </li>
        </ul>
    </div>
    <!-- 답변 페이징처리 끝 -->

    <!-- 답변 페이징 검색 폼 -->
    <form th:action="@{|/question/detail/${question.id}|}" method="get" id="answerPageForm">
        <input type="hidden" id="answerPage" name="answerPage" th:value="${answerPaging.number}">
    </form>
</div>

// 답변 페이징 관련 JS 코드
<script>
const page_elements = document.getElementsByClassName("page-link");
    Array.from(page_elements).forEach(function (element) {
        element.addEventListener('click', function () {
            document.getElementById('answerPage').value = this.dataset.page;
            document.getElementById('answerPageForm').submit();
        });
    });
</script>

⇒ 답변 페이징 및 정렬 완료.

0개의 댓글