티스토리 뷰

read.html

<tr class="comment-row">
    <td colspan="6">
        <form class="comment-form" id="commentForm">
            <label class="label">
                <span hidden>댓글작성</span>
                <input class="--object-input" id="objectInput" maxlength="100" name="content"
                       placeholder="댓글을 입력해 주세요" type="text">
            </label>
            <input type="hidden" th:value="${article.getIndex()}" name="aid">
            <input class="--object-button" type="submit" value="작성">
        </form>
        <div class="comment-container" id="commentContainer">
            <div class="comment mine">
                <div class="head">
                    <span class="writer">관리자</span>
                    <span class="dt">2022-01-01 00:00:00</span>
                    <span class="spring"></span>
                    <span class="action-container">
                    <a class="action reply" href="#">
                        답글달기
                    </a>
                    <a class="action delete" href="#">
                        삭제
                    </a>
                </span>
                </div>
                <div class="body">1등</div>
            </div>
            <form class="reply-form">
                <label class="label">
                    <span hidden>답글작성</span>
                    <input class="--object-input" maxlength="100" name="content"
                           placeholder="답글을 입력해 주세요" type="text">
                </label>
                <input class="--object-button" type="submit" value="작성">
            </form>
            <div class="comment sub">
                <div class="head">
                    <span class="writer">누구</span>
                    <span class="dt">2022-01-01 00:00:00</span>
                    <span class="spring"></span>
                    <span class="action-container">
                    <a class="action reply" href="#">
                        답글달기
                    </a>
                    <a class="action delete" href="#">
                        삭제
                    </a>
                </span>
                </div>
                <div class="body">zz</div>
            </div>
            <div class="comment sub mine">
                <div class="head">
                    <span class="writer">누구</span>
                    <span class="dt">2022-01-01 00:00:00</span>
                    <span class="spring"></span>
                    <span class="action-container">
                    <a class="action reply" href="#">
                        답글달기
                    </a>
                    <a class="action delete" href="#">
                        삭제
                    </a>
                </span>
                </div>
                <div class="body">ss</div>
            </div>
        </div>
    </td>
</tr>

read.css

#commentForm {
    display: flex;
    flex-direction: row;
    align-items: stretch;
    justify-content: flex-start;

    margin-top: 0.5rem;
}

#commentForm > .label {
    flex: 1;
    margin-right: 0.5rem;
}

#objectInput {
    width: 92.5%;
}

#commentContainer {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    margin-top: 0.5rem;

}

#commentContainer .comment {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;

}

#commentContainer .comment > .head {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;

    background-color: rgb(128, 139, 150);
    color: rgb(255, 255, 255);
    font-size: 0.9rem;
    padding: 0.375rem 0.5rem;
    border-top-left-radius: 0.375rem;
    border-top-right-radius: 0.375rem;
}

#commentContainer .comment > .head > .dt {
    color: rgb(213, 216, 220);
    margin-left: 0.5rem;
}

#commentContainer .comment > .head > .spring {
    flex: 1;
}

#commentContainer .comment > .head > .action-container {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
}

#commentContainer .comment > .head > .action-container > .action {
    color: inherit;
    text-decoration: none;
}

#commentContainer .comment > .head > .action-container > .action:hover {
    text-decoration: none;
}

#commentContainer .comment > .head > .action-container > .action + .action {
    margin-left: 0.5rem;
}

#commentContainer .comment > .body {
    background-color: rgb(255, 255, 255);
    font-size: 1rem;
    padding: 0.75rem 1rem;
    border-bottom-left-radius: 0.375rem;
    border-bottom-right-radius: 0.375rem;
}

#commentContainer .reply-form {
    display: flex;
    flex-direction: row;
    align-items: stretch;
    justify-content: flex-start;
    margin-top: 0.5rem;
    margin-left: 5rem;
}

#commentContainer .reply-form > .label {
    flex: 1;
    margin-right: 0.5rem;
}

#commentContainer .comment.sub {
    margin-left: 5rem;
}

#commentContainer .comment.mine {
    background-color: rgb(26, 188, 156);
}

#commentContainer .comment.mine > .head {
    background-color: rgb(26, 188, 156);
}

#commentContainer > * + * {
    margin-top: 0.5rem;
}

BbsMapper.xml

<select id="selectCommentsByArticleIndex"
        resultType="dev.shlee.studymemberbbs.entities.bbs.CommentEntity">
    SELECT `index`         AS `index`,
           `comment_index` AS `commentIndex`,
           `user_email`    AS `userEmail`,
           `article_index` AS `articleIndex`,
           `content`       AS `content`,
           `written_on`    AS `writtenOn`
    FROM `study_bbs`.comments
    WHERE `article_index` = #{articleIndex}
    ORDER BY `index`
</select>

우선 댓글들을 화면에 불러와야 하기 때문에 comments테이블을 select 해준다. 

우선 댓글은 무수히 많이 달릴 수도 있기 때문에 배열을 사용해야 하는데 배열은 순서가 없다.

그러므로 ORDER BY `index`를 하여 index 순서대로 위치할 수 있도록 한다.


IBbsMapper.interface

CommentEntity[] selectCommentsByArticleIndex(@Param(value = "articleIndex") int articleIndex);

Service를 사용할 수 있도록 인터페이스에서 정의해준다. 


BbsService

public CommentEntity[] getComments(int articleIndex) {
    return this.bbsMapper.selectCommentsByArticleIndex(articleIndex); 
}

매개변수로 int articleIndex를 주어 articleIndex(aid) 값을 기준으로 가져온 값들을 return 해준다. 


BbsController

@RequestMapping(value = "comment",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public String getComment(@RequestParam(value = "aid") int articleIndex) {
    JSONArray responseArray = new JSONArray(); // 댓글이 많으니깐 배열로 받는다.
    CommentEntity[] comments = this.bbsService.getComments(articleIndex);
    //서비스에서 받아온 aid번호를 기준으로 select한 값들을 comments에 넣어주고 향상된 for문을 통해서 그 값들을 하나씩 추출한다.
    for (CommentEntity comment : comments) {
        JSONObject commentObject = new JSONObject(); 
        commentObject.put("index", comment.getIndex());
        commentObject.put("commentIndex", comment.getCommentIndex());
        commentObject.put("userEmail", comment.getUserEmail());
        commentObject.put("articleIndex", comment.getArticleIndex());
        commentObject.put("content", comment.getContent());
        commentObject.put("writtenOn", new SimpleDateFormat("yyy-MM-dd HH:mm:ss").format(comment.getWrittenOn()));
        //new SimpleDateFormat("형식").format([Date 타입 객체]) : [Date 타입 객체]가 가진 일시를 원하는 형식의 문자열로 만들어 반환한다.
        responseArray.put(commentObject); // 다 추출한 한 덩어리가 0 번째 인덱스로 들어가게 된다.
    }

    return responseArray.toString();
}

articleIndex(aid) 기준으로 값들을 가져와야 하기 때문에 매개 변수로 int articleIndex를 선언해준다. 

댓글은 많기 때문에 JSONArray를 사용하여 배열로 받아준다. 

향상된 for문을 사용하기 위해 CommentEntity [] comments를 생성해주고 comments의 값들을 하나씩 추출한다. 이때 comments의 값에는 articleIndex를 기준으로 가져온 값들이 담기게 된다. 

JSONObject commentObject = new JSONObject(); 를 통해 가져온 값들을 commentObject에 넣어준다.

그다음 reponseArray.put(commentObject)를 통해 배열에 담아주면 된다. 


read.js

const commentForm = window.document.getElementById('commentForm');
const commentContainer = window.document.getElementById('commentContainer');

const loadComments = () => {
    commentContainer.innerHTML = '';

    const url = new URL(window.location.href);
    const searchParams = url.searchParams;// ?뒤를 담당
    const aid =searchParams.get('aid');
    const xhr = new XMLHttpRequest();
    xhr.open('GET', `./comment?aid=${aid}`);
    xhr.onreadystatechange = () => {
        if (xhr.readyState === XMLHttpRequest.DONE) {
            if (xhr.status >= 200 && xhr.status < 300) {

            } else {
            }
        }
    };
    xhr.send();
};

밑의 사진처럼 댓글을 작성하였을 때 오른쪽 사진의 모습처럼 나와야 하므로 innerHTML을 사용한다. 

const url에 현재 페이지의 주소를 할당해 주고, const aid에는 현재 페이지 주소에서 aid값을 가져와 할당해 준다. 

예를 들어 50번 article_index를 가지는 게시물에 댓글을 달아야 하지만 article_index값을 모르거나 잘못 지정한다면 49번이나 51번 등 다른 게시물에 댓글을 작성하게 되는 상황이 발생하기 때문에 aid를 지정해 주어야 한다. 

xhr.open을 하는데 현재페이지의 주소에서 가져온 aid값을 가져와 페이지를 열 수 있도록 해준다. 

콘솔에 loadComments(); 입력하였을 때 전송되는 값

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2026/04   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
글 보관함