출처: 마이바티스 소개 - 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 |
---|