2013년 4월 14일 일요일

[Spring] ibatis

앞에서 스프링을 이용하여 좀 더 쉬운 DB연동을 살펴 보았다. 상당히 많은 양의 중복 코드를 줄인 것을 알 수 있다.

그러나 지금 언급하고자 하는 ibatis는 DB와의 연동 시 코드의 양을 더욱 많이 줄여줄 수 있다! 단순히 XML을 사용하여 SQL statement에 매핑이 가능하다. 때문에 JDBC로만 프로그래밍 할때의 번거로움이 상당히 줄어드는 것이다.

그만큼 유용한 프레임워크인 ibatis에 대해 알아보도록하자.

ibatis는 sql 실행 결과를 자바빈즈 혹은 Map객체에 매핑해 주는 솔루션으로 sql을 소스코드가 아닌 XML로 따로 분리해 관리하도록 지원한다. 따라서 복잡한 sql을 작성하기가 수월하고 코드의 분리로 유지보수가 좀 더 간편하다. 왜냐하면 DAO자바 코드에서는 순수하게 자바 코드만을 관리하고 sql문은 따로 XML파일로 관리할 수 있기 때문에 서로의 관계를 느슨하게 만들 수 있기 때문이다.

ibatis를 사용하기 위해서는 ibatis라이브러리를 자신의 웹 어플리케이션 lib폴더에 넣어두는 것을 잊지말자. 그런다음 ibatis 사용을 위한 xml파일을 설정해 주어야한다.

2가지의 XML파일만 설정하면 된다.
첫 번째는 DataBase의 환경을 설정하는 XML이고 두 번째는 사용될 Query를 저장하는 XML파일이다. 우선 Database 환경 설정 XML파일에 <sqlMapConfig>태그를 안에 <transactionManger>태그를 사용하고 속성으로 type을 준다.
예)//////////////////////////////DB설정 XML/////////////////////////////////////////

<sqlMapConfig>

  <transactionManager type="JDBC" commitRequired="false">
    <dataSource type="JNDI">
    <property name="DataSource" value="java:comp/env/jdbc/oracle"/>
    </dataSource>
  </transactionManager>

  <sqlMap resource="kosta/ibatis/Board.xml"/>

</sqlMapConfig>

위 코드는 JDBC타입으로 JNDI네이밍 방식을 사용한다. sqlMapConfig는 ibatis에서 JDBC를 처리하기 위해 필요한 사항을 설정하며 Transaction 관리 정보, DataSource Factory와 sqlMap 파일의 위치를 기술하게 된다.

다음으로는 Query를 지정한 XML파일을 로드해 주어야 하는데 <sqlMap>이라는 태그를 사용하여 루트를 지정해 준다.

예)//////////////////////////////SQL문 설정 XML//////////////////////////////////////

<sqlMap>

<typeAlias alias="Board" type="kosta.model.Board"/>
<typeAlias alias="Search" type="kosta.model.Search"/>

<insert id="insertBoard" parameterClass="Board">
insert into Board values(
board_seq.NEXTVAL,
#title#,
#writer#,
#contents#,
sysdate,
0)
</insert>

<select id="searchBoard" parameterClass="Search" resultClass="Board">
select * from board
<dynamic prepend="where">
<iterate property="areas" conjunction="or" open="(" close=")">
$areas[]$ like #searchKey#
</iterate>
</dynamic>
order by seq desc
</select>

</sqlMap>

위의 sql문을 설정한 XML파일의 내용이다. DTO에 쿼리 결과를 담기 위해서는 위에 보이는 것과 같이 해당 클래스의 <typeAlias>를 지정해야한다. 그런다음 SQL문 태그들을 이용하여 데이터베이스의 데이터들을 관리할 수 있게 된다.

sql문을 사용하기 위한 태그를 살펴보면 태그의 속성에 id와 parameterClass, resultClass가 존재한다는 것을 알 수 있다. id는 Dao에서 호출할 sql문의 이름이다. parameterClass는 입력될 객체를 의미한다. ibatis에는 객체나 프리미티브 타입, 해쉬맵 등의 데이터를 인자값으로 넘겨 줄 수 있다. resultClass는 query의 결과를 담을 데이터를 말하며 resultClass일 경우 객체로 결과를 담는다는 것이다. resultMap을 이용하여 객체를 받을 수 있는데 특히 데이터베이스의 컬럼명과 클래스의 멤버변수명이 다를 때 그 이름을 새롭게 패핑하여 결과값을 얻을 때 사용한다.

위의 이러한 과정을 그림으로 나타내면 다음과 같다.




요약하자면 SqlMapConfig설정파일을 통해 데이터베이스의 Resource를 구하고 사용할 sql문과 sql문의 입력된 데이터와 출력데이터간의 매핑을 처리해주도록 설정한 SqlMap파일을 로드하도록 한다.

그런다음 설정한 SqlMap을 사용하기 위해 SqlMapClient interface를 얻도록 해야한다. 그 코드는 아래와 같다.







Reader reader = Resources.getResourceAsReader("로드할 SqlMapConfig파일 위치");
sqlMapper = SqlMapClientBuilder.buildSqlMapClient(reader);

동적쿼리문
디비를 활용하다보면 로직에 따라 sql문이 수시로 변경되어야할 경우가 많다. ibatis에서는 로직에 따른 동적쿼리문에 대한 태그를 제공한다.

<dynamic>태그
가장 상위의 태그이고 접두/접미 구문을 위한 수단을 제공한다.
- prepend : 맨 앞에 접두 구문을 붙인다.
- open : body의 내용 앞에 붙여짐. body의 내용이 없을 경우 생략. prepend와 동시에 정의될 경우 prepend 다음에 나타남.
- close : body의 내용 뒤에 붙여짐. body의 내용이 없을 경우 생략.

비교태그
주어진 parameter 객체간의 property값을 비교한다.
- property(필수) : parameter 객체의 property, compareValue 또는 compareProperty를 이용해 데이터 비교
- prepend(옵션) : 접두 구문 추가. 다만 생략되는 경우가 있다. 1. body의 내용이 없는 경우 2. 부모 태그의 속성이 removeFirstPrepend = "true"이고 현재 부모 태그가 부모 body의 첫 번째 요소인 경우
- open(옵션) : <dynamic>태그와 동일
- close(옵션) : <dynamic>태그와 동일
- removeFirstPrepend(옵션) : 첫 번째 자식 태그의 prepend를 생략시킴
- compareProperty : property와 비교할 property
- compareValue : property속성에 의해 비교되는 값(상수)
- <isEqual> : property속성과 compareProperty / compareValue속성이 같은지 비교
- <isNotEqal> : 다른지 비교
- <isGreaterThan> : 큰지 비교
- <isGreaterEqual> : 크거나 같은지 비교
- <isLessThan> : 작은지 비교
- <isLessEqual> : 작거나 같은지 비교

단항태그
주어진 특정 property에 대한 태그
- <isPropertyAvailable> : 특정 property가 존재하는지 체크(Map의 경우 key가 존재하는지 체크)
- <isNotPropertyAvailable> : 특정 property가 존재하지 않는지 체크
- <isNull> 특정 property가 null인지 체크
- <isNotNull> 특정 property가 null이 아닌지 체크
- <isEmpty> 특정 property가 null이거나 비어있는지 체크
- <isNotEmpty> 특정 property가 null이 아니고 비어있는지 체크

Parameter 태그
- <isParameterPresent> : 파라미터가 존재하는지 체크
- <isNotParameterPresent> : 파라미터가 존재하지 않는지 체크

interate태그
Collection 형태의 property로써 sql문의 반복적인 구간 생성
- conjunction : 반복되는 sql문 사이에 구분자로 들어감 (예: ',' or, and 등등)


댓글 없음:

댓글 쓰기