스프링으로 연습삼아 혼자서 프로젝트를 하던 도중 화면에서 한번에 데이터를 여러개로 받아 그 갯수만큼 insert처리를 해야하는 기능을 구현해야했는데요, 모르는게 많은 저는 막막했습니다.. 다행히도 바로 생각난 건 막연하게 for문을 이용하는 건 어떨까? 하는 생각으로 시작했습니다.
구글링과 사놓은 책들을 뒤져보다 mybatis에서 foreach라는 태그를 사용하여 해결했습니다. 이 외에도 mybatis에서는 여러가지의 동적 태그들이 있습니다. if, choose, trim 등등,, 그래서 mybatis의 동적태그에 대해 복습하는 겸 정리를 해볼까 합니다.
정리하기 앞서 동적 태그를 좀 더 매끄럽게 사용할 수 있게 해주는 태그에 대해 먼저 알아보겠습니다. trim이라는 태그엔데, 이 태그는 단독으로 사용되지 않는다는 것이 특징입니다.
-
trim 태그
trim 태그는 하위에서 만들어지는 SQL문을 조사하여 추가적인 SQL을 처리해주는 태그입니다.
trim태그의 속성에 대해 몇가지 알아보겠습니다.
이름 |
설명 |
prefix |
해당 태그 내에서 가장 앞에 붙음 |
prefixOverrides |
해당 태그 내에서 쿼리가 가장 앞에 해당하는 문자를 지워줌 |
suffix |
해당 태그 내에서 가장 뒤에 붙음 |
suffixOverrides |
해당 태그 내의 가장 뒤에 해당하는 문자를 지워줌 |
위의 목록을 통해 예시를 들어보겠습니다.
- 예시 1
SELECT COLUMN1, COLUME2
FROM TABLE
WHERE PK_COLUMN1 = #{key1}
<trim prefix="AND (" prefixOverrides="OR" suffix=")">
<if test="key2 != null">
OR PK_COLUMN2 = #{key2}
</if>
<if test="key3 != null">
OR PK_COLUMN3 = #{key3}
</if>
</trim>
위의 prefix 태그를 보면, prefix="AND ("라는 것을 볼 수 있습니다. 이는 where절의 조건을 이어주는 AND를 뜻하며, prefixOverride="OR"은 trim 태그 내의 맨 앞의 문자가 OR일 때 해당 문자를 지워주는 역할을 합니다. suffix=")"은 말 그대로 맨 뒤에 붙은 문자입니다.
위의 SQL문의 trim태그내의 if문이 모든 조건을 만족한다면, 해당 SQL문은 아래처럼 해석됩니다.
SELECT COLUMN1, COLUME2
FROM TABLE
WHERE PK_COLUMN1 = #{key1}
AND(PK_COLUMN2 = #{key2} OR PK_COLUMN3 = #{key3})
- 예시 2
UPDATE TABLE
<trim prefix="SET" suffixOverrides=",">
<if test="key1 != null">COLUMN1 = #{key1},</if>
<if test="key2 != null">COLUMN2 = #{key2},</if>
<if test="key3 != null">COLUMN3 = #{key3},</if>
<if test="key4 != null">COLUMN4 = #{key4},</if>
</trim>
예시 1에 없던 suffixOverrides를 사용하였습니다. suffixOverrides는 맨 끝의 문자가 해당문자와 일치할 때 제거해주는 역할을 합니다. trim태그 안의 if문을 전부 만족하는 조건이라면 해당 SQL문은 아래처럼 해석됩니다.
UPDATE TABLE SET
COLUMN1 = #{key1},
COLUMN2 = #{key2},
COLUMN3 = #{key3},
COLUMN4 = #{key4}
trim 태그정리는 이정도로 마치고, 본격적인 동적 태그들에 대해 알아보겠습니다.
-
if
if는 조건이 true가 되었을 때 태그 내의 SQL문을 처리합니다.
<if test="key1 != null">
COLUMN1 = #{key1}
</if>
위처럼 해당 if문의 test가 true일 때, 태그 내의 SQL문을 출력합니다.
-
choose
if와 달리 choose는 여러 상황들 중 하나의 상황에서만 동작합니다. 마치 Java의 if ~ else와 유사합니다.
<choose>
<when test="key1 != null">
COLUMN1 = #{key1}
</when>
<when test="key2 != null">
COLUMN2 = #{key2}
</when>
<when test="key3 != null">
COLUMN3 = #{key3}
</when>
<otherwise>
COLUMN4 = #{key4}
</otherwise>
</choose>
위의 choose태그 안에서 when이라는 태그가 있습니다. 이는 조건식을 뜻하며 Java에서 else if와 유사한 의미를 가집니다. choose태그의 마지막 otherwise는 Java의 else와 유사한 의미를 가지며, choose태그 내에서 when태그의 조건의 나머지를 뜻합니다.
-
foreach
foreach태그를 알아보기 전 foreach태그의 속성에 대해서 먼저 알아볼 필요가 있습니다.
이름 |
설명 |
collection |
전달받은 인자이며, List 또는 Array만 사용 가능 |
item |
전달받은 인자 값을 alias명으로 설정 |
open |
구문이 시작될 때 입력 할 문자열 |
close |
구문의 맨 마지막에 입력 할 문자열 |
separator |
반복되는 사이에 입력 할 문자열 |
index |
반복되는 구문 번호로, 0부터 순차적으로 증가함 |
아래 예시를 보겠습니다.
SELECT COLUMN1, COLUMN2
FROM TABLE
WHERE COLUMN1 in
<foreach item="item" index="index" collection="list" open="(" seperator="," close=")">
#{item}
</foreach>
전달받은 파라미터의 타입은 list이고, list의 alias설정은 item의 "item"으로 설정하였습니다. foreach태그 맨 앞과 끝은 "(", ")"이며, 반복될때마다 ","를 붙이게 됩니다.
만약 배열의 길이가 2인 list의 배열이라고 가정한다면,
SELECT COLUMN1, COLUMN2
FROM TABLE
WHERE COLUMN1 in (#{item[0]}, #{item[1]})
위와 같은 결과를 출력합니다.
마치며,
사실 foreach문에 대해 자세히 알아보려했는데, 글이 너무 길어질 것 같아 따로 포스팅을 하기로 결정했습니다. 개인적으로 위의 태그 중 foreach와 trim을 좀 까다로워했었고, 단순한 SQL문이라면 모를까, 조금 복잡해지기라도 저처럼 숙련도가 없는 사람들은 오랜시간 고민을 해야합니다.
다행히도 주관적으로 mybatis는 직관적인 언어라고 생각해서 그런지 그 구조가 복잡한거라고는 생각하지 않지만, 다음 foreach태그를 중점적으로 포스팅 할 때에는 혼자 고민했었던 사례를 예시로 어떻게 풀어나갔는지 적어보려 합니다.
참고자료
코드로 배우는 스프링 웹 프로젝트(이병승) www.yes24.com/Product/Goods/64340061
'코딩 > Spring' 카테고리의 다른 글
Spring Model (1) | 2020.08.28 |
---|---|
Spring Connection Pool(DBCP), Hikari CP (0) | 2020.08.24 |
Spring servlet-context.xml, root-context.xml, web.xml (0) | 2020.08.23 |
Spring Lombok Log4j 오류뜰 때 (2) | 2020.08.21 |
Spring 스프링을 사용하는 이유 (0) | 2020.08.20 |
최근댓글