[홈페이지 제작] 홈페이지 댓글 만들기 3 - 댓글 목록 보기

Feb 20, 2024
[홈페이지 제작] 홈페이지 댓글 만들기 3 - 댓글 목록 보기
 

1. 쿼리 작성

 
더미데이터 추가
insert into reply_tb(comment, board_id, user_id, created_at) values('댓글1', 1, 1, now()); insert into reply_tb(comment, board_id, user_id, created_at) values('댓글2', 4, 1, now()); insert into reply_tb(comment, board_id, user_id, created_at) values('댓글3', 4, 1, now()); insert into reply_tb(comment, board_id, user_id, created_at) values('댓글4', 4, 2, now());
 
select rt.id, rt.user_id, rt.comment, ut.username from reply_tb rt inner join user_tb ut on rt.user_id = ut.id where rt.board_id = 4 ;
 
notion image
 
게시글에 작성된 댓글을 표시한다. 화면에는 username 과 comment 만 출력하지만 댓글의 작성자 여부를 확인하기 위해 id 와 userId 도 함께 받아온다.
 
 

2. DTO 만들기

 
댓글 테이블에서 받은 데이터를 boardResponse 에 DTO로 받는다. 댓글을 게시글에 출력해야 하기 때문이다.
 
package shop.mtcoding.blog.board; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpSession; import lombok.Data; import shop.mtcoding.blog.user.User; import java.util.List; public class BoardResponse { @Data public static class DetailDTO { private Integer id; private String title; private String content; private Integer userId; private String username; @Data public static class ReplyDTO { private Integer id; private Integer userId; private String username; private String comment; public ReplyDTO(Object[] ob,User sessionUser) { this.id = (Integer) ob[0]; this.userId = (Integer) ob[1]; this.comment = (String) ob[2]; this.username = (String) ob[3]; } } }
 
notion image
 
기존 BoardResponse 는 DB에서 조회된 게시글 테이블을 받는 DTO였다. 여기에 댓글 테이블을 받는 DTO를 합친다.
 
💡
ReplyDTO를 컬렉션 형태로 받는 이유는 하나의 게시글에 여러 개의 댓글이 표현되어야 하기 때문이다. 컬렉션 형태로 mustache 에 전달하면 반복문의 형태가 된다.
notion image
 

3. 컨트롤러

 
@GetMapping("/board/{id}") public String detail(@PathVariable int id,HttpServletRequest request) { User sessionUser = (User) session.getAttribute("sessionUser"); // 세션의 id if(sessionUser!=null){ // 세션의 값이 null 이 아니어야 로그인 상태 if(boardUserId==sessionUser.getId()){ 세션 id = 게시글 작성 id 비교 owner = true; // 일치하면 권한 활성 } request.setAttribute("owner",owner); // View 에 전달 } //DB데이터를 DetailDTO에 받음 BoardResponse.DetailDTO boardDTO = boardRepository.findByIdWithUser(id); //DB데이터를 ReplyDTO에 받음 List<BoardResponse.ReplyDTO> replyDTOList = replyRepository.findByBoardId(id,sessionUser); //게시글 데이터를 view 로 가져감 request.setAttribute("board", boardDTO); //댓글 데이터를 view 로 가져감 request.setAttribute("replyList",replyDTOList); return "board/detail"; }
 
댓글은 게시글에 출력되기 때문에 boardController 의 상세보기 메서드에 작성한다.
레파지토리에 게시판 번호와 세션의 회원ID를 가져간다 세션 회원 ID는 추후에 댓글의 작성자 여부를 확인할 때 사용한다.
 

4. 레파지토리

 
public List<BoardResponse.ReplyDTO> findByBoardId(int boardId, User sessionUser) { Query query = em.createNativeQuery("select rt.id, rt.user_id, rt.comment, ut.username from reply_tb rt \n" + "inner join user_tb ut on rt.user_id = ut.id where rt.board_id = ?"); query.setParameter(1,boardId); List<Object[]> obs = query.getResultList(); //DB에서 받은 정보를 ReplyDTO에 로그인한 User 정보와 함께 받는다. return obs.stream().map(ob -> new BoardResponse.ReplyDTO(ob,sessionUser)).toList(); }
 
게시글 번호로 테이블을 조회한다.
💡
Stream API 를 통해 ReplyDTO 로 받은 테이블 데이터를 오브젝트 배열 형태로 담는다.

5. View

 
<!-- 댓글아이템 --> {{#replyList}} <div class="list-group-item d-flex justify-content-between align-items-center"> <div class="d-flex"> <div class="px-1 me-1 bg-primary text-white rounded">{{username}}</div> <div>{{comment}}</div> </div> <form action="/reply/1/delete" method="post"> <button class="btn">🗑</button> </form> </div> {{/replyList}}
 
💡
replyList 는 컬렉션 형태기 때문에 {{#replyList}} {{/replyList}} 는 mustache 에서 반복문 형태가 된다. 따라서 댓글 테이블이 여러개라면 반복문을 돌면서 출력한다.
 
 
notion image
 
4번 게시글에 댓글이 정상적으로 출력된다.
 
notion image
 
게시글이 없는 댓글은 출력되지 않는다.
 
notion image
 
댓글을 작성하면 리스트에 출력이 된다.
Share article

{CODE-RYU};