-
231205_MVC 패턴, JDBC카테고리 없음 2023. 12. 5. 17:30
객체지향 프로그램이란 소프트웨어를 모듈화 하는 것, 즉 응집성은 낮추고 독립성은 높이는 것이다.
응집성이 높다는건 모니터와 본체가 하나가 되어있는 컴퓨터와 같은거고, 독립성이 높다는건 조립컴퓨터와 같다. 본체와 모니터가 붙어있는건, 본체 부품 하나가 고장나도 뷰가 나오지 않는 문제가 발생할 수 있고 본체 부품 하나를 고치기 위해 다 뜯어 고쳐야 한다는 단점이 있다. 반면 조립 컴퓨터는 부품 하나가 고장나면 그 부품만 갈아 끼우면 된다는 흐름.
디자인 패턴과 추상 팩토리 패턴에 대해서도 다시 짚고 가셨다 (지난번 수업 때 배운 것과 크게 다르지 않다). 패턴은 대략 코드를 짤 때 구상하는 과정? 대략 이렇게 만들면 된다는 대중화 된 도면 같은거다.
MVC 패턴이란, 화면과 데이터의 처리를 분리해서 응집도를 줄이고 코드 간 종속성을 줄이는데에 목적을 가진다.
컨트롤러란, 서로 연결지어 주는 것이다. MVC 패턴의 핵심으로 모든 사용자 요청의 중심에 위치한다. 사용자 요청은 컨트롤러를 통하며, 사용자 요청에 따라 모델을 통해 데이터베이스와 연동해 데이터를 처리하고 뷰에 전달한다. 컨트롤러는 뷰를 지정하기 때문에 종속관계가 발생할수밖에 없다.
컨트롤러를 구성하는 방법.
1. 사용자 요청마다 컨트롤러를 만드는 것
2. 특정 모듈 단위로 하나의 컨트롤러 안에서 여러 요청 단위를 구분해 처리
3. 프런트 컨트롤러를 따로 두어 모든 요청을 하나의 컨트롤러로 모은 뒤 다음 요청에 따라 구현 컨트롤러를 호출
실습8-1. 컨트롤러 기초 예제: 계산기 구현
1. 뷰 구현: calcForm.html, calcResult.jsp
2. 모델구현: Calculator.java
3. 컨트롤러 구현: CalcController.java
calcForm.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>계산기-컨트롤러</title> </head> <body> <h2>계산기-컨트롤러</h2> <hr> <form method="post" action="/jwbook/calcControl"> <input type="text" name="n1" size="10"> <select name="op"> <option>+</option> <option>-</option> <option>*</option> <option>/</option> </select> <input type="text" name="n2" size="10"> <input type="submit" value="실행"> </form> </body> </html>
calcResult.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>계산기-컨트롤러</title> </head> <body> <h2>계산 결과-컨트롤러</h2> <hr> 결과: ${n1} ${op} ${n2} = ${result} </body> </html>
CalcController.java
package ch08; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/calcControl") public class CalcController extends HttpServlet { private static final long serialVersionUID = 1L; public CalcController() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int n1 = Integer.parseInt(request.getParameter("n1")); int n2 = Integer.parseInt(request.getParameter("n2")); String opp = request.getParameter("op"); long result = 0; switch(request.getParameter("op")) { case "+": result = n1+n2;break; case "-": result = n1-n2;break; case "/": result = n1/n2;break; case "*": result = n1*n2;break; } request.setAttribute("n1", n1); request.setAttribute("n2", n2); request.setAttribute("op", opp); request.setAttribute("result", result); getServletContext().getRequestDispatcher("/ch08/calcResult.jsp").forward(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
n1, n2 와 연산자를 모두 확인하고 결괏값을 받기 위해 calcResult.jsp 파일에 한 줄을 추가했다.
결과: ${n1} ${op} ${n2} = ${result}
그리고 위의 n1, n2, 연산자를 받아오기 위해 CalcController.java 파일에 아래와 같이 추가했다.
String opp = request.getParameter("op");
request.setAttribute("n1", n1);
request.setAttribute("n2", n2);
request.setAttribute("op", opp);
request.setAttribute("result", result);을 추가했다.
수정 전과 수정 후
실습 8-2. 고급 컨트롤러 구현
뷰 구현: productList.jsp, productInfo.jsp
모델 구현: Product.java, ProductService.java
컨트롤러 구현: ProductController.java
productList.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>상품 목록</title> </head> <body> <h2>상품 목록</h2> <hr> <table border="1"> <tr><th>번호</th><th>상품명</th><th>가격</th></tr> <c:forEach var="p" varStatus="i" items="${products}"> <tr><td>${i.count}</td><td><a href="/jwbook/pcontrol?action=info&id=${p.id}">${p.name}</a></td><td>${p.price}</td></tr> </c:forEach> </table> </body> </html>
productInfo.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>상품정보 조회</title> </head> <body> <h2>상품정보 조회</h2> <hr> <ul> <li>상품코드: ${p.id}</li> <li>상품명: ${p.name}</li> <li>제조사: ${p.maker}</li> <li>가격: ${p.price}</li> <li>등록일: ${p.date}</li> </ul> </body> </html>
ProductService.java
package ch08; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class ProductService { Map<String, Product> products = new HashMap<>(); public ProductService() { // Product p = new Product("101","애플사과폰 12","애플전자",1200000,"2020.12.12"); // products.put("101", p); // p = new Product("102","삼전우주폰 21","삼전전자",1300000,"2021.2.2"); // products.put("102", p); // p = new Product("103","엘스듀얼폰","엘스전자",1500000,"2021.3.2"); // products.put("103", p); Product [] p = new Product[3]; // 배열 선언 및 5개 배열 생성 p 배열 안에 있는 정보들... p[0] = new Product ("101","애플사과폰 12 뿅","애플전자",1200000,"2020.12.12"); p[1] = new Product ("102","삼전우주폰 21 뿅뿅","삼전전자",1300000,"2021.2.2"); p[2] = new Product ("103","엘스듀얼폰 뿅뿅뿅","엘스전자",1500000,"2021.3.2"); for(int i = 0; i<p.length; i++) { products.put(p[i].getId(), p[i]); //p 배열에 있는 상품코드, 상품명, 제조사, 가격, 등록일 불러옴.. } } public List<Product> findAll() { return new ArrayList<>(products.values()); } public Product find(String id) { return products.get(id); } }
ProductController.java
package ch08; import java.io.IOException; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class ProductController */ @WebServlet("/pcontrol") public class ProductController extends HttpServlet { private static final long serialVersionUID = 1L; ProductService service; public void init(ServletConfig config) throws ServletException { super.init(config); service = new ProductService(); } @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String action = request.getParameter("action"); String view = ""; if(action == null) { getServletContext().getRequestDispatcher("/pcontrol?action=list").forward(request, response); } else { switch(action) { case "list": view = list(request, response);break; case "info": view = info(request, response);break; } getServletContext().getRequestDispatcher("/ch08/"+view).forward(request, response); } } private String info(HttpServletRequest request, HttpServletResponse response) { request.setAttribute("p", service.find(request.getParameter("id"))); return "productInfo.jsp"; } private String list(HttpServletRequest request, HttpServletResponse response) { request.setAttribute("products", service.findAll()); return "productList.jsp"; } }
수정 전 수정 후 Product [] p = new Product[3];
p[0] = new Product ("101","애플사과폰 12 뿅","애플전자",1200000,"2020.12.12");
p[1] = new Product ("102","삼전우주폰 21 뿅뿅","삼전전자",1300000,"2021.2.2");
p[2] = new Product ("103","엘스듀얼폰 뿅뿅뿅","엘스전자",1500000,"2021.3.2");
for(int i = 0; i<p.length; i++) {
products.put(p[i].getId(), p[i]);
}
고급 컨트롤러 서블릿 구현 과정에서 흐름을 설명하셨는데...
교수님이 친절하게 다시 설명해주셨으니 다시 한번 확인해보자. (개인 유튜브에 영상 백업함, 텍스트 파일은 아래 참고)
231206 구로 디지털 아카데미_jsp 흐름 이해하기 텍스트 파일.txt0.03MB
ODBC 는 MS에서 만든 데이터베이스
JDBC는 Java에서 만든 데이터베이스
H2 Database Engine
H2 Database Engine Welcome to H2, the Java SQL database. The main features of H2 are: Very fast, open source, JDBC API Embedded and server modes; in-memory databases Browser based Console application Small footprint: around 2.5 MB jar file size Supp
www.h2database.com
CREATE TABLE student( id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, username VARCHAR(20), univ VARCHAR(40), birth DATE, email VARCHAR(40) ); INSERT INTO student(username, univ, birth, email) VALUES('김길동','AA대학교','1999-10-21','kim@aa.com'); INSERT INTO student(username, univ, birth, email) VALUES('박사랑','BB대학교','2000-1-21','park@bb.com'); INSERT INTO student(username, univ, birth, email) VALUES('나최고','CC대학교','1998-7-11','na@cc.com'); INSERT INTO student(username, univ, birth, email) VALUES('김길동','BB대학교','1999-03-10','kim@bb.com'); INSERT INTO student(username, univ, birth, email) VALUES('홍길동','AA대학교','1999-12-10','hong@aa.com'); select * from student;