Mvc 게시판 리스트 - Mvc gesipan liseuteu

1. 게시판 설계도를 그리시오(MVC 패턴을 이용한 전개)

Mvc 게시판 리스트 - Mvc gesipan liseuteu

1-1. Model

  • Model의 정의: 클라이언트에 의한 요청을 받는 영역으로 Controller 및 View 모두 데이터를 넘긴다.
  • Web Browser: Front Controller(서블릿)에게 요청(Request)을 한다.
  • Front Controller: Controller 영역으로 요청받은 데이터를 넘기거나 응답 데이터를 View 영역으로 넘긴다.

1-2. View

  • View의 정의: Front Controller에게 데이터를 응답(Response)받아 실제 화면에 구현할 수 있는 영역이다.
  • UI View: 유저와 접근하는 곳으로 서버 페이지(JSP)와 같은 문서에 의해 만들어지며 Controller 영역에서 정의된 기능들을 통해 Front Controller에게 응답받아 구현할 수 있다.

1-3. Controller

  • Controller의 정의: Model에게 받은 요청정보를 통해 게시판에 구현할 수 있는 기능(Create, Read, Update, Delete)들을 구현 및 제공한다.
  • Command: Front Controller 객체에게 데이터를 요청받은 것을 각 목적(CLUD)에 맞게 저장(Setter)한 후 DAO에 있는 각 메소드의 파라미터를 담아 전송한다. 이때, Command 객체는 인터페이스를 구축하여 만든 틀을 기반으로 사전에 implements하여 운용한다.
  • DTO(Data Transfer Object): DB에 있는 각 컬럼(Column)들을 정의한 객체 DAO에 전송(Transfer)한다.
  • DAO(Data Access Object): 여러 Command와 DTO들의 요청 정보들을 받는 객체 DB와 매개체(JDBC)를 통해 접근하여 CRUD의 기반이 되는 기능들을 구현한다.

2. DB 관련하여 아래를 정리하시오.

  1. 게시판 DB 설계(특히 댓글관련 컬럼)
  2. list 뽑아내는 sql
  3. 댓글 달기 위한 sql
  4. 수정 sql
  5. 게시판 글 insert sql

2-1. 게시판 DB 설계

: 통상적인 게시판 테이블의 컬럼들은 다음과 같다.

BID      NOT NULL NUMBER(4)     
BNAME             VARCHAR2(20)  
BTITLE            VARCHAR2(100) 
BCONTENT          VARCHAR2(300) 
BDATE             DATE          
BHIT              NUMBER(4)     
BGROUP            NUMBER(4)     
BSTEP             NUMBER(4)     
BINDENT           NUMBER(4)  
Mvc 게시판 리스트 - Mvc gesipan liseuteu
  • BID: 글 번호에 해당되는 컬럼으로 개체 무결성(Entity Integrity)에 의해 NULL값을 허용하지 않는다. 이후 최근 게시글에 따라 위로 올라가끔 DAO에서 적용한다.
  • BNAME: 글쓴이에 해당되는 컬럼이다.
  • BTITLE: 글 제목에 해당되는 컬럼이다.
  • BCONTENT: 글 내용에 해당되는 컬럼이다.
  • BDATE: 글을 쓴 날짜에 해당되는 컬럼이다. 리얼타임을 기준으로 추후에 DAO에서 적용한다.
  • BHIT: 조회수에 해당되는 컬럼이다.
  • BGROUP: 한 게시글 단위를 지칭하는 컬럼이다.
  • Mvc 게시판 리스트 - Mvc gesipan liseuteu
  • BSTEP: 답글을 쓰고나서 게시판 리스트에 있는 해당 게시글에 달려 있게하는 컬럼이다. 답글을 쓸수록 카운팅 하게끔 하며 우선순위에 따라 최근 답글은 위로 올라오게 하고 다답글도 해당 답글밑에 이와 같이 적용한다.
  • BINDENT: 답글이 달릴떄 해당 게시글을 들여쓰기 하여 표시하게끔 하는 컬럼이다. 게시글, 답글, 다답글에 따라 계층(LEVEL)을 나눈다.

2-2. list 뽑아내는 sql

SELECT bId, bName, bTitle, bContent, bDate, bHit, bGroup, bStep, bIndent
FROM mvc_board
ORDER BY bGroup DESC, bStep ASC; -- 게시글 정렬(답글이 달려도 원본글이 우선으로!)

2-3. 댓글 달기 위한 sql

-- INSERT하여 답글을 게시물에 추가한다
INSERT INTO mvc_board (bId, bName, bTitle, bContent, bGroup, bStep, bIndent)
VALUES (mvc_board_seq.nextval, ?, ?, ?, ?, ?, ?); -- INSERT로 답변을 게시물에 추가한다

-- UPDATE하여 답글 형태를 구현한다
UPDATE mvc_board
SET bStep = bStep + 1 -- 답변줄을 하나 추가한다
WHERE bGroup = ? -- 해당 게시글 그룹에 해당되어
	AND bStep > ?; -- 추가할 답변 수가 기존 답변줄의 수보다 더 적다는 조건하에
	
-- SELECT하여 답글을 가져온다
SELECT *
FROM mvc_board
WHERE bId = ?; -- 해당 bId 값을 조건으로 SELECT하기

2-4. 수정 sql

UPDATE mvc_board
SET bName = ?, bTitle = ?, bContent = ?
WHERE bId = ?; -- 해당 게시글 정보를 UPDATE하기

2-5. 게시판 글 inset sql

INSERT INTO mvc_board (bId, bName, bTitle, bContent, bHit, bGroup, bStep, bIndent)
VALUES (mvc_board_seq.nextval, ?, ?, ?, 0, mvc_board_seq.currval, 0, 0 ); -- 해당 게시글 정보를 Insert하기

3. Servlet 에서 forward 방법은?

: RequestDispatcher 객체를 이용하여 해당 getRequestDispatcher() 메소드를 이용한다.

// 액션 메소드
private void actionDo(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	System.out.println("actionDo");
		
	request.setCharacterEncoding("UTF-8");
		
	String viewPage = null;
	BCommand command = null;
		
	// uri 요청
	String uri = request.getRequestURI();
	// 경로 요청
	String conPath = request.getContextPath();
 
	// 요청한 경로를 본 길이만큼 자른다.(서블릿내 매핑한 것으로)
	String com = uri.substring(conPath.length());
		
	// 요청했던 데이터들을 콘솔에 출력
	System.out.println(uri);
	System.out.println(conPath);
	System.out.println(com);
		
	// 해당 경로가 본 서블릿 매핑 경로와 일치할경우
	if (com.equals("/list.do")) { 
		command = new BListCommand(); // 커맨드 리스트 객체에 담는다	
		command.execute(request, response); // 요청 및 응답 객체를 담아 커맨드 리스트를 실행한다	
		viewPage = "list.jsp"; // Controller -> View로 응답한다
	} else if(com.equals("/content_view.do")) {
		command = new BContentCommand();
		command.execute(request, response);
		viewPage = "content_view.jsp"; // 글내용 페이지로 간다
	} else if(com.equals("/write_view.do")) {
		viewPage = "write_view.jsp"; // 글쓰기 페이지로 바로 간다
	} else if(com.equals("/write.do")) {
		command = new BWriteCommand();
		command.execute(request, response);
		viewPage = "list.do"; // 글쓰기가 완료되면 list페이지로 간다
	} else if(com.equals("/delete.do")) {
		command = new BDeleteCommand();
		command.execute(request, response);
		viewPage = "list.do"; // 삭제가 완료되면 list페이지로 이동한다
	} else if(com.equals("/modify.do")) {
		command = new BModifyCommand();
		command.execute(request, response);
		viewPage = "list.do"; // 수정이 완료되면 list페이지로 이동한다
	} else if(com.equals("/reply_view.do")) {
		command = new BReplyViewCommand();
		command.execute(request, response);
		viewPage = "reply_view.jsp"; // 답변 페이지로 바로 간다
	} else if(com.equals("/reply.do")) {
		command = new BReplyCommand();
		command.execute(request, response);
		viewPage = "list.do"; // 답변이 완료되면 list.do페이지로 이동한다
	}
		
	// 디스패쳐 객체로 viewPage를 담아 요청한다.
	// 클라이언트가 요청하면서 전송한 데이터를 그대로 유지할 수 있다.
	RequestDispatcher dispatcher = request.getRequestDispatcher(viewPage);
	// 인증이 완료되면 포워딩을 한다.
	dispatcher.forward(request, response);
}

4. 아래 쿼리를 푸시오

  1. 급여(SAL)가 평균 급여보다 많고 이름(ENAME)에 T가 들어가는 사원과 동일한 부서(DEPTNO)에 소속되는 모든 사원의 사원 번호, 이름 및 급여를 출력하라.
  2. 근무지(LOC)가 DALLAS인 직원 중 직업(JOB)이 같은 사원의 이름,부서이름, 및 급여를 출력하시오

4-1. 1번 쿼리문

SELECT ename, sal
FROM emp
WHERE sal > (SELECT AVG(SAL) FROM emp) AND
      deptno IN (SELECT deptno FROM emp WHERE ename LIKE '%T%');

4-2. 2번 쿼리문

SELECT e.ename, d.dname, e.sal, e.job, d.loc
FROM dept d, emp e
WHERE d.deptno = e.deptno AND 
    e.job IN (SELECT loc
             FROM dept
             WHERE loc = 'DALLAS'); -- NOT FOUNDED!
-- DALLAS에서 근무하는 직원들의 직업을 조회하면 제각각 다름을 알 수 있다.
SELECT e.ename, d.dname, e.sal, e.job, d.loc
FROM dept d, emp e
WHERE d.deptno = e.deptno AND 
    d.loc = 'DALLAS';