본문 바로가기

Programming/iBatis

Mapped Statements

맵핑된(Mapped) Statements

SQL Maps 개념은 맵핑된 statement에 집중한다.

맵핑된 statement는 어떠한 SQL문을 사용할수도 있고 파라미터 maps(input)과 result maps(output)를 가질수 있다.

만약 간단한 경우라면 맵핑된 statement는 파라미터와 result를 위한 클래스로 직접 설정할수 있다.

맵핑된 statement는 메모리내에 생산된 results를 캐슁하기 위해 캐쉬 모델을 사용하도록 설정할수도 있다.

 

Statement Type

XML에 정의하는 SQL 문장 중에 XML에서 사용되는 문자(<, > 등)가 포함되는 경우 아래와 같이 CDATA를 사용한다.

<statement id="getPersonsByAge" parameterClass="int" resultClass="examples.domain.Person">
    <![CDATA[
        SELECT *
        FROM PERSON
        WHERE AGE > #value#
    ]]>
</statement>

 

Auto-Generated Keys

Data Mapper는 <insert>문에 <selectKey>문을 이용하여 auto-generated key를 지원한다.

<selectKey>는 pre-generated key(oracle)와 post-generated key(ms-sql)를 모두 지원한다.

<!—Oracle SEQUENCE Example -->
<insert id="insertProduct-ORACLE" parameterClass="com.domain.Product">
    <selectKey resultClass="int" keyProperty="id" >
        SELECT STOCKIDSEQUENCE.NEXTVAL AS ID FROM DUAL
    </selectKey>

    insert into PRODUCT (PRD_ID,PRD_DESCRIPTION)
        values (#id#,#description#)
</insert>
<!— Microsoft SQL Server IDENTITY Column Example -->
<insert id="insertProduct-MS-SQL" parameterClass="com.domain.Product">
    insert into PRODUCT (PRD_DESCRIPTION) values (#description#)
    <selectKey resultClass="int" keyProperty="id" >
        SELECT @@IDENTITY AS ID
    </selectKey>

</insert>

 

Stored Procedures

<procedure> 문장을 통해 stored procedure를 제공한다.

<parameterMap id="swapParameters" class="map" >
    <parameter property="email1" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
    <parameter property="email2" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
</parameterMap>

<procedure id="swapEmailAddresses" parameterMap="swapParameters">
    {call swap_email_address (?, ?)}
</procedure>

참고로 위처럼 프로시저를 호출하는 것은 파라미터 객체(map)내에서 두 개의 컬럼 사이에 두 개의 이메일 주소를 교체하는 것이다. 파라미터 객체는 파라미터 맵핑의 mode 속성 값이 "INOUT" or "OUT"일 경우에만 변경된다. 다른 경우라면 변경되지 않고 남는다. 명백한 불변의 파라미터 객체(ex> String)은 사용 할 수 없다.

Stored Procedure란? SQL Server에서 제공되는 프로그래밍기능이라고 할 수 있다.
어떠한 동작을 일괄처리하기 위한 용도로 사용된다. 어떤 특정 쿼리를 모듈화시켜 필요할 때 마다 호출하여 사용하는 것으로, 데이터베이스 개체에 속한다.

 

ParameterClass

이 속성의 값은 java class의 전체 경로를 포함한(예를 들면 패키지를 포함한) 이다.

이 속성은 옵션이지만 강력하게 추천한다.

이 속성은 statement로 전달되는 파라미터를 제한하기도 하지만 프레임워크 성능의 최적화에도 영향을 미친다.

(요구되는 파라미터가 없어도, 프레임워크가 먼저 타입을 안다면 스스로 최적화 능력을 가지고 있다.)

parameterMap을 사용하면 parameterClass 속성을 사용할 필요가 없다.

<statement id="statementName" parameterClass="examples.domain.Product">
    insert into PRODUCT values (#id#, #description#, #price#)
</statement>

 

ParameterMap

ParameterMap 속성의 값은 정의된 parameterMap 요소 이름이다.

ParameterMap 속성은 parameterClass 속성이나 Inline Parameter에 비해 잘 사용되지 않지만 XML의 purity/consistency가 주요한 이슈이거나 보다 descriptive parameterMap을 원한다면 이 속성이 보다 나은 접근 방법이다.

주의 : dynamic mapped statements는 inline parameters만 지원하고 parameterMap과는 함께 사용될 수 없다.

주의 : parameterMap 속성의 개념은 JDBC PreparedStatement에 사용될 값들에 대한 ordered list를 정의하는 것이다.

<parameterMap id="insert-product-param" class="com.domain.Product">
    <parameter property="id"/>
    <parameter property="description"/>
</parameterMap>

<statement id="insertProduct" parameterMap="insert-product-param">
    insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (?,?);
</statement>

위의 예제에서, ParameterMap은 SQL문의 각 값에 매치되고 정렬되는 두 개의 파라미터를 서술한다.

그래서 첫 번째 "?"에는 "id"의 속성 값이 대체되고, 두 번째는 "description" 속성 값이 대체된다.

 

Inline Parameter (인라인 파라미터)

인라인 파라미터는 아래의 예와 같이 매핑된 statement 내부에서 사용 될 수 있다.

<statement id=”insertProduct” >
    insert into PRODUCT (PRD_ID, PRD_DESCRIPTION)
    values (#id#, #description#);
</statement>

위 예제에서 인라인 파라미터는 #id#, #description#이다. 각각은 statement 파라미터를 대체하는 자바빈즈 속성을 표현한다.

만약 id=5, description="dog"을 가지는 Prodect를 넘겨받은 statement는 아래와 같이 동작한다.

insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (5, ‘dog’);

 

ResultClass

ResultClass 속성은 java class의 전체 경로를 포함한(예를 들면 패키지를 포함한) 이름이다.

ResultClass 속성은 ResultSetMetaData에 의해 JDBC ResultSet에 자동으로 매핑되는 클래스를 명시하도록 한다.

자바 빈즈의 프로퍼티 이름과 테이블(ResultSet)의 컬럼 이름이 매치되면 프로퍼티는 컬럼의 값으로 채워진다.

<statement id="getPerson" parameterClass=”int” resultClass="examples.domain.Person">
SELECT
    PER_ID as id,
    PER_FIRST_NAME as firstName,
    PER_LAST_NAME as lastName,
    PER_BIRTH_DATE as birthDate,
    PER_WEIGHT_KG as weightInKilograms,
    PER_HEIGHT_M as heightInMeters
FROM PERSON
WHERE PER_ID = #value#
</statement>

아래의 예에서 Person 클래스는 id, firstName 등의 프로퍼티를 갖는다.

alias(별칭)를 통해 각각의 컬럼의 값은 SQL SELECT문에 의해 빈의 프로퍼티에 채워진다.

칼럼 별칭은 데이터베이스 칼럼 이름이 매치되지 않을 때만 요구된다. (일반적으로는 요구되지 않는다.)

 

ResultMap

ResultMap의 값은 정의된 ResultMap Element의 이름이다.

ResultMap속성을 이용하여 Resultset에서 데이터가 추출되는 방법과 어떤프로퍼티가 어떤컬럼에 매핑되는지 제어할 수 있다.

자동으로 매핑되는 ResultClass속성의 자동맵핑접근과 달리 ResultMap은 컬럼 타입, 널 값 치환 방법, Complex Property Mapping(다른 자바빈즈, Collections 그리고 원시타입래퍼) 등을 지원한다.

<resultMap id=”get-product-result” class=”com.ibatis.example.Product”>
    <result property=”id” column=”PRD_ID”/>
    <result property=”description” column=”PRD_DESCRIPTION”/>
</resultMap>
<statement id=”getProduct” resultMap=”get-product-result”>
    select * from PRODUCT
</statement>

위 예제에서 SQL쿼리로부터 ResultSet은 ResultMap 정의를 사용하여 Product 인스턴스에 맵핑된다.

"SELECT *"이 지원된다는 것은 ResultSet내에 반환된 모든 컬럼에 대한 매핑을 정의할 필요는 없는 것을 의미한다.

 

CacheModel

cacheModel 속성은 정의된 cacheModel element에 대한 이름이다.

cacheModel은 쿼리가 매핑된 statement를 사용하기 위한 캐시를 서술하기 위해 사용된다.

각각의 쿼리 매핑 statement는 같은 cacheModel을 사용할 수도 있고, 서로 다른 cacheModel을 사용할 수도 있다.

<cacheModel id="product-cache" imlementation="LRU">
    <flushInterval hours="24"/>
    <flushOnExecute statement="insertProduct"/>
    <flushOnExecute statement="updateProduct"/>
    <flushOnExecute statement="deleteProduct"/>
    <property name=”size” value=”1000” />
</cacheModel>
<statement id=”getProductList” parameterClass=”int” cacheModel=”product-cache”>
    select * from PRODUCT where PRD_CAT_ID = #value#
</statement>

위 예제에서 캐쉬는 WEAK 참조타입을 사용하는 products를 위해 정의되고 24시간마다 또는 관련된 update문이 수행 될 때마다 지워진다. (flush)

 

xmlResultName

결과를 XML 문서로 직접 매핑할 때 xmlResultName의 값은 XML 문서의 가장 상위 요소의 이름이 된다.

<select id="getPerson" parameterClass="int" resultClass="xml" xmlResultName="person">
    SELECT
        PER_ID as id,
        PER_FIRST_NAME as firstName,
        PER_LAST_NAME as lastName,
        PER_BIRTH_DATE as birthDate,
        PER_WEIGHT_KG as weightInKilograms,
        PER_HEIGHT_M as heightInMeters
    FROM PERSON
    WHERE PER_ID = #value#
</select>

위의 Select Statement는 다음 구조의 XML객체를 생성 할 것이다.

<person>
    <id>1</id>
    <firstName>Clinton</firstName>
    <lastName>Begin</lastName>
    <birthDate>1900-01-01</birthDate>
    <weightInKilograms>89</weightInKilograms>
    <heightInMeters>1.77</heightInMeters>
</person>

 

참조 : http://silvermoonlight.springnote.com/pages/1764268 & iBATIS-SqlMAps-2_ko.pdf

'Programming > iBatis' 카테고리의 다른 글

iBatis - selectKey (자동생성키)  (0) 2012.12.27
iBatis - Iterate  (1) 2012.11.16
QueryForList와 QueryForMap의 차이 예  (0) 2012.04.09
QueryForObject, List, Map  (0) 2012.04.09
iBatis - 동적쿼리  (0) 2012.04.06