Code view - Board
-
MVC Diagram
MVC다이어그램을 통한 기본 구조 이해
각각의 역할에 맡는 기능만 수행하게 해야 한다. (유지보수 / Java코드분리로 원활한 수정을 위함)
View
에서는JSTL
과EL (Expression Language)
만을 사용하여 페이지 처리한다.Controller
(Servlet)는 리퀘스트의 전달과Model
에서 보내오는 페이지이름만을 컨트롤한다.Model
(Service)은 DAO의 쿼리문 의외의 모든 부분을 담당한다.DB Connect
/DB Close
/DB Commit
/DB Rollback
포함 -
Data Base
Oracle SQL을 사용했다.
보드 테이블
CREATE TABLE BOARD ( NUM NUMBER(4) PRIMARY KEY, WRITER VARCHAR2(20), EMAIL VARCHAR2(30), SUBJECT VARCHAR2(100), PASSWD VARCHAR2(20), REG_DATE DATE DEFAULT SYSDATE, READCOUNT NUMBER(4) DEFAULT 0, REF NUMBER(4), RE_STEP NUMBER(4), RE_LEVEL NUMBER(4), CONTENT VARCHAR2(4000), IP VARCHAR2(20) );
-
Model
Service
에서 담당하는 역할은Controller
부터Request
를 받아와DAO
에서 일을 시키며 처리한 결과를 보여줄 Page명만Controller
로 전달한다. 계산이 필요한 부분들은Service
에서 처리한다.Service
/DAO
/DTO
모두 POJO : Model에 속한다. -
View
보여지는 page 부분을 담당한다.
JSTL
/EL
을 사용하며 Java 코드 분리를 통해 유지보수를 수월하게 만들어 준다.Model
의Service
로부터 데이터들을 받고 보여준다. 속성을 이용하여 JSP 페이지 간 값을 전달한다.Service
의 단건조회 데이터 저장request.setAttribute("ONELIST", boardDto); request.setAttribute("PAGENO", nPageNo);
content.jsp
에서 EL을 사용해 데이터 뷰<tr height="30"> <td align= "center" width="125" bgcolor="<%=value_c %>">글번호</td> <td align= "center" width="125" align="center"> ${ONELIST.num}</td> <td align="center" width="125" bgcolor="<%=value_c%>"> 조회수</td> <td align="center" width="125" align="center"> ${ONELIST.readcount}</td> </tr> <tr height="30"> <td align ="center" width="125" bgcolor="<%=value_c%>">작성자</td> <td align ="center" width="125" align="center"> ${ONELIST.writer}</td> <td align="center" width="125" bgcolor="<%=value_c%>"> 작성일</td> <td align="center" width="125" align="center"> ${ONELIST.reg_date}</td> </tr> <tr height="30"> <td align="center" width="125" bgcolor="<%=value_c%>">글제목</td> <td align="center" width="375" align="center" colspan="3"> ${ONELIST.subject}</td> </tr> <tr> <td align="center" width="125" bgcolor="<%=value_c%>">글내용</td> <td align="left" width="375" colspan="3"> <pre>${ONELIST.content}</pre></td> </tr>
주의할 점은 View에서 View페이지 전달은 MVC가 성립되지 않는다는 점이다.
글쓰기 페이지로 이동할 때에도 Cotroller를 통해서 이동한다.
<table> <tr> <td align="right" bgcolor="<%=value_c %>"> <a href="/Myjsp/BoardCtrl?cmd=insert_Be">글쓰기</a> </td> </tr> </table>
-
Controller
WAS로부터
Request
를 받고 어떤 페이지의 데이터를 처리할 것인지, 어떤 서비스 기능을 이용할 것인지 결정하는 곳이다.말그대로
Controller
이며 어떠한 기능적인 측면, 처리부분은 하지않고Forward
로 페이지 핸들링만 담당한다.쿼리스트링을 이용해 페이지간 구분이 가능하다.
Controller
에서 파라미터를 cmd로 받은뒤 cmd의 값으로 어떤 서비스의 기능을 이용할건지 결정String cmd = request.getParameter("cmd"); if("sltMul".equals(cmd)) //전체조회 { try { viewPage = svc.ArtiList(request, response); } catch(Throwable e) { throw new ServletException(e); } } else if("sltOne".equals(cmd)) //단건조회 { try { viewPage = svc.artiListOne(request, response); } catch(Throwable e) { throw new ServletException(e); } }
Controller
로 보내는View
에서의 주소는 무조건Controller
를 통해서만 이동<tr height="30"> <td colspan="4" bgcolor="<%=value_c%>" align="right"> <input type="button" value="글수정" onclick="document.location.href='/Myjsp/BoardCtrl?cmd=update_Be&num=${ONELIST.num}&pageNum=${PAGENO}'"> <input type="button" value="글삭제" onclick="document.location.href='/Myjsp/BoardCtrl?cmd=delete_Be&num=${ONELIST.num}&pageNum=${PAGENO}'"> <input type="button" value="답글쓰기" onclick="document.location.href='/Myjsp/BoardCtrl?cmd=insert_Be&num=${param.num}&ref=${ONELIST.ref}&re_step=${ONELIST.re_step} &re_level=${ONELIST.re_level}'"> <input type="button" value="글목록" onclick="document.location.href='/Myjsp/BoardCtrl?cmd=sltMul&pageNum=${PAGENO}'"> <!-- 글목록으로 되돌아가기 이전페이지 --> </td> </tr>
-
댓글
댓글(REF)은 글의 글번호(Primary Key)를 값으로 가진다. 부모글의 그룹핑이라고 생각하면 이해하기 쉽다.
RE_STEP은 댓글의 순번으로 부모글에서 댓글이 달릴 경우 RE_STEP의 값은 가장 최근의 값을 제외하고 이외의 댓글들은 +1씩 증가시킨다. RE_LEVEL은 같은 층의 댓글들을 그룹핑한다. 댓글에 댓글이 달릴 경우 기존댓글에 +1 처리한다. 현재의 작업 방법은 댓글이 달릴때마다 모든 댓글들의 RE_STEP이 증가하는 방식이므로 추후 다른 방법으로 해결해보려한다.
DAO
에서의REF
처리 BoardDAO.java//댓글ref처리 public int insertArtiRe(BoardDTO dto) throws Exception { String updateNum = "UPDATE BOARD SET RE_STEP = RE_STEP + 1" + "WHERE REF = ? AND RE_STEP > ?"; int cnt = 0; pstmt = con.prepareStatement(updateNum); pstmt.setInt(1, dto.getRef()); pstmt.setInt(2, dto.getRe_step()); cnt = pstmt.executeUpdate(); BoardCommon.dbClose(pstmt); return cnt; }
Service
의insert
메소드 BoardSvc.javaint ref = Integer.parseInt((String)request.getParameter("ref")); int re_step = Integer.parseInt((String)request.getParameter("re_step")); int re_level = Integer.parseInt((String)request.getParameter("re_level")); int number = 0; number = boardDao.maxArtiNum(); //맥스글번호 구하기 if(num != 0) { boardDto = new BoardDTO(); boardDto.setRef(ref); //댓글일경우 ref 업뎃처리 boardDto.setRe_step(re_step); boardDao.insertArtiRe(boardDto); re_step = re_step + 1; re_level = re_level + 1; } else { ref = number; re_step = 0; re_level = 0; }
-
어려웠던 점
기본적으로 insert / update / delete 부분은 문제될게 없었다. 하지만 댓글같은 경우 댓글이 1개만 달리고 끝이 나는게 아니라 댓글에 댓글에 댓글이 달리듯이 무한정으로 달릴수 있다는 점에서 고민이 되었다. 교수님께서 말씀하시길 댓글이 1000만건이 달리게 되면 (그럴일은 없겟지만...) 모든 댓글들을 DB에서 처리 할때 무리가 갈것이다. 댓글 관리의 좀더 효율적인 방안을 생각해봐야 할것이다.
-
실행