[Spring] iBatis 2


iBatis 2


1. sqlMapConfig.xml: 설정파일

iBATIS 의 메인 설정 파일인 SQL Map XML Configuration 파일(이하 sqlMapConfig.xml 설정 파일) 작성과 상세한 옵션 설정에 대해 알아본다.


(1) sqlMapConfig.xml

SqlMapClient 설정관련 상세 내역을 제어할 수 있는 메인 설정 파일로 주로 transaction 관리 관련 설정 및 다양한 옵션 설정, Sql Mapping 파일들에 대한 path 설정 등을 포함한다.

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

<!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"

    "http://www.ibatis.com/dtd/sql-map-config-2.dtd">

<sqlMapConfig>

<properties resource="META-INF/spring/jdbc.properties" />

 

<settings cacheModelsEnabled="true" enhancementEnabled="true"

lazyLoadingEnabled="true" maxRequests="128" maxSessions="10"

maxTransactions="5" useStatementNamespaces="false"

defaultStatementTimeout="1" />

 

<typeHandler javaType="java.util.Calendar" jdbcType="TIMESTAMP"

callback="egovframework.rte.psl.dataaccess.typehandler.CalendarTypeHandler" />

 

<transactionManager type="JDBC">

<dataSource type="DBCP">

<property name="driverClassName" value="${driver}" />

<property name="url" value="${dburl}" />

<property name="username" value="${username}" />

<property name="password" value="${password}" />

<!-- OPTIONAL PROPERTIES BELOW -->

<property name="maxActive" value="10" />

<property name="maxIdle" value="5" />

<property name="maxWait" value="60000" />

<!-- validation query -->

<!--<property name="validationQuery" value="select * from DUAL" />-->

<property name="logAbandoned" value="false" />

<property name="removeAbandoned" value="false" />

<property name="removeAbandonedTimeout" value="50000" />

<property name="Driver.DriverSpecificProperty" value="SomeValue" />

</dataSource>

</transactionManager>

<sqlMap resource="META-INF/sqlmap/mappings/testcase-basic.xml" />

<sqlMap ../>

..

</sqlMapConfig>

- properties : 표준 java properties (key=value 형태)파일에 대한 연결을 지원하며 설정 파일내에서 ${key} 와 같은 형태로 properties 형태로 외부화 해놓은 실제의 값(여기서는 DB 접속 관련 driver, url, id/pw)을 참조할 수 있다. resource 속성으로 classpath, url 속성으로 유효한 URL 상에 있는 자원을 지정 가능하다.


- settings : 이 설정 파일을 통해 생성된 SqlMapClient instance 에 대하여 다양한 옵션 설정을 통해 최적화할 수 있도록 지원한다. 모든 속성은 선택사항(optional) 이다.

 속 성

설 명 

example, default 

 maxRequests

 같은 시간대에 SQL문을 실행한 수 있는 thread 의 최대 갯수 지정.

 maxRequests=“256”, 512

 maxSessions

 주어진 시간에 활성화될 수 있는 session(또는 client) 수 지정.

 maxSessions=“64”, 128

 maxTransactions

 같은 시간대에 SqlMapClient.startTransaction() 에 들어갈 수 있는 최대 갯수    지정.

 maxTransactions=“16”, 32

 cacheModelsEnabled

 SqlMapClient 에 대한 모든 cacheModel 에 대한 사용 여부를 global 하게 지  정.

 cacheModelsEnabled=“true”, true (enabled) 

 lazyLoadingEnabled

 SqlMapClient 에 대한 모든 lazy loading 에 대한 사용 여부를 global 하게 지정

 lazyLoadingEnabled=“true”, true (enabled)

 enhancementEnabled

 runtime bytecode enhancement 기술 사용 여부 지정.

 enhancementEnabled=“true”, false (disabled)

 useStatementNamespaces

 mapped statements 에 대한 참조 시 namespace 조합 사용 여부 지정. true  인 경우  queryForObject(“sqlMapName.statementName”); 과 같이 사용함.

 useStatementNamespaces=“false”, false (disabled)

 defaultStatementTimeout

 모든 JDBC 쿼리에 대한 timeout 시간(초) 지정, 각 statement 의 설정으로  override 가능함. 모든 driver가  이 설정을 지원하는 것은 아님에 유의할 것.

  정하지 않는 경우 timeout 없음(cf. 각 statement 설정에 따라)

 classInfoCacheEnabled

 introspected(java 의 reflection API에 의해 내부 참조된) class의 캐쉬를 유지  할지에 대한 설정

 classInfoCacheEnabled=“true”, true (enabled)

 statementCachingEnabled

 prepared statement 의 local cache 를 유지할지에 대한 설정

 tatementCachingEnabled=“true”, true (enabled)


- typeHandler : javaType ↔ jdbcType 간의 변환(prepared statement 의 파라메터 세팅/resultSet 의 값 얻기)을 처리하는 typeHandler 구현체를 등록할 수 있다.


- transactionManager : 트랜잭션 관리 서비스를 설정할 수 있다. type 속성으로 어떤 트랜잭션 관리자를 사용할지 지시할 수 있는데, JDBC, JTA, EXTERNAL 의 세가지 트랜잭션 관리자가 프레임워크에 포함되어 있다. 위에서는 일반적인 Connection commit()/rollback() 메서드를 통해 트랜잭션을 관리하는 JDBC 타입으로 설정하였다.


- dataSource : transactionManager 설정의 일부 영역으로 DataSource 에 대한 설정이다. type 속성으로 어떤 DataSourceFactory 를 사용할지 지시할 수 있는데, SIMPLE, DBCP, JNDI 의 세가지 설정이 가능하다. 위에서는 Apache Commons DBCP(Database Connection Pool) 를 사용하는 DBCP 타입으로 설정하였다. iBATIS 는 DBCP 속성에 대한 설정을 직접 명시할 수 있도록 지원하고 있다. iBATIS 2 버전 이후로는 단일 dataSource 만 지원한다.


- sqlMap : 명시적으로 각 SQL Map XML 파일을 포함하도록 설정한다. classpath (resource 속성으로 지정) 나 url(url 속성으로 지정) 상의 자원을 stream 형태로 로딩하게 된다. 위에서는 classpath 상에 존재하는 sql 매핑 파일을 지정하였다.


이 외에도 typeAlias(global 한 type 별명-풀패키지명에 비해 간략히), resultObjectFactory (SQL 문의 실행에 의한 결과 객체의 생성을 iBATIS 의 ResultObjectFactory 인터페이스를 구현한 factory 클래스를 통해 처리할 수 있도록 지원) 에 대한 설정이 가능하다. DTD 상 sqlMap 설정은 하나 이상이 필요하고 다른 설정은 선택사항이다.


2. SQL Map XML 파일: 매핑파일

sql 매핑 파일은 iBATIS 의 mapped statement 형태로 처리될 수 있도록 SQL Map 문서 구조에 따라 다양한 옵션 설정 및 매핑 정의, sql 문을 외부화하여 저장하는 파일이다.


(1) sqlMap.xml

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

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

<sqlMap namespace="Dept">

<typeAlias alias="deptVO" type="egovframework.DeptVO" />

 

<resultMap id="deptResult" class="deptVO">

<result property="deptNo" column="DEPT_NO" />

<result property="deptName" column="DEPT_NAME" />

<result property="loc" column="LOC" />

</resultMap>

 

<insert id="insertDept" parameterClass="deptVO">

insert into DEPT

          (DEPT_NO,

           DEPT_NAME,

           LOC)

values     (#deptNo#,

           #deptName#,

           #loc#)

</insert>

 

<select id="selectDept" parameterClass="deptVO" resultMap="deptResult">

<![CDATA[

select DEPT_NO,

      DEPT_NAME,

      LOC

from   DEPT

where  DEPT_NO = #deptNo#

]]>

</select>

</sqlMap>

- typeAlias : 현재 매핑 파일내에서 객체에 대한 간략한 alias 명을 지정함. (cf. 매우 자주 쓰이는 class 의 경우 sqlMapConfig.xml 에 global 하게 등록하는 것이 좋음)


- resultMap : DB 칼럼명(select 문의 칼럼 alias) 과 결과 객체의 attribute 에 대한 매핑 및 추가 옵션을 정의함.


- insert, select : 각 statement 타입에 따른 mapped statement 정의 요소 예시. 유형에 따라 insert/update/delete/select/procedure/statement 요소 사용 가능

이 외에도 parameterMap, resultMap 에 대한 상세 정의, cacheModel 설정, sql 문 재사용을 위한 sql 요소 설정이 나타날 수 있다. 각각에 대한 상세 사항은 관련 가이드를 참고한다.


3. sqlMapclientFactoryBean 작성

SqlMapClientFactoryBean 은 iBATIS 의 SqlMapClient 를 생성하는 FactoryBean 구현체로, Spring 의 context 에 iBATIS 의 SqlMapClient 를 셋업하는 일반적인 방법으로 사용된다. 여기서 얻어진 SqlMapClient 는 iBATIS 기반 DAO 에 dependency injection 을 통해 넘겨지게 된다.

<!-- dataSource 설정 -->

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

<property name="driverClassName" value="${driver}"/>

<property name="url" value="${dburl}"/>

<property name="username" value="${username}"/>

<property name="password" value="${password}"/>

<property name="defaultAutoCommit" value="false"/>

<property name="poolPreparedStatements" value="true"/>

</bean>

 

<!-- SqlMap setup for iBATIS Database Layer -->

<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">

<property name="configLocation" value="classpath:/META-INF/sqlmap/sqlMapConfig.xml"/>

<property name="dataSource" ref="dataSource"/>

</bean>

- dataSource : 데이터베이스 연결 추상화를 제공하는 DataSource 설정. 위에서는 Apache Commons DBCP 를 사용하였으며 DB 접속과 관련된 설정은 property-placeholder 를 사용하여 외부화 하였다.

- sqlMapClient : Spring의 iBATIS 연동을 위한 SqlMapClientFactoryBean 설정으로 configLocation 속성을 통해 지정한 iBATIS 메인 설정 파일인 sqlMapConfig.xml에 대해 iBATIS 의 SqlMapClient instance 를 생성하여 Spring 환경에서 사용 가능토록 한다. 

Spring 의 dataSource 를 iBATIS 에 넘길 수 있도록 injection 을 지시하고 있으며 이로 인해 iBATIS 설정 파일 자체에서는 dataSource 및 transaction 설정 필요없이(Spring 환경에서는 iBATIS 기반 DAO 호출 이전에 서비스 단에서 선언적인 트랜잭션 처리를 해주었을 것임) Spring 이 제공하는 유연한 dataSource 및 트랜잭션 처리를 사용하게 된다.


Spring 현재 버전에서는 configLocations 속성을 추가하여 sql-map-config.xml 에 대한 패턴 표현식이나 복수 연동(런타임에 하나의 통합 설정으로 merge 됨)도 지원하고 있다. useTransactionAwareDataSource 속성으로 SqlMapClient 에 대해 Spring 이 관리하는 transaction timeout 을 함께 적용할 수 있는 transaction-aware DataSource 를 사용하도록 설정 가능하며(default), lobHandler 속성을 통해 Spring 의 lobHandler 를 설정할 수도 있다.


cp.) mappingLocations 지원

또한 iBATIS 사용 환경에서의 중요한 개선 사항으로 mappingLocations 속성을 통해 기존에 iBATIS 메인 설정 파일 내에서 sqlMap 태그로 일일이 지정하여야만 했던 sql 매핑 파일에 대해 Spring 의 SqlMapClientFactoryBean 빈 설정파일에서 Spring 의 유연한 리소스 추상화를 적용하여 리소스 패턴 형태로 일괄 지정이 가능하다. 이 경우 sql 매핑 파일들의 위치는 sqlMapConfig 설정 파일과 런타임에 merge 되도록 세팅된다. 이 방법은 Spring 2.5.5 이상, iBATIS 2.3.2 이상에서만 지원됨에 유의한다.

<!-- SqlMap setup for iBATIS Database Layer -->

<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">

<property name="configLocation" value="classpath:/META-INF/sqlmap/sqlMapConfig.xml" />

<property name="mappingLocations" value="classpath:/META-INF/sqlmap/mappings/testcase-*.xml" />

<property name="dataSource" ref="dataSource" />

</bean>

단 위와 같이 일괄 sql 매핑 파일 지정을 Spring 설정 파일에 지시하였더라도 iBATIS 의 sqlMapConfig.xml 의 DTD(http://www.ibatis.com/dtd/sql-map-config-2.dtd) 에 sqlMap 태그가 최소 1개 이상이 나타나야 하도록 지정되어 있으므로 아래와 같이 dummy sql 매핑 파일 하나를 지정하는 sqlMapConfig.xml 로 작성하면 편할 것이다.


4. SQLMapClient를 구현하는 DAO 작성

사원정보의 SELECT, INSERT 작업을 담당하는 DAO를 작성한다.


(1) EmpDAO class 작성

- SqlMapClient를 이용하여 사원정보의 DB 작업을 담당하는 DAO를 작성한다.

- com.spring.mvc.emp.dao 패키지를 생성한다.

- SqlMapClientDaoSupport를 상속받아 getSqlMapClientTemplate() 메소드를 이용하여 등록 및 조회작업을 한다.

cf.) 

@Repository 어노테이션을 EmpDAO의 class선언부에 추가한다.

@Repository 어노테이션을 지정하면 SqlMapClient 클래스에 대한 객체가 자동생성 된다.


Spring 의 SqlMapClientDaoSupport 클래스는 iBATIS 의 SqlMapClient data access object 를 위한 편리한 수퍼 클래스로 이를 extends 하는 서브 클래스에 SqlMapClientTemplate 를 제공한다. 

SqlMapClientTemplate 는 iBATIS 를 통한 data access 를 단순화하는 헬퍼 클래스로 SQLException 을 Spring dao 의 exception Hierarchy 에 맞게 unchecked DataAccessException 으로 변환해 주며 Spring 의 JdbcTemplate 과 동일한 처리 구조의 SQLExceptionTranslator 를 사용할 수 있게 해준다. 또한 iBATIS 의 SqlMapExecutor 의 실행 메서드에 대한 편리한 mirror 메서드를 다양하게 제공하므로 일반적인 쿼리나 insert/update/delete 처리에 대해 편리하게 사용할 수 있도록 권고된다. 

그러나 batch update 와 같은 복잡한 수행에 대해서는 Spring 의 SqlMapClientCallback 에 대한 명시적인 구현(보통 anonymous inner class 로 작성)이 필요하다.

com.spring.mvc.emp.dao.EmpDAO.java

package com.spring.mvc.emp.dao;


import java.util.List;

import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

import com.spring.mvc.emp.model.Emp;


public class EmpDAO extends SqlMapClientDaoSupport {

    private static final String NAMESPACE = "emp.";


    @SuppressWarnings("unchecked")

    public List<Emp> selectEmpList() {

        return (List<Emp>) getSqlMapClientTemplate().queryForList(NAMESPACE + "selectEmpList");

    }


    public void insertEmp(Emp emp) {

        getSqlMapClientTemplate().insert(NAMESPACE + "insertEmp", emp);

    }

}


(2) plicationContext-dao.xml 설정

applicationContext-dao.xml에 EmpDAO 빈등록 작업을 한다.

iBATIS 연동 DAO 에 sqlMapClient 빈을 주입(의존성 주입)해 주어야 한다.

/srping/applicationContext-dao.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:aop="http://www.springframework.org/schema/aop"

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

    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

      

    <bean id="empDAO" class="com.spring.mvc.emp.dao.EmpDAO" >

        <property name="sqlMapClient" ref="sqlMapClient"/>           

    </bean>   

</beans>

iBATIS 연동 DAO 는 SqlMapClientDaoSupport 를 extends 하고 있으며, getSqlMapClientTemplate() 를 통해 SqlMapClientTemplate 를 얻어 iBATIS 의 data access 처리를 래핑하여 실행토록 처리하고 있다.


'Programing > Spring' 카테고리의 다른 글

[Spring] 어노테이션 기반 설정  (0) 2014.12.17
[Spring] 외부 설정 프로퍼티  (0) 2014.12.17
[Spring] iBatis 1  (0) 2014.12.16
[Spring] web.xml 기본 설정  (1) 2014.12.13
[spring] 스프링 MVC 인터페이스 구현 클래스  (0) 2014.12.13