본문 바로가기

TroubleShooting/Java

MySQL insert all on update MyBatis 쿼리문

728x90

 MySQL DB 에 MyBatis(마이바티스)로 다수의 데이터를 insert 와 update 를 동시에 하려고 쿼리문을 찾아보았다.

 여러건의 데이터들은 마이바티스 쿼리문에 파라미터로 <foreach> 구문으로 list 형태의 데이터를 전달할 수 있다. 그런데, "on duplicate key update" 뒤의 문장을 완성하려고 하니깐 어떤 식으로 쿼리문을 작성해야할 지 난감했다.


 다음 쿼리문처럼 list 에서 insert 하다가 동일키에 대해서 update 를 할때, list 의 현재 위치값을 표시해야하는데 일단 방법을 몰라서 <foreach> 문의 #{element.type} 으로 하고 테스트를 해보니깐 list 의 맨 마지막 값으로 모든 값들이 update 되어 버렸다.



<insert id="insertWordList" parameterType="List">

insert into tbl_word

(word, type, modTime, isName)

values

<foreach collection="list" item="element" separator=",">

( #{element.word}, #{element.type}, UNIX_TIMESTAMP() * 1000 , #{element.isName}

</foreach>

on duplicate key update

    type = #{element.type}

    ,modTime = UNIX_TIMESTAMP() * 1000 

    ,isName = #{element.isName}

</insert>


 구글에서 검색해서 제일 먼저 나오는 예제들은 foreach 에서 사용했던 데이터를 이용하는게 아니라, mysql 함수나 단순 연산만 사용한 쿼리문이었다. 포기하고 프로그래밍으로 for 문 돌려야하나 싶었는데, 역시나 외국 사이트에서 해답을 발견했다.


<insert id="insertWordList" parameterType="List">

insert into tbl_word

(word, type, modTime, isName)

values

<foreach collection="list" item="element" separator=",">

( #{element.word}, #{element.type}, UNIX_TIMESTAMP() * 1000 , #{element.isName}

</foreach>

on duplicate key update

    type = values(type)

    ,modTime = UNIX_TIMESTAMP() * 1000 

    ,isName = values(isName)

</insert>

 values() 를 사용해서 list 에서 iteration 마다 각각의 값들을 지정할 수 있다.


참고 사이트

http://opinionminer.blogspot.kr/2012/10/mybatis-insert-multiple-rows-if-doesnt.html