iBatis2.x 에서 3으로 오면서 바뀐 변화 중 하나가 바로 ParameterMap이 빠진 것이다.
iBatis3 에서 ParameterMap 을 사용하지 못하게 되면서 Mapper 클래스에 여러개의 파라미터를 전달하는 방법에도 변화가 생겼다. 이전에는 mapper 메소드에 전달되는 파라미터 양식에 맞춰서 ParameterMap을 정의하거나, HashMap 객체를 파라미터로 전달해서 dynamic query 를 구성하는 방식을 사용했었다.
양쪽 방식의 차이점은 parameter map 을 조립하는 시점인데, 전자의 경우는 xml 설정 파일을 읽어서 미리 parameter map을 조립하지만 hashmap 을 전달할때에는 런타임 시점에 hashmap을 까봐서 그 안에 들어있는 인스턴스들을 보고 parameter map을 조립한다.
iBatis3 에서 parameterMap에 대한 지원을 안하면서 사실상 parameter map은 실행 시점에 조립되는 듯 하다.(자세한 구현 내용은 확인을 못했지만 파라미터로 뭐가 들어올지 모른다면 미리 parameter map을 만들어 놓는게 불가능하지 않을까?)
예를 들자면 다음과 같은 경우를 말한다.
위에서는 두 개의 파라미터만 전달받지만 dynamic 쿼리를 만들때 여러개의 파라미터가 필요하다면 3~4개 이상이 전달되는 경우도 없지는 않다.
1. @Param annotation 이용방법
iBATIS 3 에서 새로 도입된 @Param 어노테이션을 적용해서 다음과 같이 Mapper 인터페이스를 선언한다.
저렇게 여러개의 파라미터에 참조될 이름을 적어주면 iBatis 안에서파라미터들을 처리하는 방식은 아래와 같다.
우선 파라미터들을 모아서 다음과 같이 map 객체를 만든다.
그리고 조립된 맵 객체를 쿼리의 parameter로 전달하고 실제 sql 에서는 다음과 같이 참조한다.
2. Annotation을 쓰지 않는 방법.
annotation 방식을 쓰지 않고도 쿼리에서 #{0}, #{1}과 같이 파라미터를 참조할 수 있다. 0, 1, 2와 같은 숫자는 파라미터가 메소드에 전달된 순서를 나타내는데 @Param("..") 으로 참조할 파라미터의 이름을 써주지 않을 경우 다음과 같이 위치를 key값으로 등록한다.
이제 sql 에서는 다음과 같이 참조한다.
그런데 이렇게 전달된 파라미터가 dynamic 쿼리 안에서 쓰일때는 참조 방식을 #{1} 이 아니라 [1] 과 같이 해야 한다.
<if test="[1] == true"> c.first_name = #{0}</if>
<if test="[1] != true"> c.first_name LIKE #{0} </if>
annotation을 쓰든 안쓰든 여러개의 파라미터가 map 인스턴스로 전달되기 때문에 실제 동작에는 별 차이가 없으나 annotation을 쓰지 않았을때 #{0}, #{1} 과 같은 숫자를 보고 무슨 값인지 알기가 어렵기 때문에 가독성이 떨어진다.
따라서 별다른 제약이 없다면 annotation을 사용하는게 더 나을 듯 싶다.
iBatis3 에서 ParameterMap 을 사용하지 못하게 되면서 Mapper 클래스에 여러개의 파라미터를 전달하는 방법에도 변화가 생겼다. 이전에는 mapper 메소드에 전달되는 파라미터 양식에 맞춰서 ParameterMap을 정의하거나, HashMap 객체를 파라미터로 전달해서 dynamic query 를 구성하는 방식을 사용했었다.
양쪽 방식의 차이점은 parameter map 을 조립하는 시점인데, 전자의 경우는 xml 설정 파일을 읽어서 미리 parameter map을 조립하지만 hashmap 을 전달할때에는 런타임 시점에 hashmap을 까봐서 그 안에 들어있는 인스턴스들을 보고 parameter map을 조립한다.
iBatis3 에서 parameterMap에 대한 지원을 안하면서 사실상 parameter map은 실행 시점에 조립되는 듯 하다.(자세한 구현 내용은 확인을 못했지만 파라미터로 뭐가 들어올지 모른다면 미리 parameter map을 만들어 놓는게 불가능하지 않을까?)
예를 들자면 다음과 같은 경우를 말한다.
1. @Param annotation 이용방법
iBATIS 3 에서 새로 도입된 @Param 어노테이션을 적용해서 다음과 같이 Mapper 인터페이스를 선언한다.
우선 파라미터들을 모아서 다음과 같이 map 객체를 만든다.
그리고 조립된 맵 객체를 쿼리의 parameter로 전달하고 실제 sql 에서는 다음과 같이 참조한다.
<select id="selectUsersBetweenAges" resultType="project.bean.User">
SELECT
user_id as "id"
, user_name as "userName"
, ...
..
FROM Users
WHERE user_age BETWEEN #{age0} AND #{age1}
</select>
SELECT
user_id as "id"
, user_name as "userName"
, ...
..
FROM Users
WHERE user_age BETWEEN #{age0} AND #{age1}
</select>
2. Annotation을 쓰지 않는 방법.
annotation 방식을 쓰지 않고도 쿼리에서 #{0}, #{1}과 같이 파라미터를 참조할 수 있다. 0, 1, 2와 같은 숫자는 파라미터가 메소드에 전달된 순서를 나타내는데 @Param("..") 으로 참조할 파라미터의 이름을 써주지 않을 경우 다음과 같이 위치를 key값으로 등록한다.
<select id="selectUsersBetweenAges" resultType="project.bean.Customer">
SELECT
c.cust_id as "id"
, c.cust_name as "customerName"
, ...
..
FROM Customers c, Phones phone
WHERE c.cust_id = phone.owner_id
AND phone.number1 LIKE #{1}
AND c.first_name LIKE #{0}
</select>
#{0}은 첫번째 파라미터인 name을, #{1}은 두번째 파라미터인 전화번호를 나타낸다.SELECT
c.cust_id as "id"
, c.cust_name as "customerName"
, ...
..
FROM Customers c, Phones phone
WHERE c.cust_id = phone.owner_id
AND phone.number1 LIKE #{1}
AND c.first_name LIKE #{0}
</select>
그런데 이렇게 전달된 파라미터가 dynamic 쿼리 안에서 쓰일때는 참조 방식을 #{1} 이 아니라 [1] 과 같이 해야 한다.
<if test="[1] == true"> c.first_name = #{0}</if>
<if test="[1] != true"> c.first_name LIKE #{0} </if>
annotation을 쓰든 안쓰든 여러개의 파라미터가 map 인스턴스로 전달되기 때문에 실제 동작에는 별 차이가 없으나 annotation을 쓰지 않았을때 #{0}, #{1} 과 같은 숫자를 보고 무슨 값인지 알기가 어렵기 때문에 가독성이 떨어진다.
따라서 별다른 제약이 없다면 annotation을 사용하는게 더 나을 듯 싶다.
'Dev > iBATIS' 카테고리의 다른 글
[iBATIS 3 + TDD] iBATIS 테이블 추가 예제 (0) | 2010.05.22 |
---|---|
[iBATIS3.0 util] 자바 POJO 인스턴스 NOT NULL 확인 (0) | 2010.05.18 |
[ iBatis 3.0 ] Mapper 인터페이스의 메서드 선언시 주의 사항. (0) | 2010.05.16 |