iBatis 에서 mybatis 로 바뀌면서 바뀐것들 중에 하나가 동적쿼리문에서 쓰는 태그들이다.

iBatis 에 있던 <isEqual/> <isNotEqual/> 요런 것들이 

mybatis 에서는 <if test="xxx == 'a'"></if> <if test="xxx != 'a'"></if> 요렇게 대체할 수 있어서 쫌더 간결해 진것 같다.

그런데 test="" 요기에서 쓸수 있는 비교연산자들 중에는 null 인지 빈 공백인지 판단하던 <isEmpty/>, <isNotEmpty/> 를 대체할만한 비교연산자가 없었다.

null 인지 공백인지 mybatis 에서 판단하기 위해서는
1
<if test="xxx == null or xxx == ''"></if>

요렇게 쫏끔 번거롭게 쓸 수 밖에 없는것 같았다. 뭐 더 찾아보진 않았지만~



어째 다른 방법이 없나 쭉 찾아보니까~ 신기하게도 조건문에서 자바 클래스의 메소드를 호출해서 하는 방법이 있었다.

클래스를 하나 맨들고 거기에다 boolean 을 리턴해주는 static 메소드들을 뽓 맨들고 고것을 호출하는 방식이다.

내가 작성해본 클래스는 요렇다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package stove99.tistory.com;
 
import java.lang.reflect.Array;
import java.util.List;
import java.util.Map;
 
public class MyComparator {
    public static boolean isEmpty(Object obj){
        if( obj instanceof String ) return obj==null || "".equals(obj.toString().trim());
        else if( obj instanceof List ) return obj==null || ((List)obj).isEmpty();
        else if( obj instanceof Map ) return obj==null || ((Map)obj).isEmpty();
        else if( obj instanceof Object[] ) return obj==null || Array.getLength(obj)==0;
        else return obj==null;
    }
     
    public static boolean isNotEmpty(String s){
        return !isEmpty(s);
    }
}


죠렇게 맨든 클래스를 땡겨다 쓰는 mabatis sql xml 예제는 요렇다.
1
2
3
4
5
6
7
8
9
<select id="testSQL" parameterType="map" resultType="hashmap">
    SELECT * FROM TB_TEST
    WHERE
        1=1
        <!-- @패키지.클래스명@호출할메소드(파라메터) -->
        <if test="@stove99.tistory.com.MyComparator@isEmpty(keyword)">
            AND KEYWORD = #{keyword}
        </if>
</select>
@패키지명.클래스@메소드 요렇게 호출해야 되기 때문에 패키지나 클래스명은 간단하게 명명하면 좋을것 같다.

뭐 쓰고보니 더 복잡해진것 같기도 하고 -_-

 아무튼 딸랑 empty 체크하는 거에만 활용해서 그럴수도 있지만, 자바 메소드를 호출할수 있다는 것은 이것저것 활용할데가 많을것 같다. 
저작자 표시 비영리 변경 금지


myBatis 파라미터 바인딩시 주의점 myBatis(ibatis)

출처: 프렐루드의 잡담방

매핑구문에 파라미터를 전달할때 값 기반으로 전달한 파라미터를 사용하면 아무런 문제 없이 처리된다.

String parameterName = "value";
session.selectList("com.test.mapper.TestSql", parameterName)


이렇게 파라미터를 주고


<select id="TestSql" parameterType="String" resultType="com.test.mapping.Account">
     SELECT *
     FROM Account
     WHERE AccountName = #{parameterName}
</select>


이렇게 매퍼를 사용하면 정상적으로 처리된다. 하지만 $를 이용해 바인딩하는 경우에는 에러가 발생한다.


<select id="TestSql" parameterType="String" resultType="com.test.mapping.Account">
     SELECT *
     FROM Account
     WHERE ${parameterName} = '가나다'
</select>


이렇게 하면 속성을 찾을 수 없다면서 오류가 발생한다. 이러한 경우에는 문자열로 바로 파라미터를 전달하지 않고 map에 넣어서 전달한다.


Map<String, Object> parameters = new HashMap<String, Object>();


parameters.put("parameterName", "value");
session.selectList("com.test.mapper.TestSql", parameterName)


이렇게 파라미터를 전달하면


<select id="TestSql" parameterType="String" resultType="com.test.mapping.Account">
     SELECT *
     FROM Account
     WHERE ${parameterName} = '가나다'
</select>


이러한 구문도 정상적으로 처리된다. #로 파라미터를 바인딩 할때와 $로 파라미터를 바인딩 할때 구조상에 차이가 있는가 보다.



+ Recent posts