detail.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="../layout/header.jsp"%>
<div class="container">
<button class="btn btn-secondary" onclick="history.back()">돌아가기</button>
<c:if test="${board.user.id == principal.user.id}">
<!-- 글 작성자만 삭제가능 -->
<a href="/board/${board.id }/updateForm" class="btn btn-warning">수정</a>
<button id="btn-delete" class="btn btn-danger">삭제</button>
</c:if>
<br>
<br>
<div>
글 번호 : <span id="id"><i>${board.id } </i></span> 작성자 : <span><i>${board.user.userName } </i></span>
</div>
<br>
<div>
<h3>${ board.title }</h3>
</div>
<hr>
<div>
<div>${board.content }</div>
</div>
<hr>
<!-- 댓글 작성 영역 -->
<div class="card">
<div class="card-body">
<textarea class="form-control" rows="2"></textarea>
</div>
<div class="card-footer">
<button class="btn btn-primary">등록</button>
</div>
</div>
<br>
<!-- 댓글 리스트 영역 -->
<div class="card">
<div class="card-header">댓글 리스트</div>
<ul id="reply--box" class="list-group"> <!-- 내가 만든 클래스는 작대기 두개 -->
<li id="reply--1" class="list-group-item d-flex justify-content-between">
<div>댓글 내용입니다!!</div>
<div class="d-flex">
<div class="font-italic">작성자 : lwj </div>
<button class="badge">삭제</button>
</div>
</li>
</ul>
</div>
</div>
<script src="/js/board.js"></script>
<%@ include file="../layout/footer.jsp"%>
샘플 DB만들기
insert into reply(content, boardId, userId, createDate)
values('첫번째 댓글', 1, 2, now());
insert into reply(content, boardId, userId, createDate)
values('두번째 댓글', 1, 2, now());
insert into reply(content, boardId, userId, createDate)
values('세번째 댓글', 1, 2, now());
select * from reply;
commit;
ReplyRepository생성
package com.lwj.blog.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.lwj.blog.model.Reply;
public interface ReplyRepository extends JpaRepository<Reply, Integer>{
}
board.java
이 보드객체는 reply list를 갖고있다. 즉 게시물 상세조회 했을때 자동으로 reply를 가져온다.
@OneToMany(mappedBy = "board", fetch = FetchType.EAGER)
// mappedBy 연관관계의 주인이 아니다 (난 FK가 아니에요) DB에 칼럼을 만들지 마세요.
// "board"는 Reply 테이블의 board 필드명
// @JoinColumn(name = "replyId") // 이걸 적는다면 FK가 생기는데 단순히 join을 할 뿐이지 FK를 만들 필요는 없다.
// 게다가 여러개의 댓글이 있을경우 1,2,3,4.. 처럼 콤마로 구분돼어 들어간다. 1NF(1정규화)가 깨진다.
private List<Reply> replys; // 하나의 글에는 여러개의 댓글이 가능하기 때문에 List 로 가져와야된다.
따라서 jsp에서 받아서 쓰기만 하면 된다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="../layout/header.jsp"%>
<div class="container">
<button class="btn btn-secondary" onclick="history.back()">돌아가기</button>
<c:if test="${board.user.id == principal.user.id}">
<!-- 글 작성자만 삭제가능 -->
<a href="/board/${board.id }/updateForm" class="btn btn-warning">수정</a>
<button id="btn-delete" class="btn btn-danger">삭제</button>
</c:if>
<br>
<br>
<div>
글 번호 : <span id="id"><i>${board.id } </i></span> 작성자 : <span><i>${board.user.userName } </i></span>
</div>
<br>
<div>
<h3>${ board.title }</h3>
</div>
<hr>
<div>
<div>${board.content }</div>
</div>
<hr>
<!-- 댓글 작성 영역 -->
<div class="card">
<div class="card-body">
<textarea class="form-control" rows="2"></textarea>
</div>
<div class="card-footer">
<button class="btn btn-primary">등록</button>
</div>
</div>
<br>
<!-- 댓글 리스트 영역 -->
<div class="card">
<div class="card-header">댓글 리스트</div>
<ul id="reply--box" class="list-group"> <!-- 내가 만든 클래스는 작대기 두개 -->
<c:forEach var="reply" items="${ board.replys }">
<li id="reply--1" class="list-group-item d-flex justify-content-between">
<div>${ reply.content }</div>
<div class="d-flex">
<div class="font-italic">작성자 : ${ reply.user.userName } </div>
<button class="badge">삭제</button>
</div>
</li>
</c:forEach>
</ul>
</div>
</div>
<script src="/js/board.js"></script>
<%@ include file="../layout/footer.jsp"%>
테스트
참고 유튜브 (메타코딩님 강의)
https://youtu.be/DjnMw07U1VI?si=G38WipoEsiws8-ZU