상세 컨텐츠

본문 제목

ibatis sqlMap 설정하기

IT 세상/자바세상

by 이현민 (지후지율아빠) 2009. 10. 27. 10:47

본문


SQL Map 설정 파일 (SqlMapConfig.xml)은 iBatis의 중심이 되는 파일이다. 
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>
  <properties resource="db.properties"/>

  <!-- 글로벌 설정 옵션 영역 -->
  <settings
    useStatementNamespace="false"
    cacheModelsEnabled="true"
    enhancementEnabled="true"
    lazyLoadingEnabled="true"
    maxRequests="32"
    maxSession="10"
    maxTransactions="5"
  />

  <!-- 트랜잭션 관리자 -->
  <transactionManager type="JDBC">
    <dataSource type="SIMPLE">
      <property name="JDBC.Driver" value="${driver}"/>
      <property name="JDBC.ConnectionURL" value="${url}"/>
      <property name="JDBC.Username" value="${user}"/>
      <property name="JDBC.Password" value="${pword}"/>
    </dataSource>
 </transactionManager>

<!-- SqlMap 파일 참조 -->
<sqlMap resource="org/apache/mapper2ii15/SqlMap.xml"/>

</sqlMapConfig>

1. <properties> 엘리먼트
<properties>엘리먼트는 이름/값 쌍으로 구성된 메인 설정 파일에 앞으로 사용될 설정을 지정하는 곳이다. 이것은 애플리케이션 개발에 매우 유용하다. 왜냐하면 환경 설정에 의존되는 공유 설정 내용에 분리되어 이용할 수 있도록 한다.
프로퍼티 파일을 이용하는 데는 2가지 방법이 있다. 각 속성은 다음과 같이 지정한다.

  • resource - 클래스 패스에 있는 자원 혹은 파일
  • url - Uniform Resource Locator(URL)
resource 속성을 이용할때 classloader은 애플리케이션의 클래스 패스에 있는 자원의 위치에서 값을 가져온다.
이것은 resource라고 불리며, 클래스 로더가 이값을 읽을 것이다. Java 도큐먼트는 이러한 방법으로 데이터파일에 접근을 하며, JAR파일 내의 엔트리까지 읽을 수 있다. 그리고 서로다른 컴퓨터의 내용도 읽을 수 있다.

URL 속성은 java.net.URL클래스에 의해서 핸들된다.

이전 예제는 <properties> 엘리먼트를 이용하여 db.properties로 불리는 파일을 classpath를 읽고 있다.

db.properties는 다음과 같이 지정한다.

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost/test
user=root
pword=apple

이러한 파일을 로드하기 위해서 다음과 같이 기술한다.

<properties resource="db.properties"/>

마지막으로 지정된 값은 이렇게 이용한다.

<property name="JDBC.Driver" value="${driver}"/>
<property name="JDBC.ConnectionURL" value="${url}"/>
<property name="JDBC.Username" value="${user}"/>
<property name="JDBC.Password" value="${pword}"/>

2. <setting> 엘리먼트
<setting>엘리먼트는 설정 옵션의 환경에 대한 설정이다. 이 설정값을 통해서 글로벌 SQL Map 인스턴스에 대해서 설정이 가능하다.

lazyLoadingEnabled
- 늦은 로딩은 가능하면 절대 경로를 이용하지 않고서 객체를 이용하기 위해서 사용한다. 이 값을 설장하면 관련된 스테이트먼트를 늦은 로딩을 이용하여 처리할 것인지 결정할 수 있다. 이 값은 true/false로 지정하며 기본값은 true이다. 이 기능은 1000명의 사용자가 25개의 아이템에 1000개의 작업을 처리하고자 할경우 25,000, 000개의 객체가 생성되어야 하고, 메모리에 이러한 객체를 가지고 있어야 하지만 늦은 로딩을 이용함으로 해서 2500개의 작업만 처리할 수 있도록 해주어, 자원과 속도의 향상을 가져오게 된다.

cacheModelsEnabled
- 캐싱은 성능향상을 위한 기술이다. 이것은 메모리 기반에서 수행됨을 의미한다. 캐시모델 설정을 하면 iBatis에서 캐싱을 수행할 수 있다. 이 값은 true/false를 설정하게 된다.

enhancementEnabled
- 이 설정은 cglib 옵티마이즈된 클래스를 이용하고자 할때 이용한다. 이것은 lazy loading를 수행하며, true/false에 의해서 지정이 가능한다.
- cglib는 iBatis에서 실행시간에 특정 함수를 생성하고, JavaBeans 프로퍼티를 설정하도록 한다.

useStatementNamespaces
- 이것은 매핑되는 문장의 컬리파이드
이름을 이용할것인지 설정하는 것이다. 이 값은 true/false를 지정하여 설정이 가능하며, 기본값은 false이다
- Sql 맵이 지정되면 팹의 이름은 쿼리파이드 이름으로 보통 이용된다.
- 예를 들어 SQL 맵 이름으로 Account라는 이름이 있다면 매핑된 구분의 이름이 insert, update, delete, getAll등으로 지정한다고 했을때, 이름을 이용하기 위해서는 Account.insert라는 매핑을 이용해야 접근할 수 있다. 그렇게 되면 매핑 충돌이 일어나지 않는다.
이것은 차후에 대규모 프로젝트를 수행할때 상당히 유용한 기능이 된다.

3. <typeAlias> 엘리먼트
org.apache.ibatis.jgamestore.domain.Account같은 이름의 타입이 사용되지 않고 작성되어 있다면 아무도 모를 것이다. <typeAlias>엘리먼트는 Account와 같은 앨리어스를 이용하여 퀄리파이드 이름을 대체하여 사용할 수 있도록 한다.
다음과 같이 지정할 수 있다.
<typeAlias alias="Account" type="org.apache.ibatis.jgamestore.domain.Account" />
Account 앨리어스는 설정을 수행하고 난후 쉽게 이용할 수 있다. 서정파일 내에서 재 사용이 가능하다.

4. <transactionManager> 엘리먼트
iBatis는 데이터베이스 접근을 간단하게 만들어 준다. 이것은 데이터베이스의 트랜잭션을 관리해 준다는 의미이다. 트랜잭션 관리를 할때 몇몇 지정된 트랜잭션 관리자가 이미 정의되어 있다. 이미 지정된 트랜잭션 관리자는  JDBC, JTA, EXTERNAL이 있다.
트랜잭션 관리자의 속성중에 commitRequired속성이 있다. 이것은 true/false로 지정이 가능하며 기본값은 false이다. 이것은 데이터베이스에서 접속해서 작업을 하고, 커넥션을 일리즈 할때, 반드시 commit나 rollback를 요구한다.

5. <property> 엘리먼트
각 트랜잭션 관리자는 서로다른 설정 옵션을 가지고 있따. iBatis 프레임워크는 <property>를 이용하기 때문에 트랜잭션이 필요로 하는 다양한 프로퍼티를 지정할 수 있다.

6. <dataSource>엘리먼트
자바에서 javax.sql.DataSource객체를 이용할때 connection Pool과 함께 주로 이용한다. <dataSource>엘리먼트는 데이터소스 팩토리로 부터 생성된 객체를 호출하여 사용하도록 하고 있으며, DataSourceFactory는 실제적인 데이터소스를 생성하는데 이용한다.
데이터소스 팩토리는 다음과 같이 iBatis에 구현되어 있으며 다음과 같은 종류가 있다.
- Simple : 단순한 데이터소스 팩토리로, 단일 커넥션 풀을 생성하고 있따. 이것은 iBatis 프레임워크에 포함되어 있으며, 이것은 JDBC드라이버를 필요로 한다.
- DBCP : DBCP 데이터소스 팩토리는 Jakarta Commons Data Connection Pool으 이용하여 생성되는 팩토리이다.
- JNDI : JNDI 데이터소스 팩토리는 iBatis에게 공유 컨테이너를 상요할 수 있도록 해준다. 이것은 JNDI를 통해서 접근이 가능하다.

7. <typeHandler> 엘리먼트
iBatis는 애플리케이션의 데이터타입과, JDBC데이터타입을 매핑하기 위해서 타입 핸들러를 이용한다.
그러므로 단순하게 애플리케이션 데이터를 JDBC타입으로 자동 변환하게 된다. 대부분의 상황에서 이러한 컴포넌트는 매우 단순하다. StringTypeHandler는 단순하게 getString메소드를 이용하여 String을 반환한다. 다른 상황에서 더욱 복잡한 타입으로 변경이 가능하다. 예를 들어 Boolean타입은 Y, N을 이용함으로 해서 True/False로 변환이 가능하게 된다.
새로운 타입 변환이 필요하게 된다면 타입 핸들러를 지정하여 애플리케이션과 JDBC데이터타입을 매핑시켜주면 된다. 대부분의 경우에 커스텀 타입핸들러를 이용할 필요는 없을것이다.

8. <sqlMap> 엘리먼트
마지막으로 SqlMapConfig.xml에서는 <sqlMap>엘리먼트를 설정하도록 하고 있다. 이것은 서로다른 2개의 설정이 필요할때 이용하게 된다. 이것 역시 JAR파일이나  WAR파일에 포함된 내용에 접근이 가능하게 되며, classpath를 루트로 해서 참조하면 된다.
보다 명확한 위치를 지정하여 사용하고자 할때에는 url속성을 이용할 수 있다. 이 속성은 java.net.URL클래스를 이용하여 접근할 수 있도록 해준다.

[출처] iBatis sqlMap 설정하기|작성자 감자돌이

 

========================================================================================================================
========================================================================================================================

이번엔 iBatis를 이용해보자...

일단 iBatis를 사용하기 위한 준비를 해보자...

 

http://ibatis.apache.org/javadownloads.cgi

 

위 사이트에서 2.3버전을 다운받은 후 압축을 풀도록 한다...

압축을 푼 후 lib폴더에 보면 ibatis-2.3.0.677.jar 파일이 있는데..

라이브러리에 추가하도록 하자..

이전 버전에서는 파일이 여러개로 나뉘어져 있었는데..

2.3버전으로 오면서 하나로 통합되었다...

 

그리고 자신이 사용할 DB에 맞는 JDBC 라이브러리를 다운받도록 한다..

나같은 경우는 MySQL을 사용하므로 MySQL JDBC 커넥터를 받았다..

아래 사이트에서 다운 받도록 하자...

 

http://dev.mysql.com/downloads/connector/j/5.1.html

 

준비는 모두 끝났다.. 본격적으로 시작해보자..

일단 iBatis 설정 파일을 만들어 보자..

보통 SqlMapConfig.xml 로 만든다..

이 파일에는 JDBC 연결 정보 및 환경 설정 등을 할 수 있다...

 

<?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>

 

 <properties resource="/org/cuvic/sql/db.properties"/>
 
 <settings useStatementNamespaces="false"
     cacheModelsEnabled="true"
     enhancementEnabled="true"
     lazyLoadingEnabled="true"
     maxRequests="512"
     maxSessions="128"
     maxTransactions="32"/>
 
 <transactionManager type="JDBC">
  <dataSource type="SIMPLE">
   <property name="JDBC.Driver" value="${driver}"/>
   <property name="JDBC.ConnectionURL" value="${url}"/>
   <property name="JDBC.Username" value="${user}"/>
   <property name="JDBC.Password" value="${pword}"/>
  </dataSource>
 </transactionManager>
 
 <sqlMap resource="/org/cuvic/sql/map/SqlMap.xml"/>
 
</sqlMapConfig>

 

<property> 태그는 properties 파일을 읽어오기 위한 태그이다...

properties 파일에 있는 속성을 ${프로퍼티이름} 이런 식으로 사용할 수 있다..

db.propertieis 파일은 아래와 같이 작성하면 된다...

 

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/cuvicdb
user=user
pword=pword

 

<transactionManager> 태그에 보면 ${driver} 이런 식으로 사용하는 것을 볼 수 있다..

 

<settings> 태그를 살펴보면 옵션이 많이 있는데...

useStatementNamespace는 이름공간을 사용할 수 있도록 하고 디폴트는 false이다..

보통의 이름 공간이 가지는 장점들을 사용할 수 있다...

cacheModelsEnabled는 캐싱을 사용할지 지정하는 옵션으로 디폴트는 true이다...

lazyLoadingEnabled는 적재지연 기술을 사용할지 지정하는 옵션이고 디폴트는 true이다...

적재지연은 데이터를 읽어올 때 실제 요청이 있을 경우에만 읽어오는 기술이다..

enhancementEnabled는 적재지연의 성능을 향상시킬 때 사용고 디폴트는 true이다....

실행시간에 코드를 변경할 수 있는 CGLIB를 사용하므로 라이브러리가 없다면 자동 비활성화 된다...

기타 max 시리즈의 옵션들은 위에 나온 값이 디폴트 값이다..

위 옵션들은 작성을 권장하지 않으므로 그대로 사용하는 것이 좋을 듯 하다..

만약 수정한다면 값이 maxRequest > maxSessions > maxTransactions 이렇게 되어야 한다...

 

이제 제일 중요한 <transactionManager> 태그를 살펴보자...

type에는 JDBC, JTA, EXTERNAL 3가지 종류가 있다..

 

iBatis에서는 트랜잭션을 자동, 로컬, 글로벌, 사용자 정의 4가지로 구분하게 된다..

자동 트랜잭션은 아래에 나오는 쿼리 실행 메소드를 호출하는 것으로 지원된다...

즉.. 하나의 쿼리 실행 메소드는 하나의 트랜잭션이라는 것이다..

그리고 로컬 트랜잭션은 자동 트랜잭션과 다를게 없다..

단지 자동이 아니고 개발자가 직접 제어할 수 있다는 것이 자동과 로컬의 차이일 뿐이다...

또한 분산 DB가 아닌 하나의 DB에만 적용할 수 있다...

여기까지가 바로 JDBC type을 사용할 경우 사용할 수 있는 트랜잭션이다...

 

글로벌 트랜잭션... 즉 분산 DB를 적용하고 싶은 경우에 JTA와 EXTERNAL type을 사용한다..

능동 혹은 수동으로 글로벌 트랜잭션을 사용할 수 있는데...

iBatis가 직접 트랜잭션을 관리하고자 한다면 JTA를...

외부에 트랜잭션을 맡기고자 한다면 EXTERNAL을 사용한다..

 

<dataSource> 태그에 실제 DB에 접속할 정보를 설정해준다...

type에는 역시나 SIMPLE, DBCP, JNDI 3가지 종류가 있다..

보통 SIMPLE을 사용해서 DB 접속 정보를 직접 넣어주면 된다...

혹시나 Jakarta Commons Database Connection Pool을 사용하고자 한다면 DBCP를 쓰면 되고...

JNDI 데이터 소스를 사용하고자 한다면 JNDI를 사용하면 된다...

 

아무튼 이것으로 iBatis 설정 파일은 끝이다...

실제 SQL을 모아놓은 파일은 <sqlMap> 태그 경로에 있는 SqlMap.xml 파일이다...

물론 하나만 할 수도 있고 여러 개를 만들 수도 있다...

SqlMap.xml은 다음에 알아보도록 하고...

이제 iBatis를 어떻게 사용하는지 알아보도록 하자...

 

import com.ibatis.sqlmap.client.*;
import com.ibatis.common.resources.*;

 

public class Test
{

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

     {

          Reader reader = Resources.getResourceAsReader("/org/cuvic/sql/SqlMapConfig.xml");
          SqlMapClient client = SqlMapClientBuilder.buildSqlMapClient(reader);

 

          // 아래와 같은 메소드들을 사용할 수 있다.

          client.queryForObject(id, parameter);

          client.queryForList(id, parameter);

          client.queryForMap(id, parameter, key);

 

          client.insert(id, parameter);

          client.update(id, parameter);

          client.delete(id, parameter);

     }

}

 

일단 앞서 설정한 SqlMapConfig.xml 파일을 읽어온다...

원래는 WEB-INF에 넣어놓으면 경로를 안 써도 된다고 하는데 난 안되서 저렇게 해주었다...

그 후에 SqlMapClient 객체를 생성해주면 된다...

이 객체가 바로 모든 SQL 명령을 내릴 수 있는 객체이다...

일단 기본적으로 select문 insert문, update문, delete문을 위한 메소드가 있다..

 

참고로 iBatis는 SQL 결과를 자바빈즈로 만드는 것을 추천하고 있다..

근데 난 자바빈즈 만드는게 귀찮아서 HashMap을 주로 이용한다..

물론 각각 장단점이 있지만 난 저게 편하다...

 

아무튼 먼저 select문에 사용되는 메소드는 다음과 같이 3가지가 있다...

 

Object queryForObject(String id, Object parameter) 메소드

List queryForList(String id, Object parameter) 메소드

Map queryForMap(String id, Object parameter, String key) 메소드

 

물론 메소드가 오버로드 되서 2개씩 존재하지만 내가 사용해 본 것만 적어놨다...

 

일단 queryForObject는 레코드가 1개만 존재할 때 사용할 수 있다...

1개 이상 리턴될 경우 에러가 발생한다...

그리고 리턴되는 객체에 디폴트 생성자가 없어도 에러가 발생하므로 주의하자...

id에는 SqlMap에 정의된 SQL id를 넘겨주고 파라미터가 필요하면 parameter에 넘겨주면 된다..

파라미터가 1개 밖에 존재하지 않는데 파라미터가 2개 이상이면 어쩌나 고민할지도 모르겠다..

2개 이상인 경우는 자바빈즈를 만들어서 전달하던가 HashMap 등을 만들어서 넘기면 된다...

이것은 insert나 update나 delete나 전부 해당하는 내용이다...

나 같은 경우는 당연히 HashMap으로 만들어서 전달하는 방식을 사용한다...

 

queryForList는 1개 이상의 레코드를 가져올 때 사용한다...

위의 예에서 볼 수 있듯이 결과값이 List 형태로 넘어오게 된다..

만약 자바빈즈를 결과 값으로 갖도록 SqlMap을 만들었다면...

List에 자바빈즈가 들어간 상태로 리턴된다...

 

queryForMap도 1개 이상의 레코드를 가져올 때 사용하는데..

Map의 특성상 key를 지정해주는 매개변수가 하나 더 추가되어 있다...

해당 key값에 결과를 저장해서 리턴해주게 된다..

 

이번에는 나머지 메소드들을 알아보도록 하자...

 

Object insert(String id, Object parameter)

int update(String id, Object parameter)

int delete(String id, Object paramter)

 

3개 다 사용법은 queryForObject와 같은 방식으로 사용하면 된다...

여기서 주목할 것은 insert의 반환값이 Object라는 사실이다...

이를 이용해서 자동 생성 키(오라클의 경우 sequence)를 사용할 수 있다고 한다..

하지만 사용해보지 않아서 어떻게 동작하는지는 모른다...

아무튼 update나 delete 같은 경우는 반환값이 int라서 수정되거나 삭제된 개수만 리턴하게 된다...

 

여기까지 기본적으로 iBatis를 어떻게 사용하는지까지 알아보았다..

아직 SqlMap에 대한 파악이 끝나지 않은 관계로 여기까지만 정리하도록 하자...

(사실 동적쿼리나 기타 고급 기능을 하나도 보지 않았다... -_-;;)

다시 한 번 말하지만 iBatis는 자바빈즈를 추천하고 있지만...

개인적으로 HashMap이 편해서 앞으로 전부다 HashMap을 이용할 계획이다..

[출처] iBatis 사용하기...|작성자 따굴찬

반응형

관련글 더보기