Hello

Spring boot 게시판 댓글 CRUD

by 볼빵빵오춘기

댓글 CRUD 하기전에 댓글은 게시물에 상세페이지에서 댓글 내용이 보이며, 댓글 쓰기, 수정 form 또한 상세페이지에 보이도록 해놓았다. 

상세페이지의 view.html은 다음과 같으며, 게시판 만들기 글을 확인하고 댓글 CRUD를 보면 될 될 것이다. 

 

html

// .. 내용 생략(상세페이지 관련 html)
<!-- 댓글 내용 부분 -->

<div  class="card" sec:authorize="isAuthenticated()">
    <div class="card-header">
        <div id="reply-write">댓글 쓰기</div>
    </div>
    <div class="card-body" id="reply-card-body">
        <form>
            <input type="hidden" id="boardId" th:value="${board.id}">
            <textarea id="reply-content" rows="3"  class="form-control mb-15"></textarea>

        </form>
    </div>
    <div class="card-footer">
        <button id="btn-reply-save" class="btn btn-primary">등록</button>
        <button id="btn-reply-update" class="btn btn-primary d-none">수정 등록</button>
        <button id="btn-reply-update-cancel" class="btn btn-primary d-none">수정 취소</button>
    </div>
</div>
<br>
<div class="card">
    <div class="card-header">댓글</div>
    <div class="card-body">
        <div th:if="${replies == null or #lists.isEmpty(replies)}">
            <!-- replies 리스트가 비어있을 때 -->
            <p>댓글이 없습니다.</p>
        </div>

        <ul id="reply-box" class="list-group" th:if="${replies != null and not #lists.isEmpty(replies)}">

            <li th:each="reply : ${replies}" class="list-group-item ">
                <div class="d-flex">

                    <span th:text="${reply.username}" class="">작성자 : test&nbsp;</span>&nbsp;&nbsp;
                    <button class="btn-xs btn-success reply-update" sec:authorize="isAuthenticated()" th:if="${reply.username == #authentication.principal.username}" th:attr="data-reply-id=${reply.id}">수정</button>&nbsp;
                    <button class="btn-xs btn-danger reply-delete" sec:authorize="isAuthenticated()" th:if="${reply.username == #authentication.principal.username}" th:attr="data-reply-id=${reply.id}">삭제</button>
                </div>
                <div th:text="${reply.content}" th:attr="data-reply-content=${reply.content}">댓글 내용!</div>
            </li>
        </ul>
    </div>
</div>

 

댓글 쓰기(Create)

Controller

@PostMapping("/communityV/{boardId}/replyW")
public ResponseEntity<?> replySave(@PathVariable int boardId, @RequestBody CommunityReplyEntity reply, @AuthenticationPrincipal PrincipalDetails principalDetails) {
    communityService.replyWrite(principalDetails.getUsername(), boardId, reply);
    ResponseDto<Integer> responseDto = new ResponseDto<>(HttpStatus.OK.value(), 1);
    return new ResponseEntity<>(responseDto, HttpStatus.OK);
}

 

Service

@Transactional
public void replyWrite(String username, int boardId, CommunityReplyEntity requstReply){
    CommunityEntity communityEntity = commnunityRepository.findById(boardId).orElseThrow(()->{
        return new IllegalArgumentException("글 찾기 실패");
    });

    requstReply.setUsername(username);
    requstReply.setCBbs(communityEntity);

    communityReplyRepository.save(requstReply);
}

 

댓글 읽기(Read)

Controller

  • 댓글은 원본 게시물 상세페이지에 들어가면 보이도록 해놓았다.
  • 댓글은 게시물관 연관관계가 되어있기 떄문에 따로 로직 필요없이 게시물을 가져오면 같이 조회가 가능하다.
@GetMapping("/communityV/{id}")
public String view(Model model,@PathVariable int id){

    // community에서 글 정보 가져오기
    CommunityEntity communityEntity =  commnunityService.view(id);
    model.addAttribute("board", communityEntity);

    // 저장 파일 가져오기
    List<BoardFileEntity> boardFiles = commnunityService.getFileList(id); // Entity로 변경하기
    model.addAttribute("boardFileList",boardFiles);

    // 댓글 가져오기
    // 댓글은 가져올 필요x
    // communityEntity를 보면
    // private List<CommunityReplyEntity> reply;
    // 이 부분을 통해 reply는 board 검색 시 그냥 가지고 오게 된다.
    // 그렇기 때문에 따로 가져오는 로직을 만들 필요가 없다.
    // 여기서 내가 말한 로직이란 service -> repository로 가는 로직을 말한다.
    List<CommunityReplyEntity> replies = communityEntity.getReply();
    // 각 댓글 내용 출력 model에 담기
    model.addAttribute("replies",replies);

    return "community/view";
}

 

댓글 수정(Update)

Controller

@PostMapping("/communityV/{boardId}/replyU")
public ResponseEntity<?> replayUpdate(@PathVariable int boardId, @RequestBody CommunityReplyEntity data, @AuthenticationPrincipal PrincipalDetails principalDetails){
    communityService.replyWrite(principalDetails.getUsername(),boardId,data);
    ResponseDto<Integer> responseDto = new ResponseDto<>(HttpStatus.OK.value(), 1);
    return new ResponseEntity<>(responseDto, HttpStatus.OK);
}

 

Service

@Transactional
public void replyWrite(String username, int boardId, CommunityReplyEntity requstReply){
    CommunityEntity communityEntity = commnunityRepository.findById(boardId).orElseThrow(()->{
        return new IllegalArgumentException("글 찾기 실패");
    });

    requstReply.setUsername(username);
    requstReply.setCBbs(communityEntity);

    communityReplyRepository.save(requstReply);
}

 

댓글 삭제(Delete)

Controller

@PostMapping("/communityV/{boardId}/replyD")
public ResponseEntity<?> replayDelete(@PathVariable int boardId, @RequestBody CommunityReplyEntity data, @AuthenticationPrincipal PrincipalDetails principalDetails){
    communityService.replyDelete(data.getId());
    ResponseDto<Integer> responseDto = new ResponseDto<>(HttpStatus.OK.value(), 1);
    return new ResponseEntity<>(responseDto, HttpStatus.OK);
}

 

Service

@Transactional
public void replyDelete(int id){
    communityReplyRepository.deleteById(id);
}

 

블로그의 정보

Hello 춘기's world

볼빵빵오춘기

활동하기