- 게시판 답글 기능
게시판의 답글 기능은 DB에서 게시판을 생성할 때 기본적인 컬럼에 추가적으로 답글 기능과 관련된 컬럼들을 함께 만들어주어야 한다.
*기본 컬럼 - num(번호), title(글제목), contents(글내용), writer(글쓴이), hit(조회수 - 없어도 됨), date(작성날짜 - 없어도 됨)
*답글 기능 관련 컬럼
- ref : 원글과 원글에 대한 답글을 하나의 그룹으로 묶어줌, 원글의 번호를 참조하여 설정됨
- step : 원글과 답글들을 한 그룹으로 묶었을 때 해당 그룹 내의 순서
- depth : 답글이 원글에 대한 답글일 수 있고, 답글에 대한 답글일 수 있는데 이 때 이러한 답글의 계층을 나타냄
위 내용을 바탕으로 DB에서 게시판을 생성하였다면, 프론트와 백엔드 부분을 차례로 만들면 된다.
1) 프론트엔드 부분
- 게시판 리스트를 불러오는 view
게시판 테이블의 바디 영역에 답글인 경우 구분하여 표시할 수 있도록 코드를 작성한다. ' '는 공백 문자열로, 들여쓰기처럼 보이도록 넣어주었다.
<tr>
<th scope="row">${qnaVO.num}</th>
<td id="re">
<c:catch>
<c:forEach begin="1" end="${qnaVO.depth}"> RE:</c:forEach>
</c:catch>
<a href="./select?num=${qnaVO.num}">${qnaVO.title}</a>
</td>
<td>${qnaVO.writer}</td>
<td>${qnaVO.hit}</td>
<td>${qnaVO.date}</td>
</tr>
- 글 선택 시 보이는 view
글 선택 시에 하단에 수정, 삭제 등의 기능과 함께 답변쓰기를 누르면 원글에 대한 답변을 쓸 수 있도록 하는 태그도 추가해준다. a 링크 태그로 처리하였다.
<a href="./reply?num=${qnaVO.num}">답변쓰기</a>
- 답글 작성 view
앞에서 '답변쓰기' 클릭 시 나타는 답변 작성 view를 새로 만들어준다. Spring mvc에서 제공하는 form 태그를 이용하였으며, 작성한 내용은 완료 버튼을 클릭하면 서버로 전송된다. 여기서 가장 상단의 num은 부모글, 즉 원글의 번호를 가져온 것이다. 이것이 다음 ref, step, depth를 정하는 데에 기준이 된다.
<form:form modelAttribute="qnaVO" enctype="multipart/form-data">
<form:hidden path="num"/> <!-- 부모글번호 -->
<div id="title">
<form:input path="title" id="title" placeholder="제목을 입력하세요" />
</div>
<div id="contents">
<form:input path="contents" id="summernote" />
</div>
<button id="submit" type="submit" class="btn btn-secondary btn-lg">작성완료</button>
</form:form>
2) 백엔드 부분
- Mapper.xml
sql 쿼리문을 만들어준다. mybatis를 이용하였다. 쿼리문은 총 3개를 만드는데, mybatis의 경우 업데이트 쿼리문 실행 시 충돌이 일어날 수 있어 세 번째 쿼리문을 꼭 작성해주고, 여기서 이용한 MySQL에서도 edit-preferences-SQL Editor에서 safe update란에 체크란을 꼭 해지해주어야 한다.
<insert id="setReplyInsert" parameterType="QnaVO" useGeneratedKeys="true" keyProperty="num">
insert into destudyqna (num, title, contents, writer, hit, date, ref, step, depth)
values (null, #{title}, #{contents}, #{writer}, 0, now(),
(select R.ref from (select * from destudyqna where num=#{num}) R),
(select S.step+1 from (select * from destudyqna where num=#{num}) S),
(select D.depth+1 from (select * from destudyqna where num=#{num}) D)
)
</insert>
<update id="setReplyUpdate" parameterType="QnaVO">
update destudyqna set step=step+1
where ref=(select R.ref from (select ref from destudyqna where num=#{num}) R)
and
step > (select S.step from (select step from destudyqna where num=#{num}) S)
</update>
<update id="setRefUpdate" parameterType="QnaVO">
update destudyqna set ref=#{num} where num=#{num}
</update>
위 쿼리문에서 ref, step, depth는 각각 아래와 같이 정해진다.
- ref : 원글의 num(번호)를 가져온다.
- step : 1) 원글의 ref와 같은 ref 글들을 찾는다 -> 2) 원글의 step보다 큰 수의 step을 가진 글이 있는지 찾고, 있다면 각각 step에 +1을 해준다. -> 3) 답글에는 원글의 step에서 +1을 한 값을 넣는다.
- depth : 원글의 depth에서 +1한 값을 넣는다.
- Repository
Mapper.xml의 쿼리문을 실행할 수 있도록 3개의 메서드를 작성한다.
public int setReplyInsert(QnaVO qnaVO)throws Exception;
public int setReplyUpdate(QnaVO qnaVO)throws Exception;
public int setRefUpdate(QnaVO qnaVO)throws Exception;
- Service
기존에 작성해두었던 일반 글쓰기의 코드에 setRefUpdate 메서드 구문을 추가한다. 그리고 답글 기능과 관련된 메서드 구문도 추가해준다.
//글쓰기
public int setInsert(QnaVO qnaVO) throws Exception {
int result = qnaRepository.setInsert(qnaVO);
result = qnaRepository.setRefUpdate(qnaVO);
return result;
}
//답글
public int setReplyInsert(QnaVO qnaVO) throws Exception {
int result = qnaRepository.setReplyUpdate(qnaVO);
result = qnaRepository.setReplyInsert(qnaVO);
return result;
}
- Controller
최종적으로 Mapper.xml -> Repository -> Service에서 실행된 메서드의 결과를 받아 view로 보내주는 코드를 작성한다(매개변수 중 BindingResult의 경우 추후 파일업로드 기능 구현을 위해 미리 넣어주었다. 그리고 우선 오버로딩을 위해서도 필요하다!).
@GetMapping("reply")
public String reply(@ModelAttribute QnaVO qnaVO) throws Exception{
return "qna/reply";
}
@PostMapping("reply")
public String reply(QnaVO qnaVO, BindingResult bindingResult) throws Exception {
int result = qnaService.setReplyInsert(qnaVO);
return "redirect:../qna/list";
}
'TIL' 카테고리의 다른 글
<자바스크립트 Javascript> 선택지 만들기(심리테스트 알고리즘 이용) (1) (0) | 2021.12.02 |
---|---|
<스프링 부트 Spring boot> 인터셉터(Interceptor)로 관리자, 일반회원 구분 기능 구현 (0) | 2021.12.01 |
<스프링 Spring> 페이징 + 검색 기능 구현 (0) | 2021.11.29 |
<스프링 부트 Spring boot> 게시판 구현 - 글 목록 조회 (0) | 2021.11.28 |
<자바 Java> 추상클래스 (0) | 2021.11.27 |