MVC 패턴은 Model, View, Controller
MVC 패턴이란 무엇인가?
- **MVC (Model-View-Controller)**는 애플리케이션을 세 개의 주요 컴포넌트(모델, 뷰, 컨트롤러)로 나누는 아키텍처 패턴입니다. 이 패턴은 유지 보수성, 확장성, 역할의 분리를 통해 코드 품질을 높이고 개발을 효율적으로 할 수 있게 도와줍니다.
- Model (모델): 애플리케이션의 데이터와 비즈니스 로직을 관리합니다. 모델은 데이터베이스와 상호작용하고, 데이터를 처리합니다.
- View (뷰): 사용자가 보는 UI 부분을 담당합니다. JSP는 뷰(View) 역할을 수행하며, 데이터가 어떻게 사용자에게 보여질지 결정합니다.
- Controller (컨트롤러): 사용자의 요청을 받아 비즈니스 로직을 처리하고, 필요한 데이터를 가져와 View에 전달합니다. 컨트롤러는 모델과 뷰를 연결하는 역할을 합니다.
JSP와 MVC 패턴의 차이와 연결고리
차이점
- JSP는 View(뷰) 역할을 수행하는 기술입니다. JSP는 웹 애플리케이션의 화면(UI)을 구성하고, 사용자에게 보여지는 데이터를 출력하는 데 사용됩니다.
- MVC는 애플리케이션을 세 개의 주요 컴포넌트인 모델(Model), 뷰(View), **컨트롤러(Controller)**로 나누는 구조적인 패턴입니다. 이 패턴에서 View는 JSP를 사용하여 구현될 수 있습니다.
JSP와 MVC 패턴의 통합 예시 흐름
1) 사용자 요청
사용자가 http://localhost:8080/board/list로 게시글 목록을 요청합니다.
2) Controller
BoardController가 이 요청을 받아 처리합니다. 컨트롤러는 boardService를 호출하여 필요한 데이터를 Model에서 가져오고, 그 데이터를 JSP에 전달할 준비를 합니다.
3) Model
boardService.getBoardList() 메서드가 데이터베이스에서 게시글 목록을 가져옵니다. BoardDAO가 SQL을 실행해 데이터를 가져오는 역할을 담당합니다.
4) View (JSP)
컨트롤러는 boardList.jsp로 데이터를 전달합니다. JSP는 이 데이터를 받아 HTML로 변환하여 웹 브라우저에 출력합니다. 사용자는 게시글 목록을 브라우저에서 확인합니다.
연결고리: JSP와 MVC의 역할 분담
MVC 패턴에서 각 컴포넌트는 서로 명확하게 구분되어 있으며, JSP는 View 부분에서 화면을 렌더링하는 역할을 합니다.
1. Model (모델)
Model은 데이터를 다루는 부분입니다. VO, DAO, Service는 모두 Model에 해당합니다.
BoardVO.java (Value Object)
import java.util.Date;
public class BoardVO {
private int seq;
private String title;
private String writer;
private String content;
private Date regdate;
private int cnt;
// 기본 생성자
public BoardVO() {}
// 모든 필드를 가진 생성자
public BoardVO(int seq, String title, String writer, String content, Date regdate, int cnt) {
this.seq = seq;
this.title = title;
this.writer = writer;
this.content = content;
this.regdate = regdate;
this.cnt = cnt;
}
// Getter 및 Setter
public int getSeq() { return seq; }
public void setSeq(int seq) { this.seq = seq; }
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public String getWriter() { return writer; }
public void setWriter(String writer) { this.writer = writer; }
public String getContent() { return content; }
public void setContent(String content) { this.content = content; }
public Date getRegdate() { return regdate; }
public void setRegdate(Date regdate) { this.regdate = regdate; }
public int getCnt() { return cnt; }
public void setCnt(int cnt) { this.cnt = cnt; }
}
BoardDAO.java (Data Access Object)
import java.util.List;
public interface BoardDAO {
// 게시글 등록
void insertBoard(BoardVO board);
// 게시글 수정
void updateBoard(BoardVO board);
// 게시글 삭제
void deleteBoard(int seq);
// 게시글 조회
BoardVO getBoard(int seq);
// 게시글 전체 목록 조회
List<BoardVO> getBoardList();
}
BoardDAOImpl.java (DAO 구현체)
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class BoardDAOImpl implements BoardDAO {
private Connection conn;
public BoardDAOImpl(Connection conn) {
this.conn = conn;
}
@Override
public void insertBoard(BoardVO board) {
String sql = "INSERT INTO BOARD (SEQ, TITLE, WRITER, CONTENT, REGDATE, CNT) VALUES (?, ?, ?, ?, ?, ?)";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, board.getSeq());
pstmt.setString(2, board.getTitle());
pstmt.setString(3, board.getWriter());
pstmt.setString(4, board.getContent());
pstmt.setDate(5, new java.sql.Date(board.getRegdate().getTime()));
pstmt.setInt(6, board.getCnt());
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void updateBoard(BoardVO board) {
String sql = "UPDATE BOARD SET TITLE = ?, CONTENT = ?, CNT = ? WHERE SEQ = ?";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, board.getTitle());
pstmt.setString(2, board.getContent());
pstmt.setInt(3, board.getCnt());
pstmt.setInt(4, board.getSeq());
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void deleteBoard(int seq) {
String sql = "DELETE FROM BOARD WHERE SEQ = ?";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, seq);
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public BoardVO getBoard(int seq) {
String sql = "SELECT * FROM BOARD WHERE SEQ = ?";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, seq);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
return new BoardVO(
rs.getInt("SEQ"),
rs.getString("TITLE"),
rs.getString("WRITER"),
rs.getString("CONTENT"),
rs.getDate("REGDATE"),
rs.getInt("CNT")
);
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
@Override
public List<BoardVO> getBoardList() {
String sql = "SELECT * FROM BOARD";
List<BoardVO> list = new ArrayList<>();
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
list.add(new BoardVO(
rs.getInt("SEQ"),
rs.getString("TITLE"),
rs.getString("WRITER"),
rs.getString("CONTENT"),
rs.getDate("REGDATE"),
rs.getInt("CNT")
));
}
} catch (SQLException e) {
e.printStackTrace();
}
return list;
}
}
2. Service (서비스)
BoardService.java (서비스 인터페이스)
import java.util.List;
public interface BoardService {
void addBoard(BoardVO board);
void modifyBoard(BoardVO board);
void removeBoard(int seq);
BoardVO getBoard(int seq);
List<BoardVO> getBoardList();
}
BoardServiceImpl.java (서비스 구현체)
import java.util.List;
public class BoardServiceImpl implements BoardService {
private BoardDAO boardDAO;
public BoardServiceImpl(BoardDAO boardDAO) {
this.boardDAO = boardDAO;
}
@Override
public void addBoard(BoardVO board) {
boardDAO.insertBoard(board);
}
@Override
public void modifyBoard(BoardVO board) {
boardDAO.updateBoard(board);
}
@Override
public void removeBoard(int seq) {
boardDAO.deleteBoard(seq);
}
@Override
public BoardVO getBoard(int seq) {
return boardDAO.getBoard(seq);
}
@Override
public List<BoardVO> getBoardList() {
return boardDAO.getBoardList();
}
}
3. Controller (컨트롤러)
BoardController.java (컨트롤러 클래스)
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@Controller
public class BoardController {
@Autowired
private BoardService boardService;
// 게시글 목록
@GetMapping("/boardList")
public String boardList(Model model) {
List<BoardVO> boardList = boardService.getBoardList();
model.addAttribute("boardList", boardList);
return "boardList"; // View 파일 이름 (boardList.jsp)
}
// 게시글 상세보기
@GetMapping("/boardDetail")
public String boardDetail(@RequestParam("seq") int seq, Model model) {
BoardVO board = boardService.getBoard(seq);
model.addAttribute("board", board);
return "boardDetail"; // View 파일 이름 (boardDetail.jsp)
}
// 게시글 작성 폼
@GetMapping("/addBoardForm")
public String addBoardForm() {
return "addBoard"; // View 파일 이름 (addBoard.jsp)
}
// 게시글 등록
@PostMapping("/addBoard")
public String addBoard(BoardVO boardVO) {
boardService.addBoard(boardVO);
return "redirect:/boardList";
}
// 게시글 삭제
@GetMapping("/deleteBoard")
public String deleteBoard(@RequestParam("seq") int seq) {
boardService.removeBoard(seq);
return "redirect:/boardList";
}
}
@RequestMapping을 사용한 Controller 코드
BoardController.java (컨트롤러 클래스)
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@Controller
@RequestMapping("/board")
public class BoardController {
@Autowired
private BoardService boardService;
// 게시글 목록
@RequestMapping(value = "/list", method = RequestMethod.GET)
public String boardList(Model model) {
List<BoardVO> boardList = boardService.getBoardList();
model.addAttribute("boardList", boardList);
return "boardList"; // View 파일 이름 (boardList.jsp)
}
// 게시글 상세보기
@RequestMapping(value = "/detail", method = RequestMethod.GET)
public String boardDetail(@RequestParam("seq") int seq, Model model) {
BoardVO board = boardService.getBoard(seq);
model.addAttribute("board", board);
return "boardDetail"; // View 파일 이름 (boardDetail.jsp)
}
// 게시글 작성 폼
@RequestMapping(value = "/addForm", method = RequestMethod.GET)
public String addBoardForm() {
return "addBoard"; // View 파일 이름 (addBoard.jsp)
}
// 게시글 등록
@RequestMapping(value = "/add", method = RequestMethod.POST)
public String addBoard(BoardVO boardVO) {
boardService.addBoard(boardVO);
return "redirect:/board/list";
}
// 게시글 삭제
@RequestMapping(value = "/delete", method = RequestMethod.GET)
public String deleteBoard(@RequestParam("seq") int seq) {
boardService.removeBoard(seq);
return "redirect:/board/list";
}
}
4. View (뷰)
boardList.jsp
<html>
<head>
<title>Board List</title>
</head>
<body>
<h1>Board List</h1>
<table border="1">
<tr>
<th>SEQ</th>
<th>Title</th>
<th>Writer</th>
<th>Date</th>
<th>Views</th>
<th>Action</th>
</tr>
<c:forEach var="board" items="${boardList}">
<tr>
<td>${board.seq}</td>
<td><a href="boardDetail?seq=${board.seq}">${board.title}</a></td>
<td>${board.writer}</td>
<td>${board.regdate}</td>
<td>${board.cnt}</td>
<td><a href="deleteBoard?seq=${board.seq}">Delete</a></td>
</tr>
</c:forEach>
</table>
<br>
<a href="addBoardForm">Add New Board</a>
</body>
</html>
boardDetail.jsp
<html>
<head>
<title>Board Detail</title>
</head>
<body>
<h1>Board Detail</h1>
<p>Title: ${board.title}</p>
<p>Writer: ${board.writer}</p>
<p>Content: ${board.content}</p>
<p>Views: ${board.cnt}</p>
<p>Date: ${board.regdate}</p>
<a href="boardList">Back to List</a>
</body>
</html>
addBoard.jsp
<html>
<head>
<title>Add New Board</title>
</head>
<body>
<h1>Add New Board</h1>
<form action="addBoard" method="post">
<label>Title: </label>
<input type="text" name="title"><br>
<label>Writer: </label>
<input type="text" name="writer"><br>
<label>Content: </label>
<textarea name="content"></textarea><br>
<input type="submit" value="Submit">
</form>
<a href="boardList">Cancel</a>
</body>
</html>
결론
이제 MVC 패턴에 맞춰 Model, View, Controller가 모두 작성되었습니다.
- Model: BoardVO, BoardDAO, BoardService 계층에서 데이터를 처리하고, 데이터베이스와 상호작용하는 로직을 담당합니다.
- View: JSP 파일들은 사용자에게 데이터를 시각적으로 제공하고, 사용자로부터 입력을 받습니다.
- Controller: 사용자의 요청을 처리하고, 그 결과를 View에 전달하는 역할을 합니다.
이 구조를 사용하면 유지보수성과 확장성이 높아지고, 각 컴포넌트의 역할이 명확해집니다.
JSP와 MVC 패턴 연결고리 (결론)
- JSP는 View로서 UI 화면을 렌더링하는 데 사용되는 기술입니다. MVC 패턴은 애플리케이션 전체를 세 개의 주요 구성 요소로 나누어 구조화하는 방법이며, 이 중 View 부분을 JSP가 담당할 수 있습니다.
- JSP와 MVC 패턴은 서로 보완적인 관계에 있습니다. JSP는 MVC 패턴의 View 역할을 하여 사용자가 볼 수 있는 화면을 출력하고, MVC는 데이터 처리 및 흐름 제어를 담당합니다. 이 두 가지는 함께 사용되어, 유지 보수가 쉽고 확장성이 좋은 웹 애플리케이션을 구축하는 데 큰 도움이 됩니다.
'개인 프로젝트 > Java Spring 프레임워크' 카테고리의 다른 글
[Board Project] Mybatis 활용, 기존 JDBC 방식과 비교 (0) | 2024.10.18 |
---|---|
[Board Project] Command 객체 활용 -> MVC 패턴 적용 (0) | 2024.10.18 |
[Board Project] 테이블 구조 -> ServiceImpl, DAO, VO (0) | 2024.10.17 |
[Java Spring] Login_Controller (0) | 2024.10.17 |
[Java Spring] Board_Controller (0) | 2024.10.17 |
댓글