본문 바로가기

MySql

[Mybatis] foreach insert duplicate update / 다중 insert시 update 처리

다중 insert시 PK중복인 데이터 update 처리

예전에 검색해서 알았는데도 잊어버려서 적어둔다. 기억력이란.. 자주 쓰지 않으면 역시 잊어버리는 듯.

 

일단 다중 insert문은 간단하다.

<insert id="insertData" parameterType="java.util.List">
  insert into user (NICK, NAME, PHONE)
  values
  <foreach collection="list" item="item" separator=",">
    (#{item.nick,jdbcType=VARCHAR}, #{item.phone,jdbcType=VARCHAR}, #{item.name,jdbcType=VARCHAR})
  </foreach>
</insert>  

 

여기서 NICK 이라는 PK가 중복 되었을 때, 다른 정보는 update를 시켜주고 싶다면?

일단 >on duplicate key update<가 생각날 것이다.

<insert id="insertData" parameterType="java.util.List">
  insert into user (NICK, NAME, PHONE)
  values
  <foreach collection="list" item="item" separator=",">
    (#{item.nick,jdbcType=VARCHAR}, #{item.phone,jdbcType=VARCHAR}, #{item.name,jdbcType=VARCHAR})
  </foreach>
  on duplicate key update PHONE = #{item.phone,jdbcType=VARCHAR}, NAME = #{item.name,jdbcType=VARCHAR}
</insert>  

그렇다고 이런 식으로 작성하면 item이 foreach문에서만 유효한 지역변수이기 때문에 밖에서 사용할 수 없어 에러가 난다.

 

그렇다면 이건 어떻까?

<insert id="insertData" parameterType="java.util.List">
  <foreach collection="list" item="item" separator=",">
    insert into user (NICK, NAME, PHONE)
    values
      (#{item.nick,jdbcType=VARCHAR}, #{item.phone,jdbcType=VARCHAR}, #{item.name,jdbcType=VARCHAR})
    on duplicate key update PHONE = #{item.phone,jdbcType=VARCHAR}, NAME = #{item.name,jdbcType=VARCHAR}
  </foreach>
</insert>  

옛날에는 이렇게도 해봤었지만.. 이제 그럴 연차는 아니니 그만두도록 하자.

 

정답은 valuse()였다.

예전에 구글링 했을 때 values()를 사용해야한다는 걸 봤는데 어디서 봤는지 찾을 수 없었다..

<insert id="insertData" parameterType="java.util.List">
  insert into user (NICK, NAME, PHONE)
  values
  <foreach collection="list" item="item" separator=",">
    (#{item.nick,jdbcType=VARCHAR}, #{item.phone,jdbcType=VARCHAR}, #{item.name,jdbcType=VARCHAR})
  </foreach>
  on duplicate key update PHONE = values(phone), NAME = values(name)
</insert>  

이렇게 작성하게 되면 깔끔하게 실행된다.

 

참고 사이트

dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html

opinionminer.blogspot.com/2012/10/mybatis-insert-multiple-rows-if-doesnt.html