*MyBatis
|
-
mapper설정)
-
<mappers>
-
<mapper>
-
....
-
</mappers>
-
mapper.xml (쿼리를 정의하는xml)
-
<insert>, <update>, <delete>, <select>, <sql>중복쿼리를 줄일때, 동적쿼리<dynamic> - OGNL |
*XML을 사용하는 이유
-
이 기종 언어간의 데이터 전달
-
외부로 값을 전달할 때
-
프로그램 내 사용할 값 저장(환경설정)
-
국제화
MyBatis Framework)
1.설정용 XML코딩
Reader r=Resources(MyBatis).getResourceAsReader("src하위경로"); //c:\~아니고 day~부터임
//이 경로가 설정용 xml과 연결해 준다. 설정용은 mapper과 연결.
2.MyBatis Framework생성
SqlSessionFactioryBuilder ssfd=new SqlSessionFactoryBuilder();
3.DB를 연동한 객체 얻기 //DB찍고 얻어옴
SqlSessionFactory ssf=ssfb.builder(r);
4.MyBatis Handler얻기
SqlSession ss=ssf.poenSession();
//이때 ss로 MyBatis를 사용하여 insert(),update(),delete() -트랜잭션이 안되 commit()함께 사용
//selectOne(), selectList() 를 사용해 보았다. |
Log4j로 로그를 쉽게 사용-MyBatis홈페이지에서>Logging>log4j.properties 부분을 긁어와 같은이름으로 만들어 넣어준다.
항상 log4j.properties 이름을 가진 파일이어야 한다. 위치는 src!
주석은 #을 이용하고 Trace로 적어 쿼리가 실행될때마다 볼예정
설정에서 UTF-8로 설정해야 한글사용이 가능하다.
org.apache.ibatis.logging.Logfactory.useLog4JLogging();
위의 문장을 useMyBatis에 쓰는데 사용하려면 log4j를 다운로드해야 한다.
(생성자부분에 해당문장을 넣어주는것으로 사용가능)
http://apache.org/>Logging>Apache Log4j>Download>Dawonload Apache Log4j 2>Previous Releases>binary(zip)?>logging-log4j-1.2.9.zip>파일을 풀어서 log4j-1.2.9.jar를 WEB-INF/lib에 넣어주면 된다.
~~~Z가 나오는 에러가 뜨면 버젼이 맞지 않는것이다!!! 낮추어 줄수도 있지만 서버와 맞는 버전이어야 하기 때문에 맞는 버전을 찾아 다시 받아준다.
log4j/1.3alpha-8에서 logging-log4j-1.3alpha-8.zip을 다시 받아 아까 넣은걸 지우고 넣어주면 잘나옴.(버전이 맞아 나오게 된다)
#파일로 남기는 추가부분
log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.File=C:/dev/mybatis.log
log4j.appender.Threshold=DEBUG
log4j.appender.file.Append=true
log4j.appender.file.DatePattern='.'yyyy-MM-dd'.log'
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p], %d{yyyy-MM-dd HH:mm:ss}, %m %n
log4j.appender.file.encoding=UTF-8
위 소스를 추가해 주면
# log4j.proerties
# LOG 레벨
# 로그를 출력하게 되는 시점 :
# (무조건 찍는다!)TRACE(쿼리가 실행만 되더라도 출력)>DEBUG>INFO>WARN>ERROR(excepption)
# >FATAL(멈출 정도의 심각한 큰오류일 떄 출력)
# 로그 사용시 장점 : 프로그램과 에러출력 코드를 분리해서 작성할 수 있다.
# 코드가 간결해진다.
# 출력시점을 내마음대로 변경가능하다.(개발할땐 TRACE->나중엔 ERROR)
# Global logging configuration
log4j.rootLogger=TRACE, file,stdout
# MyBatis logging configuration...
#log4j.logger.org.mybatis.example.BlogMapper=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
#stdout 콘솔 출력
#파일로 남기는 추가부분
log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.File=C:/dev/mybatis.log
log4j.appender.Threshold=DEBUG
log4j.appender.file.Append=true
log4j.appender.file.DatePattern='.'yyyy-MM-dd'.log'
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p], %d{yyyy-MM-dd HH:mm:ss}, %m %n
log4j.appender.file.encoding=UTF-8
파일로 남기는 추가부분을 입력함으로 mybatis.log로 파일이 계속 저장된다.(로그파일로 출력)
*Properties
오늘부터 properties 를 사용해 만들게 된다.
바뀔수 있는게 아니고 항상 그자리에 있어야한다.
MyBatis홈페이지에서>Configuration XML>properties 참고하여
new 에 others에서 File 로 생성하고 설정에 UTF-8로 변경하는것 주의
//dbcp는 단위테스트가 어려운 반면에 mybatis는 pool로 동작하여 tomcat이 필요 없어져 단위테스트가 쉽다.
//(DAO만 단위테스트가 가능하다는 소리)+service부분으로 하기도 한다고(여기서 하면 DAO+service함께 하는것)
public static void main(String[] args) {
MyBatisDAO m=MyBatisDAO.getInstance();
System.out.println(m.getSessionFactory());//이렇게 단위테스트를 해준다.
}//main
//참고로 jstljar파일이 있어야 에러안남
//+mybitis_config에 <propertis resource="properties/database.properties"/>를 추가해 주어야 한다.
<<<오늘한 예제 코드>>>
# database.properties
# properties는 "이름=값" 의 형태만 가진 설정파일이다.
# 설정 정보를 가장 간단하게 저장할 수 있는 형식
# 공백을 설정하면 값을 가져가는 (파싱) 곳에서도 공백이 포함되므로 절대 공백을 사용하지 않는다.
# 실수가 줄수 있어 사용.
driver=oracle.jdbc.OracleDriver
url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
userid=scott
userpass=tiger
//MyBatisDAO
package kr.co.sist.exam.dao;
import java.io.IOException;
import java.io.Reader;
import java.util.List;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import kr.co.sist.exam.domain.DeptInfo;
public class MyBatisDAO {
private static MyBatisDAO mb_dao;
private SqlSessionFactory ssf=null;
private MyBatisDAO() {
}//MyBatisDAO
public static MyBatisDAO getInstance() {
if(mb_dao==null) {
mb_dao=new MyBatisDAO();
}//end if
return mb_dao;
}//getInstance
public synchronized SqlSessionFactory getSessionFactory() {
if(ssf==null) {
org.apache.ibatis.logging.LogFactory.useLog4JLogging();
Reader reader=null;
try {
//1.설정용 xml 로딩
reader=Resources.getResourceAsReader("kr/co/sist/exam/dao/mybatis_config.xml");
//2.MyBatis Framework 생성
SqlSessionFactoryBuilder ssfb=new SqlSessionFactoryBuilder();
//3.DB와 연동된 객체 받기
ssf=ssfb.build(reader);
if(reader!=null) {reader.close();}//end if
} catch (IOException e) {
e.printStackTrace();
}//end catch
}//end if
return ssf;
}//getSessionFactory
public String singleColumn() {
//MyBatis Handler를 얻어 사용하여 Mapper(xml)에 있는 ID에 찾고 Parsing하여 조회된 결과를 얻는다.
String dname="";
SqlSession ss=getSessionFactory().openSession();
dname=ss.selectOne("singleColumn");
ss.close();
return dname;
}//singleColumn
public DeptInfo multiColumn() {
DeptInfo di=null;
MyBatisDAO mb_dao=MyBatisDAO.mb_dao;
SqlSession ss=mb_dao.getSessionFactory().openSession();
di=ss.selectOne("multiColumn");
ss.close();
return di;
}//multiColumn
public List<Integer> multiRow(){
List<Integer> list=null;
SqlSession ss=getInstance().getSessionFactory().openSession();
list=ss.selectList("multiRow");
ss.close();
return list;
}//multiRow
public static void main(String[] args) {
MyBatisDAO m=MyBatisDAO.getInstance();
//System.out.println(m.getSessionFactory());
//System.out.println(m.singleColumn());
System.out.println(m.multiColumn());
}//main
}//class
//mybatis_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">
<!-- MyBatis의 환경설정(연동할 DB에 대한 설정)을 수행하는 xml
설정 정보를 properties에 넣고 하는 것과
설정 정보를 직접 Hard Coding하는 방법 2가지.
-->
<configuration>
<properties resource="properties/database.properties"/>
<typeAliases>
<typeAlias type="kr.co.sist.exam.domain.DeptInfo" alias="di"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${userid}"/>
<property name="password" value="${userpass}"/>
</dataSource>
</environment>
</environments>
<!-- 쿼리문을 가진 XML을 연결(*:0~n개) -->
<mappers>
<mapper resource="kr/co/sist/exam/mapper/exam_mapper1.xml"/>
<mapper resource="kr/co/sist/exam/mapper/exam_mapper2.xml"/>
</mappers>
</configuration>
//exam_mapper1.xml
<?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">
<!-- Query문을 정의
namespace=ns: XML내에서 중복된 id를 사용할 수 있도록 구분하는 것.
(자바의 패키지와 비슷한 용도)
select 안에 ; 절대 사용하지 않는다!!!
-->
<mapper namespace="kr.co.sist.exam1">
<!-- 컬럼하나에 레코드 하나 조회 할 때 -->
<!-- MyBatis에서는 Java의 데이터형(기본형,참조형)을 그대로 사용할 수 있다.
String data=SqlSession.selectOne("singleColumn"); //을 찾으면 DNAME이 문자열로 나온다.찾기만 하면 return이 된다.
-->
<select id="singleColumn" resultType="String">
SELECT DNAME
FROM DEPT
WHERE DEPTNO=10
</select>
<!-- 컬럼하나에 레코드 여러개 조회 할 때
resultType="자바 데이터형(기본형,참조형)"
호출 : List<데이터형> list=SqlSession.selectList("id");
기본형을 사용해도 되고, 기본형에 대응되는 클래스 - (래퍼)Wrapper class를 사용할 수 있다.
-->
<!-- <select id="multiRow" resultType="int"> -->
<select id="multiRow" resultType="Integer">
select deptno
from dept
</select>
<!-- 컬럼여러개 레코드 하나 조회 할 때 -->
<!-- <typeAlias>: Domain이나 VO를 미리 등록(iBATIS-mapper에 정의->MyBatis-설정파일에 정의)해 두고 짧은 이름으로 사용할 때 사용한다.
자주 쓰면 편하당(여러번 사용되면 유리하고 한번만 사용된다면 안쓰는게 낫겠다)
조회되는 컬럼은 대소문자를 구분하지 않지만 setter method는 대소문자를 구분한다.
iBATIS에서는 컬렴명 또는 컬럼명 as setter명 으로 사용가능?했다?
resultType="패키지명.Domain명 사용되거나 typeAlias의 id가 사용된다."
-->
<select id="multiColumn" resultType="kr.co.sist.exam.domain.DeptInfo">
<!-- <select id="multiColumn" resultType="di"> -->
SELECT DNAME,LOC
FROM DEPT
WHERE DEPTNO=10
</select>
<!-- 컬럼여러개 레코드 여러개 조회 할 때 -->
<!-- < 의 조회 -->
<!-- > 의 조회 -->
<!-- 동일 쿼리의 처리 -->
<!-- like의 조회 -->
<!-- subquery의 조회 -->
<!-- union의 조회 -->
<!-- join의 조회 -->
<!-- join+subquery 의 조회 -->
<!-- 컬럼명 또는 테이블명이 동적일 때의 조회 -->
<!-- dynamic query : where,if,choose,foreach -->
</mapper>
//main.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" type="text/css" href="http://localhost:8080/mybatis_prj/common/main_v190130.css"/>
<style type="text/css">
#wrap{margin:0px auto;width:800px; height:860px;}
#header{width:800px; height:140px; background:#FFFFFF url(http://localhost:8080/mybatis_prj/common/images/header_bg.png) repeat-x;
position: relative; }
#headerTitle{font-family: HY견고딕,고딕; font-size:35px; font-weight:bold; text-align:center;
/* padding-top: 35px */ position:absolute; top:40px; left:290px; }
#container{width:800px; min-height: 600px; }
#footer{width:800px; height:120px; }
#footerTitle{float: right; font-size:15px; padding-top:20px; padding-right:20px; }
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
});//ready
</script>
</head>
<body>
<div id="wrap">
<div id="header">
<div id="headerTitle">SIST Class4</div>
<div style="padding-top:100px; ">
<c:import url="/common/jsp/main_menu.jsp"></c:import>
</div>
</div>
<div id="container">
<c:if test="${not empty param.page}">
<c:import url="day0404/${param.page}.jsp"/>
</c:if>
</div>
<div id="footer">
<div id="footerTitle">copyright© all right reserved. class 4.</div>
</div>
</div>
</body>
</html>
//main_mane.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- smartmenu 시작 -->
<!-- SmartMenus core CSS (required) -->
<link href="http://localhost:8080/mybatis_prj/common/smartmenu/css/sm-core-css.css" rel="stylesheet" type="text/css" />
<!-- "sm-blue" menu theme (optional, you can use your own CSS, too) -->
<link href="http://localhost:8080/mybatis_prj/common/smartmenu/css/sm-simple/sm-simple.css" rel="stylesheet" type="text/css" />
<!-- jQuery -->
<!-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> -->
<!-- SmartMenus jQuery plugin -->
<script type="text/javascript" src="http://localhost:8080/mybatis_prj/common/smartmenu/jquery.smartmenus.js"></script>
<!-- SmartMenus jQuery init -->
<script type="text/javascript">
$(function() {
$('#main-menu').smartmenus({
subMenusSubOffsetX: 1,
subMenusSubOffsetY: -8
});
});
</script>
<!-- smartmenu 끝 -->
<nav id="main-nav">
<!-- Sample menu definition -->
<ul id="main-menu" class="sm sm-simple">
<li><a href="#void">홈으로</a></li>
<li><a href="#void">쿼리 실행</a>
<ul>
<li><a href="#void">1일차</a>
<ul>
<li><a href="main.jsp?page=single_column">컬럼하나에 레코드 하나</a></li>
<li><a href="main.jsp?page=multi_column">컬럼여러개에 레코드 하나</a></li>
<li><a href="main.jsp?page=multi_row">컬럼하나에 레코드 여러개</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
//MyBatisService.java
package kr.co.sist.exam.service;
import java.util.List;
import kr.co.sist.exam.dao.MyBatisDAO;
import kr.co.sist.exam.domain.DeptInfo;
public class MyBatisService {
/**
* 컬럼하나 레코드하나
* @return
*/
public String deptName() {
MyBatisDAO mb_dao=MyBatisDAO.getInstance();
String dname=mb_dao.singleColumn()+"부서";
return dname;
}//deptName -controller가 가져다 사용하게 된다.
/**
* 컬럼여러개 레코드하나
* @return
*/
public DeptInfo deptInfo() {
MyBatisDAO mb_dao=MyBatisDAO.getInstance();
DeptInfo di=mb_dao.multiColumn();
return di;
}//deptInfo
public List<Integer> multiRow(){
List<Integer> list=null;
MyBatisDAO mb_dao=MyBatisDAO.getInstance();
list=mb_dao.multiRow();
return list;
}//multiRow
}//class
//DeptInfo.java
package kr.co.sist.exam.domain;
public class DeptInfo {
private String dname,loc;
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
}
//single_column.jsp
<%@page import="kr.co.sist.exam.service.MyBatisService"%>
<%@page import="kr.co.sist.exam.dao.MyBatisDAO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
MyBatisService mbs=new MyBatisService();
String dname=mbs.deptName();
%>
10번 부서는 <strong><%=dname%></strong> 입니다.
//multi_column.jsp
<%@page import="kr.co.sist.exam.domain.DeptInfo"%>
<%@page import="kr.co.sist.exam.service.MyBatisService"%>
<%@page import="kr.co.sist.exam.dao.MyBatisDAO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
MyBatisService mbs=new MyBatisService();
DeptInfo di=mbs.deptInfo();
%>
10번 부서정보<br/>
부서명 : <strong><%=di.getDname()%></strong><br/>
위치 : <strong><%=di.getLoc()%></strong><br/>
//multi_row.jsp
<%@page import="java.util.List"%>
<%@page import="kr.co.sist.exam.service.MyBatisService"%>
<%@page import="kr.co.sist.exam.dao.MyBatisDAO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
MyBatisService mbs=new MyBatisService();
List<Integer> deptnoList=mbs.multiRow();
pageContext.setAttribute("deptnoList", deptnoList);
%>
<label>부서번호</label>
<select name="deptno">
<c:forEach var="deptno" items="${deptnoList}">
<option value="${deptno}"><c:out value="${deptno}" escapeXml="false"></c:out>
</c:forEach>
</select>