티스토리 뷰

[01] iBATIS 개론 



     - 
SQL Maps 프레임워크는 관계형 데이터베이스에 접근할 때 필요한 자바코드를 현저하게 줄일수 있도록 도와줍니다.
     -
 SQL Maps는 간단한 XML서술자를 사용해서 간단하게 자바빈즈를 SQL statement에 맵핑시킵니다.
     
- SQL Map API는 프로그래머에게 자바빈즈를 PreparedStatement파라미터와 ResultSets으로 쉽게 맵핑할수 있도록 함.
     - SQL과 비즈니스 로직이 분리되어 있어 배포 및 유지보수, 재활용성이 뛰어납니다. 
     - 일반 SQL뿐만 아니라 저장 프로시져까지 iBATIS는 처리할 수 있습니다. 
     - 파라미터를 기반으로 동적으로 실행할 SQL을 지정할 수 있습니다
                                                                                 


1. -  iBATIS의 위치 

JSP ---> Spring(Struts2)---> Manager ---> DAO ---> iBATIS ---> SQL ---> ORACLE 
 |                                                                     |  
 |                                                                     |   
 +----- DTO(Value Object, Domain Object ------------+ 



 - iBATIS의 설정의 핵심 개념  


 


- iBATIS의 설정파일  
              
    . SqlMapConfig 파일: 최상단에 위치 하며 전체옵션을 설정하고 각각의 SQL Map파일들의 위치를 지정합니다.  
    
    . Sql Map 파일 : 애플리케이션이 데이터베이스와 소통하기 위해 제공하는 입력 파라미터 값과 조합되는 매핑 구문을 정의 합니다. 



2. 다운 로드 및 설치 (현재는 MyBATIS로 변경됨)


   - http://ibatis.apache.org 
   - ibatis-2.3.4.726.jar 파일을 복사하여 'lib' 폴더에 복사합니다. 



3. SQL Maps 설정 파일 형식

     -sql맵 파일 위치 명시

>>>>> ibatis-2.3.0.677/simple_example/com/mydomain/data/SqlMapConfig.xml 


<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE sqlMapConfig       
    PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"  "http://ibatis.apache.org/dtd/sql-map-config-2.dtd"> 
<sqlMapConfig> 
  <!-- Configure a built-in transaction manager.  If you're using an  
app server, you probably want to use its transaction manager and a managed datasource --> 
  <transactionManager type="JDBC" commitRequired="false"> 
        <dataSource type="SIMPLE"> 
              <property name="JDBC.Driver" value="org.hsqldb.jdbcDriver"/> 
              <property name="JDBC.ConnectionURL" value="jdbc:hsqldb:."/> 
              <property name="JDBC.Username" value="sa"/> 
              <property name="JDBC.Password" value="sa"/> 
        </dataSource> 
  </transactionManager> 

  <!-- List the SQL Map XML files. They can be loaded from the  classpath, as they are here (com.domain.data...) --> 
  <sqlMap resource="com/mydomain/data/Account.xml"/> 
  <!-- List more here... 
  <sqlMap resource="com/mydomain/data/Order.xml"/> 
  <sqlMap resource="com/mydomain/data/Documents.xml"/> 
  --> 

</sqlMapConfig> 



sqlMapConfig파일의 구체적인 설명을 보려면 클릭





4. SQL Map 파일 형식 
     -sql문 

>>>>>> ibatis-2.3.0.677/simple_example/com/mydomain/data/Account.xml 

<?xml version="1.0" encoding="UTF-8" ?> 

<!DOCTYPE sqlMap       
    PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"       
    "http://ibatis.apache.org/dtd/sql-map-2.dtd"> 

<sqlMap namespace="Account"> 

  <!-- Use type aliases to avoid typing the full classname every time. --> 
  <typeAlias alias="Account" type="com.mydomain.domain.Account"/>     간단한 형식선언

  <!-- Result maps describe the mapping between the columns returned 
       from a query, and the class properties.  A result map isn't 
       necessary if the columns (or aliases) match to the properties exactly. --> 
  <resultMap id="AccountResult" class="Account"> 
    <result property="id" column="ACC_ID"/> 
    <result property="firstName" column="ACC_FIRST_NAME"/> 
    <result property="lastName" column="ACC_LAST_NAME"/> 
    <result property="emailAddress" column="ACC_EMAIL"/> 
  </resultMap> 

  <!-- Select with no parameters using the result map for Account class. --> 
  <select id="selectAllAccounts" resultMap="AccountResult">       
    select * from ACCOUNT 
  </select> 

  <!-- A simpler select example without the result map.  Note the  
       aliases to match the properties of the target result class. --> 
  <select id="selectAccountById" parameterClass="int" resultClass="Account"DTO

select한 결과가 resultClass Account에 저장됨

id는 여러개의 select가 있을 때 구분하기 위해서..쓴다

    select 
      ACC_ID as id,    컬럼명 as ailias(Account DTO의 property필드명과 왼쪽 DB컬럼값 이 둘의 이름은 같아야 한다, 

                                                  다르다면 alias 별명을 붙여서 같게 만들어 주어야 한다)
      ACC_FIRST_NAME as firstName, 
      ACC_LAST_NAME as lastName, 
      ACC_EMAIL as emailAddress 
    from ACCOUNT 
    where ACC_ID = #id#             파라미터 클래스는 int이고 여기서는 ? 가 아니다.
  </select> 
    
  <!-- Insert example, using the Account parameter class --> 
  <insert id="insertAccount" parameterClass="Account"> 
    insert into ACCOUNT ( 
      ACC_ID, 
      ACC_FIRST_NAME, 
      ACC_LAST_NAME, 
      ACC_EMAIL 
    )values ( 
      #id#, #firstName#, #lastName#, #emailAddress#       Account에 있는 컬럼들이 자동으로 ##getter이용해서 들어감
    ) 
  </insert> 

  <!-- Update example, using the Account parameter class --> 
  <update id="updateAccount" parameterClass="Account"> 
    update ACCOUNT set 
      ACC_FIRST_NAME = #firstName#, 
      ACC_LAST_NAME = #lastName#, 
      ACC_EMAIL = #emailAddress# 
    where 
      ACC_ID = #id# 
  </update> 

  <!-- Delete example, using an integer as the parameter class --> 
  <delete id="deleteAccountById" parameterClass="int"> 
    delete from ACCOUNT where ACC_ID = #id# 
  </delete> 

</sqlMap> 





5. SqlMapClient API를 통해 statement를 수행하기.



-  SqlMapClient인스턴스는  SqlMapClientBuilder를 사용해서 빌드된다. 
   이 클래스는 buildSqlMap()이라는 하나의 중요한 정적 메소드를 가진다.

-  buildSqlMap()메소드는 간단하게 sqlMap-config.xml의 내용을 읽을수 있는 Reader인스턴스를 가져온다.

public MyAppSqlConfig {
private static final SqlMapClient sqlMap;                여기 안에 있는 메소드를 이용해서 xml안의 태그 호출
static {
  try {
      String resource = “com/ibatis/example/sqlMap-config.xml”;
      Reader reader = Resources.getResourceAsReader (resource);
      sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
  } catch (Exception e) {
      e.printStackTrace();
     throw new RuntimeException (“Error initializing MyAppSqlConfig class. Cause: ” + e);
 }
}
public static SqlMapClient getSqlMapInstance () {
        return sqlMap;
}
}




 - SqlMapClient는 이것에 관련된 모든 맵핑된 statement를 수행하기 위한 API를 제공한다. 그 메소드들은 아래와 같다.


public Object insert(String statementName, Object parameterObject)           태그 id와 insert할 내용DTO
throws SQLException
 
public int update(String statementName, Object parameterObject)
throws SQLException
 
public int delete(String statementName, Object parameterObject)      태그 id, 삭제할때 사용할 파라미너
throws SQLException
 
public Object queryForObject(String statementName, Object parameterObject)  저장할 객체..DTO반환
throws SQLException
 
public Object queryForObject(String statementName, Object parameterObject, Object resultObject)
throws SQLException
 
public List queryForList(String statementName, Object parameterObject)    저장할 list 반환
throws SQLException
 
public List queryForList(String statementName, Object parameterObject, int skipResults, int maxResults)
throws SQLException
 
                               :
                               :




SQL Map XML 파일 


<sql> 


refid - <sql>로 생성된 쿼리문을 refid=id 로 해서 <include>로 가져온다. 
  
    <sql id="boardWhere"
       <isNotEmpty property="keyword" prepend="AND"> 
          <isEqual property="keytype" compareValue="title"> 
              title LIKE '%' || #keyword# || '%' 
          </isEqual> 
          <isEqual property="keytype" compareValue="content"> 
              contents LIKE '%' || #keyword# || '%' 
          </isEqual> 
          <isEqual property="keytype" compareValue="userid"> 
              userid LIKE '%' || #keyword# || '%' 
          </isEqual> 
          <isEqual property="keytype" compareValue="all"> 
           (  
               title LIKE '%' || #keyword# || '%' 
               OR 
               contents LIKE '%' || #keyword# || '%' 
               OR 
               userid LIKE '%' || #keyword# || '%' 
           ) 
          </isEqual> 
       </isNotEmpty> 
    </sql> 

  
     <select id="getList" parameterClass="boardCmd" resultMap="domain"> 
         SELECT 
             boardSeq, categoryId, userid, title, contents, hit, regDate, grp, dep, stp,  
             commCnt, attachCnt, isReply, rowNum 
         FROM ( 
             SELECT 
                boardSeq, categoryId, userid, title, contents, hit, regDate, grp, dep, stp,  
                commCnt, attachCnt, isReply,  
                ROW_NUMBER() OVER(ORDER BY grp DESC, stp) as rowNum 
             FROM 
                board 
             WHERE 
                categoryId = #categoryId# 
                <dynamic> 
                     <include refid="boardWhere" /> 
               </dynamic> 
            ) 
         WHERE rowNum BETWEEN #start# AND #end# 
     </select> 




<parameterMap> 


parameterMap - ?,? 표시로 접근, parameterMap 태그를 따로 선언해야함 , 

                      맵형식의 값을 파라미터로 전달해야 할 때 사용. (한번에 많은 값 전달 시에 쓰는 것 같음)


    <parameterMap id="boardColumnclass="Board"> 
        <parameter property="boardSeq" jdbcType="NUMBER"  />     1번째 물음표 값
        <parameter property="title" jdbcType="NVARCHAR"  />         
2번째 물음표 

        <parameter property="contents" jdbcType="NTEXT"  />         3번째 물음표 

    </parameterMap> 
     

  <insert id="insert" parameterMap="boardColumn"> 
        INSERT INTO board ( 
            boardSeq, title, contents 
        ) VALUES ( 
            ?, ?, ? 
        ) 
    </insert> 





<selectKey> 


- 자동 key 생성 , 자동증가


    <insert id=""  parameterClass="BoardDTO" ..   >


    <selectKey keyProperty="boardSeq" resultClass="int">     

keyProperty : DTO 필드(멤버변수)/boardSeq는 num같은거

        SELECT nextVal(#sequence#)        

selectKey값을 사용하면 리턴형이 시퀀스번호의 객체형이다  (10이면 Integer 10)

안썼다면 null 반환, 

    </selectKey> 


    INSERT (....) VALUES (#boardSeq#, ...) Table 


    </insert>


insert후에 그 Primary 키가 필요할 떄 사용

보통의 경우에는 insert한 개수를 얻어오기 위해 update태그 안에 넣어 준다. 이런경우에는 update 태그를 호출해 주어야 함





<Result Map>   Collection  (한방쿼리) 


resultMap -  resultClass와 같은 역할하며 resultMap 태그를 따로 선언해야함 
              -  컬럼의 이름과 저장할 객체에 필드가 이름이 다를때 사용 



    - BoardDTO.java 


    private int boardSeq ;

    private String title;

    private String contents;

    private List<Attachment> attachList; 

              :



    - BoardDao.java 


    getSqlMapClientTemplate().queryForObject("Board.get", 10);  //namespace명.id,  

parameterClass int형식의 #value#의 값

                           :


    <sqlMap namespace="Board"> 


    <resultMap id="boardView" class="BoardDTO"> 

    <result property="boardSeq" column="boardSeq" /> 

    <result property="title" column="title" /> 

    <result property="contents" column="contents" /> 

    <result property="attachList" select="Board.getAttachList" column="boardSeq" /> 

                                                     //namespace명.id

    </resultMap>     


    <select id="get" parameterClass="int" resultMap="boardView"> 

    SELECT boardSeq, title, contents FROM board 

    WHERE boardSeq = #value# 

    </select> 

      

    <select id="getAttachList" parameterClass="int" resultClass="Attachment"> 

        SELECT boardSeq, attachSeq, fileName FROM attachment WHERE boardSeq = #value# 

    </select> 

    </sqlMap> 

     

resultMap의 <result> 프로퍼티 들은 자바 객체의 변수로 선언되어 잇어야 하며, get/set 메소드가 설정되어 있어야 한다

    - property : 자바빈 객체(BoardDTO)의 멤버변수이름

    - column : 쿼리 결과 ResultSet 내의 칼럼의 이름


   -select 시 column값은 기존과 다르게 파라미터처럼 전달되는 값으로 사용된다.
이름 지정이 필요할 경우는 column ={"key1=column1, key2=column2..}" 의 형태로 나열하면 된다


고: http://hyeonstorage.tistory.com/285 [개발이 하고 싶어요] 

  




<parameterMap>   동적맵핑 문장  (다이나믹 쿼리) 

  


    <select id="get" parameterClass="cmd" resultClass="board"> 

    SELECT * 

    FROM board 

    <dynamic prepend=" WHERE " open="(" close=")"> 


    <isNotEmpty property="keyword"> 

    <isEqual property="keytype" compareValue="title"> 

        title LIKE '%' || #keyword# || '%' 

    </isEqual> 


    <isEqual property="keytype" compareValue="content"> 

        contents LIKE '%' || #keyword# || '%' 

    </isEqual> 

    </isNotEmpty> 


    </dynamic> 

    </select> 



   <select id="board parameterClass="cmd" resultClass="Board"> 

    SELECT * FROM board 


    <dynamic prepend=" WHERE "> 


    <isEqual property="userType" compareValue="ADMIN"> 

        userType = 'ADMIN' 

    </isEqual> 


    <isNotEqual property="userType" compareValue="ADMIN"> 

        userType <> 'ADMIN' 

    </isNotEqual> 


    </dynamic> 

    </select> 


  

 dynamic 요소


     property – 비교되는 프라퍼티(필수)


     [prepend] – statement에 붙을 오버라이딩 가능한 SQL부분


     [open] – 결과적인 전체내용물을 열기위한 문자열


     [close] – 결과적인 전체내용물을 닫기위한 문자열


  


 이항연산 


 removeFirstPrepend - 처음으로 내용을 출력하는 자식 요소의 prepend속성 값을 출력할지 여부 


 comparePreperty - property 속성과 비교할 파라미터 객체의 프로퍼티 


 compareValue - property 속성과 비교할 정적인 값 


 <isEqual> / <isNotEqual> 


 <isGreaterThan> - 값이 큰지 


 <isGreaterEqual> - 값이 크거나 같은지 


 <isLessThan> - 값이 작은지 


 <isLessEqual> - 값이 작거나 같은지 


  


 단항연산 


removeFirstPrepend - 처음으로 내용을 출력하는 자식 요소의 prepend속성 값을 출력할지 여부 


<isPropertyAvailable> - 프로퍼티가 파라메터에 존재하는지 검사, domain에서는 프로퍼티를, Map에서는 key를 찾는다. 


<isNotPropertyAvailable> - 프로퍼티가 파라메터에 존재하지 않는지 검사, domain에서는 프로퍼티를, Map에서는 key를 찾는다. 


<isNull> / <isNotNull> 


<isEmpty>  / <isNotEmpty> 


  


파라미터 요소 (parameterClass, parameterMap) 


<isParameterPresent> - 파라메터가 존재하는지 


<isNotParameterPresent> - 파라메터가 존재하지 않는지 


  

    <select id="board" resultClass="Board">

    SELECT * FROM board 


    <isParameterPresent prepend=" WHERE "> 

    <isNotEmpty property="category"> 

        category = #category# 

    </isNotEmpty> 

    </isParameterPresent> 

    </select> 





ibatis/board.xml



board.xml

    <delete id="deleteXE" parameterClass="map"> 

    DELETE  FROM  board 


    <dynamic prepend=" WHERE "> 

    <iterate property="boardSeqs"   open=" num IN ("   close=")"   conjunction=","> 

        #boardSeqs[]

    </iterate> 

    </dynamic> 

    </delete> 


->dynamic 문장: where문에 iterate로 반복처리하면서 num IN(으로 시작할거고 ,를 중간마다 붙여주면서 )으로 끝낼거야.

그 값들은 boardSeqs[]안에 있는 값들 일거야. 여기서 property의 boardSeqs는 단지 for문의 i나 iterater의 value..?같이 의미없는 것 같음


  sql 결과:   delete from board 

                where num in (2,4,6,8);



BoardDAO.java


     :

@Autowired

private SqlMapClientTemplate ibatis;

 

public void setIbatis (SqlMapClientTemplate ibatis) {

     this.ibatis = ibatis;

}

     

public int deleteXE() throws Exception {                        

    int boardSeqs[] = {2,4,6,8};

    Map map = new HashMap();

    map.put("boardSeqs", boardSeqs);

    return  ibatis.delete("board.deleteXE", map) ;                        sqlmap 파일(board.xml)의 delete id가 deleteXE인 태그를 

호출하여 결과값 리턴받은것을 리턴함

}


        


BoardTest.java


package spring.sts.model;

 

import org.springframework.beans.factory.BeanFactory;

import org.springframework.beans.factory.xml.XmlBeanFactory;

import org.springframework.core.io.ClassPathResource;

import org.springframework.core.io.Resource;

 

public class BoardTest {

 

public static void main(String[] args) throws Exception {

 

Resource rs = new ClassPathResource("board.xml");

 

BeanFactory factory  = new XmlBeanFactory(rs);

 

BoardDAO dao = (BoardDAO) factory.getBean ("dao");       board.xml에서 객체생성한 DAO객체를 가져온다

        

int cnt = dao.deleteXE();                                               DAO 메소드 호출


System.out.println("cnt:"+cnt);

if(cnt>0){

      System.out.println("성공");

}else{

      System.out.println("실패");

}

}

 

}


 


>>>>> src/main/resources/ibatis-config.xml


<?xml version="1.0" encoding="UTF-8" ?> 

 

<! DOCTYPE sqlMapConfig 

    PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN" 

    "http://ibatis.apache.org/dtd/sql-map-config-2.dtd"> 

 

<!-- SQL Mapping file list --> 

<sqlMapConfig>   

    <settings 

         useStatementNamespaces="true" 

    /> 

 

    <sqlMap resource="ibatis/board.xml" /> 

 

</ sqlMapConfig> 

  


sqlMapConfig: 전역정보 설정파일, sql Map파일의 위치 명시 등

sql Map 파일 : sql문 




porm.xml에 추가


 <!-- iBATIS setting -->         
<dependency> 
  <groupId>org.apache.ibatis</groupId> 
  <artifactId>ibatis-sqlmap</artifactId> 
  <version>2.3.4.726</version> 
</dependency> 
 <!-- DBCP setting -->  
    <dependency>  
  <groupId>commons-dbcp</groupId> 
  <artifactId>commons-dbcp</artifactId> 
  <version>1.4</version> 
</dependency> 
<dependency> 
  <groupId>org.springframework</groupId> 
  <artifactId>spring-orm</artifactId> 
  <version>${org.springframework-version}</version> 
</dependency>  

<!-- Oracle JDBC Driver--> 

<dependency>
   <groupId>com.oracle</groupId>
   <artifactId>ojdbc6</artifactId>
   <version>11.1.0.7.0</version>
</dependency>


   :
   :
   <repositories> 

      <repository>
        <id>oracle</id>
     <name>ORACLE JDBC Repository</name> 
    <url>http://maven.jahia.org/maven2</url>
    </repository>
    </repositories>
</project>





root-context.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"                           (4번째줄에 추가)

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 



<bean id="dao" class="spring.model.board.BoardDAO"    사용할 DAO 객체 생성

      p:ibatis-ref = "sqlMapClientTemplate"

   />


<!-- 데이터베이스 접속 설정 --> 
<bean id="dataSource" 
class="org.apache.commons.dbcp.BasicDataSource" 
p:driverClassName="oracle.jdbc.driver.OracleDriver" 
p:url="jdbc:oracle:thin:@127.0.0.1:1521:XE" 
p:username="soldesk"  
p:password="1234"  
p:maxActive="2" 
p:maxIdle="1" 
p:defaultAutoCommit="true" 
/> 


<!-- iBATIS SQL 실행 클래스  --> 
<bean id="sqlMapClient" 
class="org.springframework.orm.ibatis.SqlMapClientFactoryBean" 
p:dataSource-ref="dataSource" 
p:configLocation="WEB-INF/spring/ibatis-config.xml" /> 

<!--  Spring과 iBATIS 연결자 -->     
<bean id="sqlMapClientTemplate"  
  class="org.springframework.orm.ibatis.SqlMapClientTemplate" 
  p:sqlMapClient-ref="sqlMapClient" />


'IBATIS MYBATIS' 카테고리의 다른 글

[MyBatis] MyBatis 특징, SqlSession생성, SQL 문장 실행  (0) 2018.04.23
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
TAG
more
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함