MVC 패턴을 배워봅시다.
MVC패턴 그림을 보고 구조를 이해해보자
MVC 패턴의 의미
MVC
는 Model-View-Controller 의 약자입니다.
개발 할 때, 3가지 형태로 역할을 나누어 개발하는 방법론입니다.
비지니스 처리 로직과 사용자 인터페이스 요소들을 분리시켜 서로 영향없이 개발 하기 수월하다는 장점이 있습니다.
Model은 어플리케이션이 “무엇”을 할 것인지를 정의 합니다.
내부 비지니스 로직을 처리하기 위한 역할을 할 것입니다.
처리되는 알고리즘, DB 와 상호작용(CRUD Create Read Update Delete), 데이터 등등..
Controller는 모델이 “어떻게” 처리할 지를 알려주는 역할을 할 것이고, 모바일에서는 화면의 로직처리 부분입니다. 화면에서 사용자의 요청을 받아서 처리되는 부분을 구현되게 되며, 요청 내용을 분석해서 Model과 View에 업데이트 요청을 하게 됩니다.
사용자로 부터의 입력 을 받고 Model 또는 View중개인 역할
View는 화면에 “무엇” 인가를 “보여주기 위한 역할”을 합니다. 컨트롤러 하위에 종속되어, 모델이나 컨트롤러가 보여주려고 하는 모든 필요한 것들을 보여줄 것입니다.
최종 사용자에게 “무엇”을 화면(UI)으로 보여줌
그리고 Controller는 Model과 View가 각각 무엇을 해야 할 지를 알고 있고, 통제합니다. 비지니스 로직을 처리하는 Model과 완전히 UI에 의존적인 View가 서로 직접 이야기 할 수 없게 합니다.
◆ JDBC 란 무엇일까요
JDBC(Java Database Connectivity)는 자바에서 데이터베이스에 접속할 수 있도록 하는 자바 API이다. JDBC는 데이터베이스에서 자료를 쿼리하거나 업데이트하는 방법을 제공한다.
◆ MyBatis란 무엇이죠?
마이바티스는 개발자가 지정한 SQL, 저장프로시저 그리고 몇가지 고급 매핑을 지원하는 퍼시스턴스 프레임워크이다. 마이바티스는 JDBC로 처리하는 상당부분의 코드와 파라미터 설정및 결과 매핑을 대신해준다. 마이바티스는 데이터베이스 레코드에 원시타입과 Map 인터페이스 그리고 자바 POJO 를 설정해서 매핑하기 위해 XML과 애노테이션을 사용할 수 있다.
- 객체 지향 언어인 자바의 관계형 데이터 베이스 프로그래밍을 보다 쉽게 도와주는 프레임 워크
- 자바에서는 관계형 데이터베이스 프로그래밍을 하기위해 JDBC를 제공
MyBatis는 JDBC의 편한 사용을 위함
사용환경 준비
필요한 jar 목록
WebContent
/ WEB-INF
/ lib
에 넣어줘야함
MyBatis
mybatis를 사용하기 위한 설정
DBService.java 객체 생성
sqlmap-config.xml, member.xml 설정
DBService.java
package mybatis.config;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class DBService {
//DBService: SqlSessionFactory 반환
private SqlSessionFactory factory;
// DBService 생성자: Singleton
private DBService() {
try {
String resource = "mybatis/config/sqlmap-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
factory = new SqlSessionFactoryBuilder().build(inputStream);
} catch(Exception e) {
e.printStackTrace();
}
}
private static DBService service = new DBService();
public static DBService getInstance() {
return service;
}
public SqlSessionFactory getFactory() {
return factory;
}
}
sqlmap-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd" >
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
<property name="username" value="spring"/>
<property name="password" value="oracle"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mybatis/mapper/member.xml"/>
</mappers>
</configuration>
mapper.xml(member)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="mybatis.mapper.member">
</mapper>
DB
drop sequence member_seq;
create sequence member_seq
start with 1
increment by 1
maxvalue 999999
nocycle
nocache;
drop table member;
create table member
(
mno number primary key,
mid varchar2(30) not null unique,
mpw varchar2(30) not null,
mname varchar2(30),
memail varchar2(50) not null unique,
mphone varchar2(20),
maddress varchar2(100),
mregdate date
);
insert into member values(member_seq.nextval, 'admin', '1111', '관리자', 'admin@myhome.com', '010-0000-0000', '부천', sysdate);
DAO
public class MemberDao {
private SqlSessionFactory factory;
private MemberDao() {
factory = DBService.getInstance().getFactory();
}
private static MemberDao memberDao = new MemberDao();
public static MemberDao getInstance() {
return memberDao;
}
}
DTO
package dto;
import java.sql.Date;
public class MemberDto {
private int mNo;
private String mId;
private String mPw;
private String mName;
private String mEmail;
private String mPhone;
private String mAddress;
private Date mRegdate;
public int getmNo() {
return mNo;
}
public void setmNo(int mNo) {
this.mNo = mNo;
}
...
}
MVC 패턴 구축
Controller
package controller;
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;
import command.member.MemberCommand;
import command.member.MemberFindIdCommand;
import command.member.MemberLoginCommand;
import command.member.MemberLogoutCommand;
import common.PathNRedirect;
@WebServlet("*.member")
public class MemberController extends HttpServlet {
private static final long serialVersionUID = 1L;
public MemberController() {
super();
// TODO Auto-generated constructor stub
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String requestURI = request.getRequestURI();
String context = request.getContextPath();
String cmd = requestURI.substring(context.length());
MemberCommand command = null;
PathNRedirect pathNRedirect = null;
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
controller의 doGet()메소드의 pathNRedirect
package common;
public class PathNRedirect {
private String path;
private boolean isRedirect;
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public boolean isRedirect() {
return isRedirect;
}
public void setRedirect(boolean isRedirect) {
this.isRedirect = isRedirect;
}
}
- Command
package command.member;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import common.PathNRedirect;
public interface MemberCommand {
public PathNRedirect execute(HttpServletRequest request, HttpServletResponse response);
}
- view
index 파일 - header와 footer를 include 해준다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!-- 머리글 포함(파라미터(title)가 있으므로 동적 페이지 포함 -->
<jsp:include page="template/header.jsp"/>
<c:if test="${loginDto.mId eq 'admin' }">
<h1>관리자님 환영합니다.</h1>
<a href="/MyHome/memberList.admin">회원관리</a><br>
<a href="/MyHome/guestList.admin">방명록관리</a><br>
<a href="/MyHome/bbsList.admin">BBS관리</a><br>
<a href="/MyHome/boardList.admin">게시판관리</a><br>
</c:if>
<c:if test="${loginDto.mId ne 'admin'}" >
<h1>MyHome에 오신 걸 환영합니다.</h1>
</c:if>
<!-- 바닥글 포함(파라미터가 없으므로 정적 페이지 포함 -->
<%@include file="template/footer.jsp" %>
header.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%
request.setCharacterEncoding("utf-8");
String title = request.getParameter("title");
if(title == null || title.isEmpty()){
title = "환영합니다.";
}
pageContext.setAttribute("title", title);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>${title }</title>
<!-- css -->
<link rel="stylesheet" href="asset/style/common.css?ver0.1">
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script type="text/javascript">
function fn_logout(f){
if(confirm('로그아웃 하시겠습니까?')){
f.action = '/MyHome/logout.member';
f.submit();
}
}
function fn_signOut(){
location.href= '/MyHome/signOutPage.member';
}
</script>
</head>
<body>
<div class="wrap">
<img alt="고양이" src="asset/image/cat-3059075_1920.jpg" style="height: 100px; width: 250px">
<div class="head-wrap">
<!-- 로그인 안 된 상태 -->
<c:if test="${loginDto eq null }">
<input type="button" value="MyHome로그인" onclick="location.href='/MyHome/loginPage.member'"/>
<input type="button" value="회원가입" onclick="location.href='/MyHome/signUpPage.member'"/>
<input type="button" value="마이페이지" onclick="location.href='/MyHome/loginPage.member'"/>
<input type="button" value="방명록" onclick="location.href='/MyHome/'"/>
<input type="button" value="BBS" onclick="location.href='/MyHome/'"/>
<input type="button" value="게시판" onclick="location.href='/MyHome/'"/>
<!-- 2.로그인 상태 -->
</c:if>
<c:if test="${loginDto ne null }">
${loginDto.mName } 님 반갑습니다.
<form>
<input type="button" value="로그아웃" onclick="fn_logout(this.form)"/>
<input type="button" value="회원탈퇴" onclick="fn_signOut()"/>
<input type="button" value="마이페이지" onclick="location.href='/MyHome/myPage.member'"/>
<input type="button" value="방명록" onclick="location.href='/MyHome/'"/>
<input type="button" value="BBS" onclick="location.href='/MyHome/'"/>
<input type="button" value="게시판" onclick="location.href='/MyHome/'"/>
</form>
</c:if>
</div>
<div class="body-wrap">
footer.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
</div>
<div class="foot-wrap">
개인정보보호정책 | 약관 | 저작권
</div>
</div>
</body>
</html>