국비지원학원/MyBatis

111일차-MyBatis

초코맛 2019. 4. 17. 03:12
반응형
*MyBatis

  • 설정용.xml (mymatis_config.xml) 사용하려면)
  • driver, URL, ID,PASS
    • =>ojdbc6.jar가 WEB-INF/lib에 들어있어야 하지만....
    • ojdbc6.jar가 Libraries에 이미 들어가 있어 사용가능했던것
    • 원래는 WEB-INF/lib에 넣어 사용한다.
  • mapper설정
    • <mappers>
    •     <mapper>
    •     ....
    • </mappers>
  • mapper.xml (쿼리를 정의하는xml)
    • <insert>, <update>, <delete>, <select>, <sql>중복쿼리를 줄일때, 동적쿼리<dynamic> - OGNL
  • 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&copy; 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>
반응형