본문 바로가기
Spring Framework

step ref 사용하지 않는 스프링 댓글 처리 - 연결리스트 활용

by 자유코딩 2018. 7. 27.

스프링 댓글처리 코드를 올립니다. 동영상 강의도 녹화했습니다.

 

제 유튜브 채널에서 보실 수 있습니다.

 

https://www.youtube.com/watch?v=AFqX2-F2mwM

 

컨트롤러 코드

 

1
2
3
4
5
6
7
8
9
10
11
12
13
    @RequestMapping(value="/freeboard_info")//자유게시판 글 1개 보기
    public String freeboard_info(HttpServletRequest request) {
        FreeboardInfoService freeboardInfoService = new FreeboardInfoService();
        Map<String,Object> map = freeboardInfoService.service(request, mapper);
        String page = (String) map.get("page");
        FreeboardVO freeboardVO = (FreeboardVO)map.get("freeboardVO");
        request.setAttribute("freeboardVO", freeboardVO);
        List<Freeboard_CommentVO> freeboardCommentList = (LinkedList<Freeboard_CommentVO>)map.get("freeboardCommentList");
        
        request.setAttribute("freeboardCommentList", freeboardCommentList);
        
        return page;
    }
cs

 

 

서비스 클래스 코드

 

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package com.simple.service;
 
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
 
import javax.servlet.http.HttpServletRequest;
 
import com.simple.dao.Mapper;
import com.simple.domain.FreeboardVO;
import com.simple.domain.Freeboard_CommentVO;
 
public class FreeboardInfoService implements Service {
    
    @Override
    public Map<String, Object> service(HttpServletRequest request, Mapper mapper) {
        
        int freeboard_id = Integer.parseInt(request.getParameter("freeboard_id"));//글 번호 가져오기
        FreeboardVO freeboardVO = mapper.freeboardInfo(freeboard_id);
        List<Freeboard_CommentVO> CommentList = mapper.freeboardCommentList(freeboard_id);
        
        LinkedList<Freeboard_CommentVO> CommentLinkedList = new LinkedList<Freeboard_CommentVO>();
        
        for (int i = 0; i < CommentList.size(); i++) {
            if (CommentList.get(i).getFreeboard_comment_level()==0) {//레벨 0 댓글들 먼저 연결리스트에 보관한다.
                CommentLinkedList.add(CommentList.get(i));//1개씩 추가한다.
            }
        }
        
        for (int i = 0; i < CommentList.size(); i++) {//댓글 전체를 돌면서
            if (CommentList.get(i).getFreeboard_comment_level()!=0) {//먼저 레벨이 0이 아닌것들을 거름
                //0이 아닌 것들을 걸렀다. -> 댓글에 달린 댓글들을 의미한다.
                int origin_id = CommentList.get(i).getFreeboard_comment_origin_id();
                for (int j = 0; j < CommentLinkedList.size(); j++) {
                    if (CommentLinkedList.get(j).getFreeboard_comment_id() == origin_id) {
                        CommentLinkedList.add(j+1, CommentList.get(i));
                    }
                }
            }             
        }
        
        Map<String,Object> map = new HashMap<>();
        map.put("page""freeboard_info");
        map.put("freeboardVO", freeboardVO);
        map.put("freeboardCommentList", CommentLinkedList);
        
        return map;
    }
}
cs

 

 

연결리스트를 사용해서 구현했습니다. 처음엔 C#처럼 람다식을 활용하려고 했습니다. 자바는 연결리스트를 쓰는게 코드가 더 간소할 것 같습니다.

 

데이터 베이스 구조

 

 

데이터 베이스는 이렇게 생겼습니다.

 

step ref 이런 것들은 없습니다. 몇 단계 참조되는 댓글인지를 의미하는 level 이 있습니다.

 

freeboard_comment_origin_id 는 어떤 댓글을 부모 댓글로 하는지를 의미합니다.

 

 

jsp 페이지 소스코드

 

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>자유게시판 글보기</title>
 
<script
    src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
 
<script type="text/javascript">
    function checkValue() {
 
    }
    function checkValueDefault(){
        
    }
    function viewForm(target_comment){
        var comment_id = "comment_"+target_comment;
        $("#"+comment_id).toggle();
    }
 
</script>
</head>
<body>
    <div>
        <table style="border-style: solid;">
            <tbody>
                <tr>
                    <td>글 제목 :</td>
                    <td>${freeboardVO.freeboard_title}</td>
                </tr>
                <tr>
                    <td>작성자 :</td>
                    <td>${freeboardVO.freeboard_writer}</td>
                </tr>
                <tr>
                    <td>작성 날짜:</td>
                    <td>${freeboardVO.freeboard_date}</td>
                </tr>
                <tr>
                    <td style="text-align: center;" colspan="2">글 내용</td>
                </tr>
                <tr>
                    <td colspan="2">${freeboardVO.freeboard_content}</td>
                </tr>
                <tr>
                    <td>첨부파일 :</td>
                    <td>${freeboardVO.freeboard_fileName}</td>
                </tr>
            </tbody>
        </table>
        <pre> </pre>
        <input type="button"
            onclick="location.href='<%=request.getContextPath()%>/freeboardList?pagenum=1&contentnum=10'"
            value="목록으로">
    </div>
    <br />
    <div>
        <c:choose>
            <c:when test="${empty freeboardCommentList}">
                <h5>댓글이 없습니다.</h5>
                <br />
                <h5>댓글 달기</h5>
                <form name="commentWriteDefault"
                    action="<%=request.getContextPath()%>/freebaord_comment_write_request">
                    작성자 <input type="text" name="writer"> <br />
                    비밀번호<input type="password" name="password"> <br />
                    <textarea name="content"></textarea>
                    <input type="button" onclick="checkValueDefault()" /> <br />
                </form>
            </c:when>
            <c:otherwise>
                <c:forEach items="${freeboardCommentList}" var="k">
                    <c:if test="${k.freeboard_comment_level ne 0}">
                        <c:forEach begin="1" end="${k.freeboard_comment_level}"
                            var="level">&nbsp;&nbsp;&nbsp;</c:forEach>
                    </c:if>
                    <span>${k.freeboard_comment_content} -
                        ${k.freeboard_comment_writer} <input type="button" value="댓글달기" onclick="viewForm(${k.freeboard_comment_id})"></span>
                    <div>
                        <form name="commentWrite" id="comment_${k.freeboard_comment_id}"
                            action="<%=request.getContextPath()%>/freebaord_comment_write_request" style="display: none;">
                            작성자 <input type="text" name="writer" > <br />
                            비밀번호<input type="password" name="password" >
                            <br />
                            <textarea name="content" ></textarea>
                            <input type="button" onclick="checkValue(${k.freeboard_comment_id})" value="쓰기"/> <br />
                        </form>
                    </div>
                    <br />
 
                </c:forEach>
 
            </c:otherwise>
        </c:choose>
 
    </div>
 
</body>
</html>
cs

 

댓글 처리는 방법이 많습니다.

 

step ref 방식을 사용하면 댓글이 10000만개면 10000개를 모두 업데이트 해야 됩니다.

 

글 번호를 100씩 증가시키는 방법도 있습니다.

 

100

200

300

400

......

 

100과 200사이에 댓글의 댓글을 삽입하는 방식입니다. 댓글을 100개 이상 달 수 없습니다.

 

Oracle DB에서는 Connect By 를 활용하는 방법도 있습니다.

 

MySQL에서는 Connect By가 안됩니다.

 

여러 DB에서 모두 사용할만한 방법을 생각해봤습니다.

 

연결리스트를 활용했습니다.

댓글