반응형
댓글 작성 기능은 두가지 방법이 있다.
1. 댓글 테이블을 따로 만들지 않는 방법
2. 댓글 테이블을 따로 만드는방법
이번 포스팅에서는 댓글 테이블을 따로 만들지 않는 방법을 이용한다.
댓글 테이블을 따로 만들지 않는 법
댓글 테이블을 따로 만들지 않는 방법은 댓글도 게시글처럼 올릴 수 있도록 하고 원글번호랑 연결하여 댓글이 원글번호에서만 나오도록 하는 방법이다.
1. 원글번호 객체 추가 private int parent
먼저 기본 보드 Vo에 private int parent;를 추가한다. parent는 댓글에서 원글번호를 알 수 있도록 나타내주는 변수이다.
2. 생성자, getter, setter 선언
이미 만들어진 board의 기능들까지 수정할 필요 없도록 parent 를 포함한 새로운 생성자를 추가한다.
public class BoardVo {
private int num;
private String writer;
private Date date;
private String title;
private String content;
private int parent; //원글 번호
public BoardVo(int num, String writer, Date date, String title, String content,int parent) {
super();
this.num = num;
this.writer = writer;
this.date = date;
this.title = title;
this.content = content;
this.parent = parent;
public int getParent() {
return parent;
}
public void setParent(int parent) {
this.parent = parent;
}
}
3. DAO , SERVICE 추가
원글을 제외한 원글과 연결되는 댓글을 모두검색하는 dao 를 추가한다.
parent 번호에 따른 검색 결과가 여러개 나올 수 있으니 ArrayList 에 담는다.
//댓글 검색
public ArrayList<BoardVo> selectReps (int parent){
dbconn = DBConnect.getInstance();
String sql = "select * from board where parent=? order by num desc";
ArrayList<BoardVo> list = new ArrayList<BoardVo>();
Connection conn = dbconn.conn();
try {
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, parent);
ResultSet rs = pstmt.executeQuery();
while(rs.next()) {
list.add(new BoardVo(rs.getInt(1),rs.getString(2),rs.getDate(3),rs.getString(4),rs.getString(5)));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return list;
}
//댓글 검색 메소드 추가
public ArrayList<BoardVo> getReps(int parent){
return dao.selectReps(parent);
}
4. detail.jsp 에 댓글 폼 추가
댓글 폼을 detail.jsp에 추가한다. 즉, 현재 제작하고 있는 웹 페이지의 경로는 index → list → detail ( detail 안에서 수정, 삭제, 댓글작성)이다.
1 | <form name ="f"> 댓글 : <input type = "text" name = "content"> <input type ="hidden" name ="writer" value ="${sessionScope.loginId }"> <input type ="hidden" name ="title" value ="-->${vo.title }"> <input type ="hidden" name ="parent" value ="${vo.num }"> |
댓글폼 txt (작성) 버튼으로 나타나도록 한다. 원 글 정보는 같이 서블릿에 보내줘야하지만 사용자에게 보여줄 필요 없으므로 hidden 으로 숨긴다. title의 경우 원글과의 비교를 위해 앞에 --> 표시를 붙여준다. |
2 | <input type ="button" value = "작성" onclick="addrep()"> </form> |
버튼 클릭 시 addrep() 함수로 이동한다. |
<div id="reps"> <c:forEach var="rep" items="${reps }" > ${rep.content }(writer:${rep.writer })<br/> </c:forEach> |
div 공간. id 는 "reps"로 부여했다. ${reps} 에서 가져온 content, writer 값 을 하나씩 꺼낸다. |
<tr>
<th>댓글작성 </th>
<td>
<form name ="f">
댓글 : <input type = "text" name = "content">
<input type ="hidden" name ="writer" value ="${sessionScope.loginId }">
<input type ="hidden" name ="title" value ="-->${vo.title }">
<input type ="hidden" name ="parent" value ="${vo.num }">
<input type ="button" value = "작성" onclick="addrep()">
</form>
<div id="reps">
<c:forEach var="rep" items="${reps }" >
${rep.content }(writer:${rep.writer })<br/>
</c:forEach>
</div>
</td>
</tr>
5. addrep () 함수로 이동
3 | const xhttp = new XMLHttpRequest(); | XMLHttpRequest 객체 생성 |
19 | xhttp.onload = function(){ let txt = xhttp.responseText; let html = ''; |
서버에서 값을 가지고 왔을 때 실행되는 함수 xhttp.onload 이다 |
20 | let arr = JSON.parse(txt); | 댓글이 여러개일 확률이 높아 대괄호로 받아올 것을 예측할 수 있다. 즉, 대괄호를 파싱해준다. |
21 | for (let obj of arr){ html += obj.content+"(writer:"+obj.writer+")<br/>"; } |
for문으로 값을 html에 담아준다. (짐을 하나씩 풀어준다고 생각) |
22 | let res = document.getElementById("reps"); |
id가 reps인 공간을 불러온다. |
23 | res.innerHTML = html; } |
불러온 공간에 html의 사잇값을 읽어와 보여준다. |
4 | let param = "parent=" + f.parent.value +"&title="+f.title.value + "&writer="+f.writer.value+ "&content="+f.content.value ; | 받아온 parent, title, writer 작성된 content 값을 변수 param에 담음 |
5 | xhttp.open("POST", "${pageContext.request.contextPath}/board/add" ); | 데이터 값 전송 경로 & 방식 설정 /board/add 로 전송 |
6 | xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); | 전송 데이터 형식 지정 (HTML 폼 데이터 전송 형식) |
7 | xhttp.send(param); | param에 담은 값 전송 |
function addrep(){
const xhttp = new XMLHttpRequest();
xhttp.onload = function(){
let txt = xhttp.responseText;
let html = '';
let arr = JSON.parse(txt);
for (let obj of arr){
html += obj.content+"(writer:"+obj.writer+")<br/>";
}
let res = document.getElementById("reps");
res.innerHTML = html;
}
let param = "parent=" + f.parent.value +"&title="+f.title.value + "&writer="+f.writer.value+ "&content="+f.content.value ;
xhttp.open("POST", "${pageContext.request.contextPath}/board/add" );
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send(param);
}
6. /board/add 서블릿 (Post) 이동
8 | String writer = request.getParameter("writer"); String title = request.getParameter("title"); String content = request.getParameter("content"); |
addrep에서 보내준 parent, title, writer 값을 받아온다. |
9 | int parent = 0; |
parent 선언 및 초기화, 의미는 원글일 때만 이 값을 유지한다는 것이다. |
10 | String p = request.getParameter("parent"); | detail.jsp 의 parent 값을 String p에 받아온다. |
11 | if(p!=null) { parent = Integer.parseInt(p); } |
p = null -> 원글 작성 p = not null -> 댓글 p가 값이 있을 때, String p를 int 로 변환해서 parent 에 담는다. 댓글일 때만 parent 가 0에서 변경된다. |
12 | BoardVo vo = new BoardVo(0,writer,null,title,content, parent); | 새로운 보드를 만들어 |
13 | BoardService service = new BoardService (); service.addboard(vo); |
보드 서비스 생성 후 보드에 추가한다. |
댓글과 원글을 구분해야한다. | ||
14 | //댓글 리스트 보여줌 if(p != null) { ArrayList<BoardVo> reps = service.getReps(parent); |
p 값이 있으면 댓글이기 때문에, p 값이 있을 때 서비스 메소드를 호출해 댓글을 검색한다. 검색 결과를 ArrayList reps 에 담는다. |
15 | JSONArray arr = new JSONArray(); | JSONArray 생성 (배열에 담으려고 선언한다) |
16 | for(BoardVo x:reps) { JSONObject obj = new JSONObject(); obj.put("content",x.getContent()); obj.put("writer", x.getWriter()); arr.add(obj); } |
검색된 결과를 list 형태로 reps에 넣었기 때문에 이것을 x에 넣어 하나씩 꺼내준다. // 객체 생성 {} // {"content":"aaa"} // {"content":"aaa", "writer":"ggg"} // [{"content":"aaa", "writer":"ggg"}] |
17 | String txt = arr.toJSONString(); |
JSON을 String으로 변환해서 변수 txt에 넣어준다. |
18 | response.getWriter().append(txt); } |
jsp로 txt를 담아서 detail.jsp에 다시 보내준다. |
5. addrep() 함수의 xhttp.onload 함수로 이동한다. | ||
else { response.sendRedirect(request.getContextPath()+"/board/list"); } |
원글일 경우 글목록으로 이동한다. |
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
String writer = request.getParameter("writer");
String title = request.getParameter("title");
String content = request.getParameter("content");
int parent = 0;
String p = request.getParameter("parent");
if(p!=null) {
parent = Integer.parseInt(p);
}
BoardVo vo = new BoardVo(0,writer,null,title,content, parent);
System.out.println(vo);
BoardService service = new BoardService ();
service.addboard(vo);
//댓글 리스트 보여줌
if(p != null) {
ArrayList<BoardVo> reps = service.getReps(parent);
JSONArray arr = new JSONArray();
for(BoardVo x:reps) {
JSONObject obj = new JSONObject();
obj.put("content",x.getContent());
obj.put("writer", x.getWriter());
arr.add(obj);
}
String txt = arr.toJSONString();
response.getWriter().append(txt);
}else {
response.sendRedirect(request.getContextPath()+"/board/list");
}
}
Oracle DB에 댓글은 이와 같은 형태로 나타난다.
반응형