*아이디 중복 확인
memberEnrollForm.jsp (쿼리 무결성 적용 X)
👉🏻 중복확인 버튼에 onlick 속성 걸고, 하단에 script 구문 추가하기
// 중복 확인 버튼에 onclick 속성 걸기
<tr>
<td>* 아이디</td>
<td><input type="text" name="userId" maxlength="12" required></td>
<td><button type="button" onclick="idCheck();">중복확인</button></td>
<!-- 아이디 중복 확인은 나중에 AJAX 라는 기술을 배운 뒤 할 것 -->
</tr>
// form과 div까지 빠져나온 뒤 선언적 함수가 들어갈 script 구문 만들기
<script>
function idCheck() {
// 아이디를 입력하는 input 요소 객체
var $userId = $("#enroll-form input[name=userId]");
// name 속성이 userId인 요소가 menubar.jsp 에도 있기 때문에
// 확실하게 어디에 속해 있는 요소인지 잘 적어 둬야 함
$.ajax({
url : "idCheck.me",
data : {checkId : $userId.val()},
success : function() {
},
error : function() {
console.log("아이디 중복체크용 ajax 통신 실패!");
}
});
}
</script>
AjaxIdCheckController 서블릿 생성
👉🏻 url mapping: /idCheck.me
package com.kh.member.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.kh.member.model.service.MemberService;
/**
* Servlet implementation class AjaxIdCheckController
*/
@WebServlet("/idCheck.me")
public class AjaxIdCheckController extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public AjaxIdCheckController() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 요청 시 전달값 뽑기
// checkId: 검사하고자 하는 아이디
String checkId = request.getParameter("checkId"); // checkId라는 변수에 든 value값 뽑기
// 전달값을 서비스로 넘겨서 요청 처리 후 결과 받기
int count = new MemberService().idCheck(checkId); // 중복된 아이디가 있다면 1, 없다면 0
// 조건에 따른 응답 데이터 넘겨 주기
// => 응답 데이터 1개만 넘길 것이기 때문에 굳이 JSON을 쓰지 않아도 됨!
response.setContentType("text/html; charset=UTF-8");
if(count > 0) { // 이미 사용 중인 아이디가 있을 경우 => 사용 불가능 ("NNNNN")
response.getWriter().print("NNNNN");
} else { // 존재하는 아이디가 없을 경우 => 사용 가능 ("NNNNY")
response.getWriter().print("NNNNY");
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
MemberService
// 아이디 중복체크용 서비스
public int idCheck(String checkId) {
Connection conn = JDBCTemplate.getConnection();
int count = new MemberDao().idCheck(conn, checkId);
JDBCTemplate.close(conn);
return count;
}
MemberDao
public int idCheck(Connection conn, String checkId) {
// SELECT문 => ResultSet 객체 (숫자 하나)
int count = 0;
PreparedStatement pstmt = null;
ResultSet rset = null;
String sql = prop.getProperty("idCheck");
try {
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, checkId);
rset = pstmt.executeQuery();
if(rset.next()) {
count = rset.getInt("COUNT(*)");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCTemplate.close(rset);
JDBCTemplate.close(pstmt);
}
return count; // 중복된 아이디가 있다면 1, 없다면 0
}
member-mapper.xml
<entry key="idCheck">
SELECT COUNT(*)
FROM MEMBER
WHERE USER_ID = ?
</entry>
![](https://blog.kakaocdn.net/dn/dcElbs/btrPx1Is5IS/f9oVZCOFyWGkWWyYHSVuZ0/img.png)
이미 존재하는 아이디를 입력했을 때 뜨는 알림창
![](https://blog.kakaocdn.net/dn/bN63Ku/btrPxIa8bXC/mtGi7J6umBdgSkv5J1d5Dk/img.png)
중복되지 않는 아이디를 입력했을 때 뜨는 창
하지만!
아직은 중복체크만 했을 뿐 회원가입 버튼이 눌러지기 때문에
admin 등 이미 있는 계정을 중복확인 후 회원가입 버튼 누르면
회원가입 실패창 뜸
USER_ID는 PK라서 중복된 값이 들어갈 수 없는데 억지로 중복된 값을 넣으려고 했기 때문!
menubar.jsp (쿼리 무결성 적용)
👉🏻 방법1: 회원가입창 기본 비활성화 해 놓고 중복확인 시 사용가능한 아이디 확인 눌렀을 때 활성화시키기
👉🏻 변화가 있는 부분인 회원가입 버튼, 추가된 하단의 script 부분만 추가함
<div align="center">
<button type="submit" disabled>회원가입</button>
<button type="reset">초기화</button>
</div>
<br>
</form>
</div>
<script>
function idCheck() {
// 아이디를 입력하는 input 요소 객체
var $userId = $("#enroll-form input[name=userId]");
// name 속성이 userId인 요소가 menubar.jsp 에도 있기 때문에
// 확실하게 어디에 속해 있는 요소인지 잘 적어 둬야 함
$.ajax({
url : "idCheck.me",
data : {checkId : $userId.val()},
success : function(result) {
// result의 값은 "NNNNN" 또는 "NNNNY"가 담겨 있음
if(result == "NNNNN") { // 사용 불가
alert("이미 존재하거나 탈퇴한 회원의 아이디입니다.");
$userId.focus(); // 커서를 깜빡거림으로써 재입력 유도
} else {
if(confirm("사용 가능한 아이디입니다. 사용하시겠습니까?")) { // 사용하겠다
// 아이디 입력값 확정 => 다시 수정 못 하게 readonly 속성 추가
$userId.attr("readonly", true);
// 회원 가입 버튼 활성화
$("#enroll-form button[type=submit]").removeAttr("disabled");
} else { // 사용하지 않겠다
// 재입력 유도
$userId.focus();
}
}
},
error : function() {
console.log("아이디 중복체크용 ajax 통신 실패!");
}
});
}
</script>
👉🏻 방법2: 중복된 아이디를 입력 시 alert창 띄우고 아이디 창을 비워 버리기
👉🏻 방법 1에서 회원가입 disabled 속성 지우고 중복된 아이디 입력 시 alert창 띄우고 아이디 입력칸 초기화
그냥 내 생각이라 틀릴 수 잇음 근데 테스트 해 봤는데 잘되더라구요그럼된거아닌가,,
<div align="center">
<button type="submit">회원가입</button>
<button type="reset">초기화</button>
</div>
<br>
</form>
</div>
<script>
function idCheck() {
// 아이디를 입력하는 input 요소 객체
var $userId = $("#enroll-form input[name=userId]");
// name 속성이 userId인 요소가 menubar.jsp 에도 있기 때문에
// 확실하게 어디에 속해 있는 요소인지 잘 적어 둬야 함
$.ajax({
url : "idCheck.me",
data : {checkId : $userId.val()},
success : function(result) {
// result의 값은 "NNNNN" 또는 "NNNNY"가 담겨 있음
if(result == "NNNNN") { // 사용 불가
alert("이미 존재하거나 탈퇴한 회원의 아이디입니다.");
$userId.val(""); // 아이디 창 초기화
$userId.focus(); // 커서를 깜빡거림으로써 재입력 유도
} else {
if(confirm("사용 가능한 아이디입니다. 사용하시겠습니까?")) { // 사용하겠다
// 아이디 입력값 확정 => 다시 수정 못 하게 readonly 속성 추가
$userId.attr("readonly", true);
} else { // 사용하지 않겠다
// 재입력 유도
$userId.focus();
}
}
},
error : function() {
console.log("아이디 중복체크용 ajax 통신 실패!");
}
});
}
</script>
json-simple-1.1.1.jar
gson-2.8.2.jar
두 가지 .jar 파일을 WebContent\WEB-INF\lib 경로에 붙여넣기 후 진행!
*댓글 달기(정적 코딩 ver.)
오라클에 더미 데이터 먼저 만들기
👉🏻 게시글 번호와 회원 번호는 반드시 기존에 존재하던 번호로 확인 후 넣어 줘야 함!
INSERT INTO REPLY (REPLY_NO
, REPLY_CONTENT
, REF_BNO
, REPLY_WRITER)
VALUES (SEQ_RNO.NEXTVAL
, 'ㅋㅋㅋ꿀잼'
, 108
, 4);
INSERT INTO REPLY (REPLY_NO
, REPLY_CONTENT
, REF_BNO
, REPLY_WRITER)
VALUES (SEQ_RNO.NEXTVAL
, '노잼인데요'
, 108
, 3);
INSERT INTO REPLY (REPLY_NO
, REPLY_CONTENT
, REF_BNO
, REPLY_WRITER)
VALUES (SEQ_RNO.NEXTVAL
, 'ㅋㅋㄹㅇ'
, 108
, 2);
COMMIT;
Reply 클래스 생성
👉🏻 댓글 기능은 게시판 기능에 종속된 기능이므로 별도로 패키지를 만들지 않고 Board 내에 생성
package com.kh.board.model.vo;
public class Reply {
private int replyNo; // REPLY_NO NUMBER PRIMARY KEY,
private String replyContent; // REPLY_CONTENT VARCHAR2(400) NOT NULL,
private int refBoardNo; // REF_BNO NUMBER NOT NULL,
private String replyWriter; // REPLY_WRITER NUMBER NOT NULL,
private String createDate; // CREATE_DATE DATE DEFAULT SYSDATE NOT NULL,
private String status; // STATUS VARCHAR2(1) DEFAULT 'Y' CHECK (STATUS IN ('Y', 'N')),
public Reply() {
super();
}
public Reply(int replyNo, String replyContent, int refBoardNo, String replyWriter, String createDate, String status) {
super();
this.replyNo = replyNo;
this.replyContent = replyContent;
this.refBoardNo = refBoardNo;
this.replyWriter = replyWriter;
this.createDate = createDate;
this.status = status;
}
// 댓글 리스트 조회용 생성자
public Reply(int replyNo, String replyContent, String replyWriter, String createDate) {
super();
this.replyNo = replyNo;
this.replyContent = replyContent;
this.replyWriter = replyWriter;
this.createDate = createDate;
}
public int getReplyNo() {
return replyNo;
}
public void setReplyNo(int replyNo) {
this.replyNo = replyNo;
}
public String getReplyContent() {
return replyContent;
}
public void setReplyContent(String replyContent) {
this.replyContent = replyContent;
}
public int getRefBoardNo() {
return refBoardNo;
}
public void setRefBoardNo(int refBoardNo) {
this.refBoardNo = refBoardNo;
}
public String getReplyWriter() {
return replyWriter;
}
public void setReplyWriter(String replyWriter) {
this.replyWriter = replyWriter;
}
public String getCreateDate() {
return createDate;
}
public void setCreateDate(String createDate) {
this.createDate = createDate;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
@Override
public String toString() {
return "Reply [replyNo=" + replyNo + ", replyContent=" + replyContent + ", refBoardNo=" + refBoardNo
+ ", replyWriter=" + replyWriter + ", createDate=" + createDate + ", status=" + status + "]";
}
}
boardDetailView.jsp
👉🏻 댓글 부분만 발췌
<div id="reply-area">
<table border="1" align="center">
<thead>
<!-- 로그인이 되어 있을 경우 -->
<!--
<tr>
<th>댓글 작성</th>
<td>
<textarea id="" cols="50" rows="3" style="resize:none;"></textarea>
</td>
<td><button>댓글등록</button></td>
</tr>
-->
<!-- 로그인이 되어 있지 않은 경우 -->
<tr>
<th>댓글 작성</th>
<td>
<textarea id="" cols="50" rows="3" style="resize:none;" readonly>로그인 후 이용 가능한 서비스입니다.</textarea>
</td>
<td><button disabled>댓글등록</button></td>
</tr>
</thead>
<tbody>
<tr>
<td>admin</td>
<td>댓글 내용이 들어갈 자리~!</td>
<td>2022년 10월 22일</td>
</tr>
<tr>
<td>admin</td>
<td>댓글 내용이 들어갈 자리~!</td>
<td>2022년 10월 22일</td>
</tr>
</tbody>
</table>
<script>
$(function() {
selectReplyList();
});
function selectReplyList() {
$.ajax({
url : "rlist.bo",
data : {bno : <%= b.getBoardNo() %>},
success : function(list) {
console.log(list);
},
error : function() {
console.log("댓글리스트 조회용 ajax 통신 실패!");
}
});
}
</script>
<br>
<br>
</div>
</div>
</body>
</html>
AjaxReplyListController 서블릿 생성
👉🏻 url mapping: /rlist.bo
package com.kh.board.controller;
import java.io.IOException;
import java.util.ArrayList;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.gson.Gson;
import com.kh.board.model.service.BoardService;
import com.kh.board.model.vo.Reply;
/**
* Servlet implementation class AjaxReplyListController
*/
@WebServlet("/rlist.bo")
public class AjaxReplyListController extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public AjaxReplyListController() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 게시글 번호 뽑기
int boardNo = Integer.parseInt(request.getParameter("bno")); // request.getParameter()는 기본이 문자열이기 때문에 파싱 해 줌
// 게시글 번호를 서비스로 전달하면서 요청 처리 후 결과 받기
ArrayList<Reply> list = new BoardService().selectReplyList(boardNo);
// GSON을 이용해서 응답 => ArrayList를 자바 스크립트의 배열 형태로 변환
response.setContentType("application/json; charset=UTF-8");
new Gson().toJson(list, response.getWriter()); // 응답할 데이터, 데이터를 넘길 통로 객체를 차례로 넘김
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
BoardService
public ArrayList<Reply> selectReplyList(int boardNo) {
Connection conn = getConnection();
ArrayList<Reply> list = new BoardDao().selectReplyList(conn, boardNo);
close(conn);
return list;
}
BoardDao
public ArrayList<Reply> selectReplyList(Connection conn, int boardNo) {
// SELECT문 => ResultSet 객체(여러 행 조회)
ArrayList<Reply> list = new ArrayList<>();
PreparedStatement pstmt = null;
ResultSet rset = null;
String sql = prop.getProperty("selectReplyList");
try {
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, boardNo);
rset = pstmt.executeQuery();
while(rset.next()) {
list.add(new Reply(rset.getInt("REPLY_NO"),
rset.getString("REPLY_CONTENT"),
rset.getString("USER_ID"),
rset.getString("CREATE_DATE")));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(rset);
close(pstmt);
}
return list;
}
board-mapper.xml
<entry key="selectReplyList">
SELECT REPLY_NO
, REPLY_CONTENT
, USER_ID
, TO_CHAR(CREATE_DATE, 'YY/MM/DD HH:MI:SS') CREATE_DATE
FROM REPLY R
JOIN MEMBER ON (REPLY_WRITER = USER_NO)
WHERE REF_BNO = ?
AND R.STATUS = 'Y'
ORDER BY REPLY_NO DESC
</entry>
*댓글 달기(동적 코딩 ver.)
boardDetailView.jsp
👉🏻 기존 하드 코딩 댓글 내용 주석 처리 후 script 구문 추가!
<!-- 우선 화면 구현만! 기능구현은 AJAX 배우고 나서 할 것! -->
<div id="reply-area">
<table border="1" align="center">
<thead>
<!-- 로그인이 되어 있을 경우 -->
<!--
<tr>
<th>댓글 작성</th>
<td>
<textarea id="" cols="50" rows="3" style="resize:none;"></textarea>
</td>
<td><button>댓글등록</button></td>
</tr>
-->
<!-- 로그인이 되어 있지 않은 경우 -->
<tr>
<th>댓글 작성</th>
<td>
<textarea id="" cols="50" rows="3" style="resize:none;" readonly>로그인 후 이용 가능한 서비스입니다.</textarea>
</td>
<td><button disabled>댓글등록</button></td>
</tr>
</thead>
<tbody>
<!--
<tr>
<td>admin</td>
<td>댓글 내용이 들어갈 자리~!</td>
<td>2022년 10월 22일</td>
</tr>
<tr>
<td>admin</td>
<td>댓글 내용이 들어갈 자리~!</td>
<td>2022년 10월 22일</td>
</tr>
-->
</tbody>
</table>
<script>
$(function() {
selectReplyList();
});
function selectReplyList() {
$.ajax({
url : "rlist.bo",
data : {bno : <%= b.getBoardNo() %>},
success : function(list) {
// console.log(list);
var result = "";
for(var i in list) { // i: 0, 1, 2, 3, ..., 마지막 인덱스값
result += "<tr>"
+ "<td>" + list[i].replyWriter + "</td>"
+ "<td>" + list[i].replyContent + "</td>"
+ "<td>" + list[i].createDate + "</td>"
+ "</tr>";
}
$("#reply-area tbody").html(result);
},
error : function() {
console.log("댓글리스트 조회용 ajax 통신 실패!");
}
});
}
</script>
*댓글 작성
boardDetailView.jsp
👉🏻 textarea id값 부여, 댓글 등록 버튼에 onclick 속성, script 태그의 insertReply 메소드 추가
👉🏻 추가된 부분 기준으로 발췌
<div id="reply-area">
<table border="1" align="center">
<thead>
<% if(loginUser != null) { %>
<!-- 로그인이 되어 있을 경우 -->
<tr>
<th>댓글 작성</th>
<td>
<textarea id="replyContent" cols="50" rows="3" style="resize:none;"></textarea>
</td>
<td><button onclick="insertReply();">댓글등록</button></td>
</tr>
<% } else { %>
<!-- 로그인이 되어 있지 않은 경우 -->
<tr>
<th>댓글 작성</th>
<td>
<textarea id="" cols="50" rows="3" style="resize:none;" readonly>로그인 후 이용 가능한 서비스입니다.</textarea>
</td>
<td><button disabled>댓글등록</button></td>
</tr>
<% } %>
</thead>
<tbody>
<!--
<tr>
<td>admin</td>
<td>댓글 내용이 들어갈 자리~!</td>
<td>2022년 10월 22일</td>
</tr>
<tr>
<td>admin</td>
<td>댓글 내용이 들어갈 자리~!</td>
<td>2022년 10월 22일</td>
</tr>
-->
</tbody>
</table>
<script>
$(function() {
selectReplyList();
});
function insertReply() {
$.ajax({
url : "rinsert.bo",
data : {
content : $("#replyContent").val(),
bno : <%= b.getBoardNo() %>
},
type : "post",
success : function(result) {
// result에 댓글 작성 성공 시 1, 실패 시 0이 담겨 있을 것
if(result > 0) { // 성공
// 갱신된 댓글 리스트를 다시 조회
selectReplyList();
// textarea 초기화 => 새로고침 하지 않아도 한 것 같은 효과
$("#replyContent").val("");
} else { // 실패
alert("댓글 작성에 실패했습니다.")
}
},
error : function() {
console.log("댓글 작성용 ajax 통신 실패!");
}
});
}
function selectReplyList() {
$.ajax({
url : "rlist.bo",
data : {bno : <%= b.getBoardNo() %>},
success : function(list) {
// console.log(list);
var result = "";
for(var i in list) { // i: 0, 1, 2, 3, ..., 마지막 인덱스값
result += "<tr>"
+ "<td>" + list[i].replyWriter + "</td>"
+ "<td>" + list[i].replyContent + "</td>"
+ "<td>" + list[i].createDate + "</td>"
+ "</tr>";
}
$("#reply-area tbody").html(result);
},
error : function() {
console.log("댓글리스트 조회용 ajax 통신 실패!");
}
});
}
</script>
AjaxReplyInsertController 서블릿 생성
👉🏻 url mapping: /rinsert.bo
package com.kh.board.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.kh.board.model.service.BoardService;
import com.kh.board.model.vo.Reply;
import com.kh.member.model.vo.Member;
/**
* Servlet implementation class AjaxReplyInsertController
*/
@WebServlet("/rinsert.bo")
public class AjaxReplyInsertController extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public AjaxReplyInsertController() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 요청 시 전달값 먼저 뽑기
// content : 댓글 내용
String replyContent = request.getParameter("content");
// bno : 참조 게시글 번호
int boardNo = Integer.parseInt(request.getParameter("bno"));
// 추가적으로 필요한 데이터: 댓글 작성자 (지금 로그인한 회원)의 회원번호
int userNo = ((Member)request.getSession().getAttribute("loginUser")).getUserNo();
// Object 타입을 Member로 강제 형변환 후 getter 메소드 이용해서 회원 번호만 뽑기
// Reply 타입으로 가공
Reply r = new Reply();
r.setReplyContent(replyContent);
r.setRefBoardNo(boardNo);
r.setReplyWriter(String.valueOf(userNo));
int result = new BoardService().insertReply(r); // 댓글 작성 성공 시 1, 실패 시 0
// 응답 데이터 보내기
response.setContentType("text/html; charset=UTF-8");
response.getWriter().print(result);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
BoardService
public int insertReply(Reply r) {
Connection conn = getConnection();
int result = new BoardDao().insertReply(conn, r);
if(result > 0) {
commit(conn);
} else {
rollback(conn);
}
close(conn);
return result;
}
BoardDao
public int insertReply(Connection conn, Reply r) {
// INSERT문 => int (처리된 행의 개수)
int result = 0;
PreparedStatement pstmt = null;
String sql = prop.getProperty("insertReply");
try {
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, r.getReplyContent());
pstmt.setInt(2, r.getRefBoardNo());
pstmt.setInt(3, Integer.parseInt(r.getReplyWriter()));
result = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(pstmt);
}
return result;
}
board-mapper.xml
<entry key="insertReply">
INSERT INTO REPLY (REPLY_NO
, REPLY_CONTENT
, REF_BNO
, REPLY_WRITER)
VALUES (SEQ_RNO.NEXTVAL
, ?
, ?
, ?)
</entry>
(+) 댓글 실시간 조회
BoardDetailView.jsp
👉🏻 script 최상단에 페이지가 로드 된 후에 한 번 실행하도록 했던 $(function() { }) 구문 내에 작성!
👉🏻 $(function() { 여기 }
$(function() {
selectReplyList();
// 댓글 실시간 조회 기능을 추가하고 싶다면? (== 단톡방처럼)
// 1초 간격마다 selectReplyList 함수 실행
setInterval(selectReplyList, 1000);
});