반응형

spring 에서 mybatis 로 bulk upsert 를 해줘야 할때 아래와 같이 작업을 했다.

 

jpa 를 사용하면 saveall 메소드로 bulk upsert 가 가능했는데, mybatis 에서는 메소드를 직접 만들다 보니 그런게 없어서, 직접 만들어줘야 한다.

일반적으로는 pk 로 데이터 조회 후 없으면 insert 있으면 Update 를 해줘야 하나 매번 select 를 하기 db 커넥션도 아깝고 코드가 번거롭다.

하지만 mysql 에는 ON DUPLICATE KEY UPDATE 기능 이 있어 이미 데이터가 있다면 update 를 할 수 있다. 

 

해당 방식은 INSERT를 하다가 PK값이 존재하면 UPDATE를 한다는 조건이 있는데 이 조건을 만족하기 위해 테이블에 무조건 PK값이 지정이 되어있어야 정상적으로 동작한다.

Mapper

@Repository
public interface TestMapper {

    int upsertData(List<Data> dataList);

}

mybatis 쿼리

<insert id="upsertData" parameterType="Data">
        INSERT INTO 테이블명 (id, data_name, data_category)
        VALUES
        <foreach collection="list" index="index" item="item" separator=",">
            (
            #{item.id},
            #{item.dataName},
            #{item.dataCategory}
            )
        </foreach>
        ON DUPLICATE KEY UPDATE building_name=VALUES(dataName), building_category=VALUES(dataCategory);
</insert>

parameterType 에는 List 객체 내부 클래스를 사용하고, collection 에 list 를 명시하고 다음과 같이 foreach 구문을 사용한다.

ON DUPLICATE KEY UPDATE 에는 pk를 제외한 update 쳐야 하는 컬럼명을 명시해준다.

ON DUPLICATE KEY UPDATE  도 for 문을 작성할 필요는 없다.

 

데이터 클래스

public class Data {
     private int id;
     private String dataName;
     private String dataCategory;
 }

사용예시

List<Data> list = new ArrayList<>();
list.add(data1);
list.add(data2);
list.add(data3);
~~

testMapper.upsertData(list);

 

위의 예시가 bulk upsert 이니깐, bulk insert 및 bulk update 는 ON DUPLICATE KEY UPDATE 키워드만 빼고, foreach 구문만 사용하면 된다.

 

 

 

참고문헌 > https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html [ON DUPLICATE KEY UPDATE 공식문서]

반응형

+ Recent posts