본문 바로가기
개발~/MyBatis

MyBatis] foreach

by 보배곰 2017. 6. 7.

출처: 마이바티스 소개 - http://www.mybatis.org/mybatis-3/ko/dynamic-sql.html


아래 예제 소스는 

전자정부프레임워크 3.6(Spring), mysql, myBatis를 기준으로 합니다.


제가 마이바티스에서 정말 자주 쓰는 foreach입니다. 

JSTL의 foreach랑 조금 비슷한 듯 합니다. (제 생각이지만요ㅋㅋㅋ)


foreach문은 동적 SQL을 처리하기 위해 사용하는 것으로, collection에 대해 반복처리를 합니다. 

저는 주로 IN조건에 많이 쓰고, 여러행을 update할 때도 사용했습니다. 


foreach문 변수로는  item, index, collection, open, separator, close  이렇게 6가지를 쓸 수 있습니다.



IN 조건에서 쓰인 예제

(PROCESS 테이블에서 해당 조건에 맞는 행의 수 출력)


아래 sql부르는 controller로 참고하시라구 간단히 넣어요.


sql.xml

<select id="selectSearchCnt" resultType="int" parameterType="hashmap">

<![CDATA[

/*selectSearchCnt*/

SELECT count(A.Process_Code) as Count

FROM PROCESS A

]]>

<where>

<if test="Grade != null">

                                A.Grade in

<foreach collection="Grade" item="item" index="index" separator="," open="(" close=")">

#{item}

</foreach>

and

</if>

<if test="Field != null">

  A.Field in

<foreach collection="Field" item="item" index="index" separator="," open="(" close=")">

#{item}

</foreach>

  and

</if>

<if test="searchCategory != 'Tag' and content != null and content != '' ">

<![CDATA[A.${searchCategory} like '%${content}%' and ]]>

</if>

<![CDATA[A.Regist_Date <= #{end_period}]]>

<![CDATA[and A.Regist_Date >= #{start_period}]]>

</where>

</select> 


collection에는 Map이나 배열객체와 더불어 List, Set 등과 같은 반복가능한 객체를 전달할 수 있다. 

반복 가능하거나 배열을 사용할 때 index 값은 현재 몇번째 반복인지를 나타낸다. (0부터 시작, 1부터 시작 하고싶으면 (#{index}+1)  ) 해주면 된다.

value항목은 반복과정에서 가져오는 요소를 나타낸다. (#{item} #{item.value} 같음)

Map을 사용할때 index는 key객체가 되고 항목은 value객체가 된다. (#{item.key}, #{item.value})

open은 foreach문이 시작할 때 한 번, close는 foreach문이 끝날 때 한번 들어갑니다. 

separator은 foreach문이 반복할 때, 사이에 들어가는 구분자 입니다. 

index, open, separator, close는 필요할 때만 명시해주셔도 괜찮습니다.


만약 String[] Grade의 내용이 [1,2,3,4,5] 이라고 한다면, 위에 굵은 부분은 아래처럼 sql이 작성됩니다. 

A.Grade in ( 1 , 2 , 3 , 4 , 5 ) 

간단하죠? 


이번에는 여러행을 Update할 때 foreach를 써봅시다. 

여러행을 업데이트하는 방법은 이 블로그를 참고했습니다. ( http://marobiana.tistory.com/7 )

CASE문을 사용하면 됩니다.


만약 테이블이

seq 

 ord

 1

 1

 2

 2

 3

 3 


이 상태일 때, 

ord를 입력받은 순서대로, 만약 2,3,1 이 순으로 바꾸고 싶다면,


UPDATE TABLE

      SET ord

CASE

WHEN seq=1 THEN 2

WHEN seq=2 THEN 3

WHEN seq=3 THEN 1

END

WHERE

seq IN (1,2,3) 


(그리고 아마... seq(조건에 쓰이는 값)는 UNIQUE여야 했던거 같다. 아마.. )


예제

(테이블의 모든 행을 seq에 따라 order를 변경해주는 쿼리문)


아래 seqList는 ordering된 순서대로 seq가 들어오고 있고, 나는 그 순서에 맞게 Order에 1부터 차례대로 넣어주면 되서 아래처럼 짰다. index의 경우 0부터 시작하는데, Order가 1부터 시작해야되서 (#{inedx}+1) 해주었다. 

(Order의 경우 mysql에서 쓰이는 예약어이기 때문에 `Order` ``이거 붙여주었다. 저거 숫자1 왼쪽에 있는거ㅋㅋㅋ )



sql.xml

<update id="ordering" parameterType="hashmap">

UPDATE PROCESS 

        SET `Order`= CASE

<foreach collection="seqList" item="item" index="index">

WHEN seq = #{item} THEN (#{index}+1) 

</foreach>

END

WHERE seq IN

<foreach collection="seqList" item="item" open="(" close=")" separator=", ">

#{item}

</foreach>

</update>



'개발~ > MyBatis' 카테고리의 다른 글

[IntelliJ] MyBatis binding 에러  (0) 2021.05.24

댓글