mybatisWork02
■■■ SpringMVC + Annotation + Mybatis 프로젝트 실습 02 ■■■
○ 프로젝트
: mybatisWork02
○ 관련 라이브러리
: 위에서 정리한 내용 참조
○ 기능 구현
: 이름, 전화번호를 데이터베이스에서 읽어내어 화면에 출력
이 과정에서 mybatis 활용
○ 데이터베이스 관련 객체 준비
- 사용 계정 : scott
- 테이블 : TBL_MEMBERLIST
- 테이블 구조 : MID NUMBER -- PK
,NAME VARCHAR2(30)
,TELEPHONE VARCHAR2(40)
- 시퀀스 : MEMBERLISTSEQ
○ 페이지 레이아웃 구성
회원 관리
이름 [ ]
전화 [ ]
< 회원 추가 >
전체 인원 수 : 2명
------------------------------
번호 이름 전화
1 윤석원 010-1122-3344
2 최호중 010-5566-7788
------------------------------
○ 물리적 파일 구성
- mybatisWork02_scott.sql → 데이터베이스 관련 작업
- MemberDTO.java → 데이터베이스 객체 자료형 클래스(DTO)
- IMemberDAO.java → 인터페이스
- MemberDAO.xml → mybatis 환경 설정 파일 활용
- MemberMain.java → mybatis 객체 활용(Controller)
- MemberList.jsp → View 페이지 활용
- dispatcher-servlet.xml → mybatis 객체 등록 및 활용
- web.xml → front controller 객체 등록 및 인코딩 설정(필터 활용)
○ 사용자 최초 요청 주소
http://localhost:3306/mybatisWork02/memberlist.action
더보기
SELECT USER
FROM DUAL;
--==>>SCOTT
--○ 기존 테이블 제거
DROP TABLE TBL_MEMBERLIST;
--==>> Table TBL_MEMBERLIST이(가) 삭제되었습니다.
--○ 실습 테이블 생성(TBL_MEMBERLIST)
CREATE TABLE TBL_MEMBERLIST
( MID NUMBER
, NAME VARCHAR2(30)
, TELEPHONE VARCHAR2(40)
, CONSTRAINT MEMBERLIST_MID_PK PRIMARY KEY(MID)
);
--==>> Table TBL_MEMBERLIST이(가) 생성되었습니다.
--○ 기존 시퀀스 제거
DROP SEQUENCE MEMBERLISTSEQ;
--==>>Sequence MEMBERLISTSEQ이(가) 삭제되었습니다.
--○ 실습 시퀀스 생성
CREATE SEQUENCE MEMBERLISTSEQ
NOCACHE;
--==>>Sequence MEMBERLISTSEQ이(가) 생성되었습니다.
--○ 데이터 입력
INSERT INTO TBL_MEMBERLIST(MID,NAME, TELEPHONE)
VALUES(MEMBERLISTSEQ.NEXTVAL, '윤석원', '010-1122-3344');
--==>> 1 행 이(가) 삽입되었습니다.
--○ 확인 (리스트 조회)
SELECT MID, NAME, TELEPHONE
FROM TBL_MEMBERLIST
ORDER BY MID;
--==>>1 윤석원 010-1122-3344
--○ 커밋
COMMIT;
--==>> 커밋 완료.
--○ 인원 수 확인
SELECT COUNT(*) AS COUNT
FROM TBL_MEMBERLIST;
--==>>1
--○ 데이터 추가 입력
INSERT INTO TBL_MEMBERLIST(MID,NAME, TELEPHONE)
VALUES(MEMBERLISTSEQ.NEXTVAL, '최호중', '010-5566-7788');
--==>> 1 행 이(가) 삽입되었습니다.
--○ 커밋
COMMIT;
--==>> 커밋 완료.
--○ 데이터 삭제
DELETE
FROM TBL_MEMBERLIST
WHERE MID=1;
--○ 롤백
ROLLBACK;
더보기
/*==================================
MemberDTO.java
- 데이터 저장 및 전송 전용 객체
==================================== */
package com.test.mybatis;
public class MemberDTO
{
// 주요 속성 구성
private String mid, name, telephone;
// 사용자 정의 생성자 정의 안함
// → default 생성자 자동 삽입
// getter / setter 구성
public String getMid()
{
return mid;
}
public void setMid(String mid)
{
this.mid = mid;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getTelephone()
{
return telephone;
}
public void setTelephone(String telephone)
{
this.telephone = telephone;
}
}
/*=====================
IMemberDAO.java
- 인터페이스
=====================*/
package com.test.mybatis;
import java.util.ArrayList;
public interface IMemberDAO
{
// 어떤 페이지 어떤 것을 만들 것이냐를 생각해서 구성
// → 리스트 조회 쿼리문, 인원수 조회 쿼리문, insert 쿼리문
public ArrayList<MemberDTO> list();
public int count();
public int add(MemberDTO m);
}
- MemberDAO.xml
- IMemberDAO 의 행세를 하게끔 만든다!
<?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="com.test.mybatis.IMemberDAO">
<!-- 필요한 쿼리문 구성 -->
<select id="list" resultType="com.test.mybatis.MemberDTO">
SELECT MID, NAME, TELEPHONE
FROM TBL_MEMBERLIST
ORDER BY MID
</select>
<!-- select : select 쿼리문이 필요할 때, id = "메소드 이름" -->
<!-- 쿼리문 그대로 사용하면 됨, 굳이 한 줄 구성이 필요하지 않음 -->
<!-- resultType : 해당 메소드가 반환하는 타입 -->
<select id="count" resultType="java.lang.Integer">
SELECT COUNT(*) AS COUNT
FROM TBL_MEMBERLIST
</select>
<insert id="add">
INSERT INTO TBL_MEMBERLIST(MID,NAME, TELEPHONE)
VALUES(MEMBERLISTSEQ.NEXTVAL, #{name}, #{telephone})
</insert>
<!--
insert 쿼리 문의 경우 : resultType 반환하는 것이 중요하지 않기 때문에 생략
안에 들어가야할 값을 어떻게 구성?
→ name 속성 : name, telephone
#{name속성이름} 으로 값을 받아온다!
MemberDTO m 의 값을 받아온 것에서 name 과 telephone 을 꺼내 쓰는 것이다.
-->
</mapper>
/*==================
MemberMain.java
- 컨트롤러
===================*/
package com.test.mybatis;
import org.apache.ibatis.session.SqlSession;
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;
@Controller
public class MemberMain
{
// 주요 속성 구성
// → mybatis 객체 의존성 (자동) 주입! //-- Autowired : 자동으로 묶어서 등록해!
@Autowired
private SqlSession sqlSession;
//-- 해당 세션을 구성하기 위해서 mybatis 가 개입하게 되는 것임
//-- 일반적으로는 setter 를 구성하여,
//-- dispatcher-servlet 에 bean 의 name과 class 를 property 와 함께 등록하였으나
//-- 이제는 스프링이 직접 확인해서 사용하라고 context 구성해두었기 때문에...
//-- Autowired 로 자동으로 묶어주게끔 구성
@RequestMapping(value="/memberlist.action", method=RequestMethod.GET)
public String memberList(Model model)
{
String result = "";
//IMemberDAO dao = (IMemberDAO)new MemberDAO();
//-- 위의 구문을 sqlSession 을 이용하여 아래와 같이 쓸 수 있다. //-- 정확히 동일한 구문
IMemberDAO dao = sqlSession.getMapper(IMemberDAO.class);
// 이렇게 사용 가능
//dao.count();
//dao.list();
model.addAttribute("count", dao.count());
model.addAttribute("list", dao.list());
result = "/WEB-INF/view/MemberList.jsp";
return result;
}
public String memberInsert()
{
String result = "";
return result;
}
}
- MemberList.jsp
- jQuery, Bootstrap 사용
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
request.setCharacterEncoding("UTF-8");
String cp = request.getContextPath();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>MemberList.jsp</title>
<link rel="stylesheet" type="text/css" href="<%=cp %>/css/main.css">
<!-- jQuery -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<!-- 합쳐지고 최소화된 최신 CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<!-- 부가적인 테마 -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css">
<!-- 합쳐지고 최소화된 최신 자바스크립트 -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<script type="text/javascript">
$(function()
{
$(".btnDelete").click(function()
{
// 확인
//alert($(this).val());
if(confirm("정말로 해당 데이터를 삭제하시겠습니까?"))
{
$(location).attr("href", "memberdelete.action?mid="+$(this).val());
}
});
});
</script>
</head>
<body>
<div>
<h1>회원 정보</h1>
<hr />
</div>
<div class="container">
<div class="panel-group">
<div class="panel panel-default">
<div class="panel-heading" id="title">
회원 정보 입력
</div>
<div class="panel-body">
<form role="form" action="memberinsert.action" method="post">
<div class="form-group">
<label for="name">
NAME :
</label>
<input type="text" class="form-control" id="name" name="name" />
</div>
<div class="form-group">
<label for="telephone">
TELEPHONE :
</label>
<input type="tel" class="form-control" id="telephone" name="telephone" />
</div>
<button type="submit" class="btn btn-default btn-sm">SUBMIT</button>
<button type="button" class="btn btn-default btn-sm btnCancel">CANCEL</button>
</form>
</div>
</div><!-- close .panel .panel-default -->
<div class="panel panel-default">
<div class="panel-heading" id="title">
회원 정보 출력
</div>
<div class="panel-body">
<table class="table">
<thead>
<tr>
<th>MID</th>
<th>NAME</th>
<th>TELEPHONE</th>
<th>삭제</th>
</tr>
</thead>
<tbody>
<!--
<tr>
<td>1</td>
<td>정성화</td>
<td>010-1234-1234</td>
</tr>
<tr>
<td>2</td>
<td>이경수</td>
<td>010-4321-4321</td>
</tr>
-->
<c:forEach var="member" items="${list }">
<tr>
<td>${member.mid }</td>
<td>${member.name }</td>
<td>${member.telephone }</td>
<td>
<button type="button" class="btn btn-default btn-xs btnDelete"
value="${member.mid }">삭제</button>
</td>
</tr>
</c:forEach>
</tbody>
</table>
<button type="button" class="btn btn-default btn-sm" role="badgeFrame">
<!-- Count <span class="bedge" role="bedge">2</span> -->
Count <span class="bedge" role="bedge">${count }</span>
</button>
</div>
</div><!-- close .panel .panel-default -->
</div>
</div>
</body>
</html>
- dispatcher-servlet.xml
- 필요시에만 설정
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- ※ 사용자 정의 Controller 객체 등록 및 URL 매핑 주소 등록 -->
<!-- - 『name=""』 속성에 매핑 주소를 등록한다. -->
<!-- 이 과정에서 Front Controller 가 갖고있는 확장자의 형태로 구성한다. -->
<!-- - 『class=""』 속성은 Controller 객체의 클래스 경로 및 이름을 등록한다. -->
<!--
① 기존코드
※ Annotation 을 활용하여 Controller 객체를 등록할 수 있도록 한다.
-->
<context:component-scan base-package="com.test.mybatis" />
<!--
③ mybatis 등록 과정에서 생겨나는 추가코드 『2』
※ mybatis 를 사용하기 위한 환경 설정을 추가하는 과정에서 필요한
dataSource 를 사용하기 위한 환경 설정 추가
→ SimpleDriverDataSource
-->
<bean id="localDataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver"></property>
<property name="url" value="jdbc:oracle:thin:@211.238.142.49:1521:xe"></property>
<property name="username" value="scott"></property>
<property name="password" value="tiger"></property>
</bean>
<!--
② mybatis 등록 과정에서 생겨나는 추가 코드 『1』
※ mybatis 를 사용하기 위한 환경 설정 추가
→ SqlSessionFactoryBean 등록
-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- ④ dataSource 를 등록하고 와서 다시 추가 -->
<property name="dataSource" ref="localDataSource"></property>
<!--
⑤ 매퍼 파일을 작성하고 와서 다시 추가
//-> 현재 마이바티스에서 사용하게 될 가장 중심이 되는 것은 Mapper라고 할 수 있다.
-->
<property name="mapperLocations" value="classpath:com/test/mybatis/mapper/*.xml"></property>
<!-- >> 클래스 패스 경로는 ~~고 안에 있는 xml 파일들을 사용하면 됨! -->
</bean>
<!--
⑥ mybatis 등록 과정에서 생겨나는 추가 코드 『3』
※ sqlSession 을 사용하기 위한 환경 설정 추가
→ SqlSessionTemplete 등록
-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory"></constructor-arg>
<!-- >> 생성자-인자 리스트의 0번째에 ref 를 넘기며 구성하겠다.// arg = argument -->
</bean>
</beans>
더보기
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>mvc01</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- ※ Spring MVC Framework 등록 -->
<!-- → Front Controller 등록 -->
<!-- → DispatcherServlet 등록 -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
<!-- check -->
<!-- ※ 필터 등록 → 인코딩 필터 등록 → CharacterEncodingFilter -->
<!-- 서블릿 처럼 filter 과 filter-mapping 이 한 쌍 -->
<filter>
<filter-name>encodingFilter</filter-name>
<!-- 필터를 직접 설계한 경우 class 에 경로 입력 -->
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!-- 필터 설정 → 필터에 파라미터 초기값 지정 -->
<init-param> <!-- 처음 파라미터 값을 설정 -->
<!-- CharacterEncodingFilter 가 가지고 있는 파라미터 -->
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern> <!-- 모든 요청에 대해서 적용 / 주소 하나에만 적용할 수 도 있다. -->
</filter-mapping>
</web-app>