MVC란?
MVC에서 View와 Controller가 같이 있는 형태
규모가 비교적 작은 형태
Model2에 비해서 작업속도는 빠르지만 유지보수에 대한 문제가 생길수도 있다.
MVC에서 Model, View, Controller가 모두 모듈화(부품화) 되어있는 형태
규모가 비교적 큰 형태이며 전통적인 MVC패턴의 형태
모듈화가 잘 되어있어 유지보수에 좋다.
테이블 생성
create table mvc_board(
bId number(4) primary key, //id값
bName varchar2(20), //작성자 이름
bTitle varchar2(100), //게시글 제목
bContent varchar2(300), //게시글 내용
bDate Date default sysdate, //작성날짜
bHit number(4) default 0, //조회수
bGroup number(4), // 게시글에대한
bStep number(4), // 답글을 달때
bIndent number(4) // 사용되는 필드들
)
id값 자동증가를 위한 sequence 생성
create sequence mvc_board_seq;
테스트를 위한 데이터 삽입
insert into mvc_boar (bId, bName, bTitle, bContent, bHit, bGroup, bStep, bIndent)
values (mvc_board_seq.nextval, 'abcd', 'is title', 'is content', 0, mvc_board_seq.currval, 0, 0)
클라이언트의 요청을 받는 역할을 하는 Controller를 만든다.
코드보기//doGet, doPost 둘 중 하나의 요청을 받으면 actionDo 메서드로 넘겨준다.
private void actionDo(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
System.out.println("actionDo");
request.setCharacterEncoding("utf-8"); //한글 깨짐 방지
String viewPage = null; //어떤 뷰를 보여줄 것인지 결정
BCommand command = null; //어떤 로직을 수행할 것인지 결정
String uri = request.getRequestURI(); //uri를 얻어옴
String conPath = request.getContextPath(); //contextPath를 얻어옴
String com = uri.substring(conPath.length()); //요청받은 파일명을 얻기위한 작업?
if(com.equals("/write_view.do")) { //글 작성화면을 요청받으면
viewPage = "write_view.jsp"; //viewPage에 파일명이 담겨서 dispatcher로 포워딩 해줌
} else if(com.equals("/write.do")) { //작성하는 화면이면
command = new BWriteCommand(); //객체를 실행
command.execute(request, response); //execute를 실행
viewPage = "list.do"; //viewPage로 화면을 보여줌
} else if(com.equals("/list.do")) {
command = new BListCommand();
command.execute(request, response);
viewPage = "list.jsp";
} else if(com.equals("/content_view.do")) {
command = new BContentCommand();
command.execute(request, response);
viewPage = "content_view.jsp";
} else if(com.equals("/modify.do")) {
command = new BModifyCommand();
command.execute(request, response);
viewPage = "list.do";
} else if(com.equals("/delete.do")) {
command = new BDeleteCommand();
command.execute(request, response);
viewPage = "list.do";
} 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";
}
//viewPage의 값이 jsp로 끝나면 UI화면을 띄워주고
//do로 끝나면 커맨드를 생성하여 적절한 로직을 실행 후 list.do로 포워딩한다.
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPage);
dispatcher.forward(request, response);
}
Command 인터페이스를 만들고 나머지 파일들은 그 인터페이스를 구현한다.
1.BCommand.java(인터페이스)
package command;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface BCommand {
void execute(HttpServletRequest request, HttpServletResponse response);
}
2.다른 Command관련 파일들
위에 있는 BCommand인터페이스를 구현하는 Command파일들이 있어야한다.
1. DTO
데이터베이스의 데이터 DTO객체를 만든다
데이터 필드들에 대한 멤버변수를 선언하고 Getter, Setter 메서드만 만들어주면 끝
2. DAO
데이터베이스에 연결하여 필요한 로직을 수행하는 DAO클래스를 만든다.
package dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.util.ArrayList;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import dto.BDto;
public class BDao {
DataSource dataSource;
public BDao() {
// TODO Auto-generated constructor stub
try {
Context context = new InitialContext();
dataSource = (DataSource) context.lookup("java:comp/env/jdbc/Oracle11g");
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
public void write(String bName, String bTitle, String bContent) { //글 작성 메서드
// TODO Auto-generated method stub
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = dataSource.getConnection();
String query = "insert into mvc_board (bId, bName, bTitle, bContent, bHit, bGroup, bStep, bIndent) values (mvc_board_seq.nextval, ?, ?, ?, 0, mvc_board_seq.currval, 0, 0 )";
preparedStatement = connection.prepareStatement(query);
preparedStatement.setString(1, bName);
preparedStatement.setString(2, bTitle);
preparedStatement.setString(3, bContent);
int rn = preparedStatement.executeUpdate();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally {
try {
if(preparedStatement != null) preparedStatement.close();
if(connection != null) connection.close();
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
}
public ArrayList<BDto> list() { //글 목록 메서드
ArrayList<BDto> dtos = new ArrayList<BDto>();
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
connection = dataSource.getConnection();
String query = "select bId, bName, bTitle, bContent, bDate, bHit, bGroup, bStep, bIndent from mvc_board order by bGroup desc, bStep asc";
preparedStatement = connection.prepareStatement(query);
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
int bId = resultSet.getInt("bId");
String bName = resultSet.getString("bName");
String bTitle = resultSet.getString("bTitle");
String bContent = resultSet.getString("bContent");
Timestamp bDate = resultSet.getTimestamp("bDate");
int bHit = resultSet.getInt("bHit");
int bGroup = resultSet.getInt("bGroup");
int bStep = resultSet.getInt("bStep");
int bIndent = resultSet.getInt("bIndent");
BDto dto = new BDto(bId, bName, bTitle, bContent, bDate, bHit, bGroup, bStep, bIndent);
dtos.add(dto);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally {
try {
if(resultSet != null) resultSet.close();
if(preparedStatement != null) preparedStatement.close();
if(connection != null) connection.close();
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
return dtos;
}
public BDto contentView(String strID) { //본문 보여주는 메서드
// TODO Auto-generated method stub
upHit(strID);
BDto dto = null;
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
connection = dataSource.getConnection();
String query = "select * from mvc_board where bId = ?";
preparedStatement = connection.prepareStatement(query);
preparedStatement.setInt(1, Integer.parseInt(strID));
resultSet = preparedStatement.executeQuery();
if(resultSet.next()) {
int bId = resultSet.getInt("bId");
String bName = resultSet.getString("bName");
String bTitle = resultSet.getString("bTitle");
String bContent = resultSet.getString("bContent");
Timestamp bDate = resultSet.getTimestamp("bDate");
int bHit = resultSet.getInt("bHit");
int bGroup = resultSet.getInt("bGroup");
int bStep = resultSet.getInt("bStep");
int bIndent = resultSet.getInt("bIndent");
dto = new BDto(bId, bName, bTitle, bContent, bDate, bHit, bGroup, bStep, bIndent);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally {
try {
if(resultSet != null) resultSet.close();
if(preparedStatement != null) preparedStatement.close();
if(connection != null) connection.close();
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
return dto;
}
public void modify(String bId, String bName, String bTitle, String bContent) { // 글 수정 메서드
// TODO Auto-generated method stub
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = dataSource.getConnection();
String query = "update mvc_board set bName = ?, bTitle = ?, bContent = ? where bId = ?";
preparedStatement = connection.prepareStatement(query);
preparedStatement.setString(1, bName);
preparedStatement.setString(2, bTitle);
preparedStatement.setString(3, bContent);
preparedStatement.setInt(4, Integer.parseInt(bId));
int rn = preparedStatement.executeUpdate();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally {
try {
if(preparedStatement != null) preparedStatement.close();
if(connection != null) connection.close();
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
}
public void delete(String bId) { //글 삭제 메서드
// TODO Auto-generated method stub
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = dataSource.getConnection();
String query = "delete from mvc_board where bId = ?";
preparedStatement = connection.prepareStatement(query);
preparedStatement.setInt(1, Integer.parseInt(bId));
int rn = preparedStatement.executeUpdate();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally {
try {
if(preparedStatement != null) preparedStatement.close();
if(connection != null) connection.close();
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
}
public BDto reply_view(String str) {//답글 보기 메서드
// TODO Auto-generated method stub
BDto dto = null;
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
connection = dataSource.getConnection();
String query = "select * from mvc_board where bId = ?";
preparedStatement = connection.prepareStatement(query);
preparedStatement.setInt(1, Integer.parseInt(str));
resultSet = preparedStatement.executeQuery();
if(resultSet.next()) {
int bId = resultSet.getInt("bId");
String bName = resultSet.getString("bName");
String bTitle = resultSet.getString("bTitle");
String bContent = resultSet.getString("bContent");
Timestamp bDate = resultSet.getTimestamp("bDate");
int bHit = resultSet.getInt("bHit");
int bGroup = resultSet.getInt("bGroup");
int bStep = resultSet.getInt("bStep");
int bIndent = resultSet.getInt("bIndent");
dto = new BDto(bId, bName, bTitle, bContent, bDate, bHit, bGroup, bStep, bIndent);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally {
try {
if(preparedStatement != null) preparedStatement.close();
if(connection != null) connection.close();
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
return dto;
}
public void reply(String bId, String bName, String bTitle, String bContent, String bGroup, String bStep, String bIndent) { //답글 작성 메서드
// TODO Auto-generated method stub
replyShape(bGroup, bStep);
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = dataSource.getConnection();
String query = "insert into mvc_board (bId, bName, bTitle, bContent, bGroup, bStep, bIndent) values (mvc_board_seq.nextval, ?, ?, ?, ?, ?, ?)";
preparedStatement = connection.prepareStatement(query);
preparedStatement.setString(1, bName);
preparedStatement.setString(2, bTitle);
preparedStatement.setString(3, bContent);
preparedStatement.setInt(4, Integer.parseInt(bGroup));
preparedStatement.setInt(5, Integer.parseInt(bStep) + 1);
preparedStatement.setInt(6, Integer.parseInt(bIndent) + 1);
int rn = preparedStatement.executeUpdate();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally {
try {
if(preparedStatement != null) preparedStatement.close();
if(connection != null) connection.close();
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
}
private void replyShape( String strGroup, String strStep) { //답글이 달릴때 보이는 모양 설정
// TODO Auto-generated method stub
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = dataSource.getConnection();
String query = "update mvc_board set bStep = bStep + 1 where bGroup = ? and bStep > ?";
preparedStatement = connection.prepareStatement(query);
preparedStatement.setInt(1, Integer.parseInt(strGroup));
preparedStatement.setInt(2, Integer.parseInt(strStep));
int rn = preparedStatement.executeUpdate();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally {
try {
if(preparedStatement != null) preparedStatement.close();
if(connection != null) connection.close();
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
}
private void upHit( String bId) { //조회수 올려주는 메서드
// TODO Auto-generated method stub
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = dataSource.getConnection();
String query = "update mvc_board set bHit = bHit + 1 where bId = ?";
preparedStatement = connection.prepareStatement(query);
preparedStatement.setString(1, bId);
int rn = preparedStatement.executeUpdate();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally {
try {
if(preparedStatement != null) preparedStatement.close();
if(connection != null) connection.close();
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
}
}
- list.jsp(글 목록 페이지를 보여주는 과정)
list.jsp 코드
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>//jstl 선언
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<table width="500" cellpadding="0" cellspacing="0" border="1">
<tr>
<td>번호</td>
<td>이름</td>
<td>제목</td>
<td>날짜</td>
<td>히트</td>
</tr>
<c:forEach items="${list}" var="dto"> //dto객체 내용을 반복문으로 돌림
<tr>
<td>${dto.bId}</td>
<td>${dto.bName}</td>
<td>
<c:forEach begin="1" end="${dto.bIndent}">-</c:forEach>//답글 들여쓰기를 위한 for문
<a href="content_view.do?bId=${dto.bId}">${dto.bTitle}</a></td>
<td>${dto.bDate}</td>
<td>${dto.bHit}</td>
</tr>
</c:forEach>
<tr>
<td colspan="5"> <a href="write_view.do">글작성</a> </td>
</tr>
</table>
</body>
</html>
list.jsp 파일 자체를 실행하면 글 목록이 출력되지 않는다.
FrontController에서 *.do만 명령으로 받기 때문에 글 목록을 출력되게 하려면 list.do로 호출을 해야한다.
- cotent_view.jsp(글 내용을 보여주는 과정)
글을 수정하는 modify.do, 글을 삭제하는 delete.do도 위 2가지 기능과 동일한 로직으로 진행
로직은 위의 다른 기능들과 동일하다.
bGroup은 본글과 본글에 종속된 답글들을 묶어주는 것이고 bStep은 본글에서 몇번째 답글인지 지정해주는 것이고 bIndent는 답글의 들여쓰기를 위한 것이다.