📅2024. 02.19 48일차
Db 테이블 구현
# reply 테이블 생성
CREATE TABLE reply (
id INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
regDate DATETIME NOT NULL,
updateDate DATETIME NOT NULL,
memberId INT(10) UNSIGNED NOT NULL,
relTypeCode CHAR(50) NOT NULL COMMENT '관련 데이터 타입 코드',
relId INT(10) NOT NULL COMMENT '관련 데이터 번호',
`body`TEXT NOT NULL
);
# reply 테이블에 좋아요 관련 컬럼 추가
ALTER TABLE reply ADD COLUMN goodReactionPoint INT(10) UNSIGNED NOT NULL DEFAULT 0;
ALTER TABLE reply ADD COLUMN badReactionPoint INT(10) UNSIGNED NOT NULL DEFAULT 0;
# update join -> 기존 게시물의 good,bad RP 값을 RP 테이블에서 가져온 데이터로 채운다
UPDATE reply AS R
INNER JOIN (
SELECT RP.relTypeCode,RP.relId,
SUM(IF(RP.point > 0, RP.point, 0)) AS goodReactionPoint,
SUM(IF(RP.point < 0, RP.point * -1, 0)) AS badReactionPoint
FROM reactionPoint AS RP
GROUP BY RP.relTypeCode, RP.relId
) AS RP_SUM
ON R.id = RP_SUM.relId
SET R.goodReactionPoint = RP_SUM.goodReactionPoint,
R.badReactionPoint = RP_SUM.badReactionPoint;
댓글 작성 폼
로그인 했을 경우에만 작성 가능하게 처리
<c if test: > 활용
<c:if test="${rq.isLogined() }">
<form action="../reply/doWrite" method="POST" onsubmit="ReplyWrite__submit(this); return false;">
<input type="hidden" name="relTypeCode" value="article" />
<input type="hidden" name="relId" value="${article.id }" />
<table class="write-box table-box-1" border="1">
<tbody>
<tr>
<th>내용</th>
<td>
<textarea class="input input-bordered input-primary w-full max-w-xs" autocomplete="off" type="text"
placeholder="내용을 입력해주세요" name="body"> </textarea>
</td>
</tr>
<tr>
<th></th>
<td>
<input class="btn btn-outline btn-info" type="submit" value="댓글 작성" />
</td>
</tr>
</tbody>
</table>
</form>
</c:if>
<c:if test="${!rq.isLogined() }">
<a class="btn btn-outline btn-ghost" href="../member/login">LOGIN</a> 하고 댓글 써
</c:if>
댓글 작성기능
댓글 작성란에 아무것도 입력 안했을 시에 대한 처리
@RequestMapping("/usr/reply/doWrite")
@ResponseBody
public String doWrite(HttpServletRequest req, String relTypeCode, int relId, String body) {
Rq rq = (Rq) req.getAttribute("rq");
if (Ut.isNullOrEmpty(relTypeCode)) {
return Ut.jsHistoryBack("F-1", "내용을 입력해주세요");
}
if (Ut.isEmpty(relId)) {
return Ut.jsHistoryBack("F-2", "내용을 입력해주세요");
}
if (Ut.isNullOrEmpty(body)) {
return Ut.jsHistoryBack("F-3", "내용을 입력해주세요");
}
ResultData<Integer> writeReplyRd = replyService.writeReply(rq.getLoginedMemberId(), relTypeCode, relId, body);
int id = (int) writeReplyRd.getData1();
return Ut.jsReplace(writeReplyRd.getResultCode(), writeReplyRd.getMsg(), "../article/detail?id=" + relId);
}
댓글 리스팅
<div class="mx-auto">
<h2>댓글 리스트(${repliesCount })</h2>
<table class="table-box-1 table" border="1">
<colgroup>
<col style="width: 5%" />
<col style="width: 10%" />
<col style="width: 60%" />
<col style="width: 10%" />
<col style="width: 5%" />
<col style="width: 5%" />
</colgroup>
<thead>
<tr>
<th>번호</th>
<th>날짜</th>
<th>내용</th>
<th>작성자</th>
<th>좋아요</th>
<th>싫어요</th>
</tr>
</thead>
<tbody>
<c:forEach var="reply" items="${replies }">
<tr class="hover">
<td>${reply.id }</td>
<td>${reply.regDate.substring(0,10) }</td>
<td>${reply.body }</td>
<td>${reply.extra__writer }</td>
<td><button id="likeButton" class="btn btn-outline btn-sm btn-success" onclick="doGoodReaction(${reply.id})">👍 ${reply.goodReactionPoint }</button></td>
<td><button id="DislikeButton" class="btn btn-outline btn-sm btn-error" onclick="doBadReaction(${reply.id})">👎 ${reply.badReactionPoint }</button></td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
리스트에서 게시글마다 댓글 수 보이도록
SELECT A.*, M.nickname AS extra__writer, IFNULL(COUNT(R.id),0) AS extra__repliesCnt
FROM article AS A
INNER JOIN `member` AS M
ON A.memberId = M.id
LEFT JOIN `reply` AS R
ON A.id = R.relId
WHERE 1
GROUP BY A.id
ORDER BY A.id DESC
@Select("""
<script>
SELECT A.*, M.nickname AS extra__writer, IFNULL(COUNT(R.id),0) AS extra__repliesCnt
FROM article AS A
INNER JOIN `member` AS M
ON A.memberId = M.id
LEFT JOIN `reply` AS R
ON A.id = R.relId
WHERE 1
<if test="boardId != 0">
AND A.boardId = #{boardId}
</if>
<if test="searchKeyword != ''">
<choose>
<when test="searchKeywordTypeCode == 'title'">
AND A.title LIKE CONCAT('%',#{searchKeyword},'%')
</when>
<when test="searchKeywordTypeCode == 'body'">
AND A.body LIKE CONCAT('%',#{searchKeyword},'%')
</when>
<otherwise>
AND A.title LIKE CONCAT('%',#{searchKeyword},'%')
OR A.body LIKE CONCAT('%',#{searchKeyword},'%')
</otherwise>
</choose>
</if>
GROUP BY A.id
ORDER BY A.id DESC
<if test="limitFrom >= 0 ">
LIMIT #{limitFrom}, #{limitTake}
</if>
</script>
""")
public List<Article> getForPrintArticles(int boardId, int limitFrom, int limitTake, String searchKeywordTypeCode,
String searchKeyword);