티스토리 뷰

반응형

같은 테이블에 여러번 row를 입력하여야 하는 경우 이전에 작성했던 방식은 foreach 문을 돌려서 여러번 입력을 진행하곤 했습니다.

그렇다 보니 발생하는 문제는 정말 많은 row를 입력할 때 성능적인 문제가 발생하고 종종 트랜잭션과 관련된 문제가 발생하기도 했습니다. 

 

이전에 방식을 소스로 표현하면 아래와 같습니다.

 

JavaSomeService.java

public int insertList(List<ObjectDto> list) {
    int count = 0;
    for(ObjectDto dto : list) {
        dao.insert("SomeMapper.insertSomething", dto);
        count++;
    }
    return count;
}

 

SomeMapper.xml

<parameterMap id="req" type="com.abbo.tistory.com.ObjectDto" />

<insert id="insertSomething" parameterMap="req">
   INSERT INTO schema.something 
       (id, col1, col2, col3)
   VALUES
       (#{id}, #{col1}, #{col2}, #{col3})
</insert>

 

위와 같은 구조에서는 insert 문이 매번 다르게 호출됩니다. 

그래서 그런지 서버와 DB의 물리적 거리 차이가 있다면, 즉 같은 서버에서 작동되고 있지 않다면 위 로직을 실행하였을 때 지연이 생기게 됩니다. 

 

이제 이 부분을 foreach 문을 활용하여 바꿔보려합니다. 

먼저 자바 부분을 확인해보겠습니다. 

(저 같은 경우는 HashMap을 흔히 사용할 수 있어서 이렇게 변경하였지만, dto를 생성하여 세팅하고 실행하여도 됩니다.)

 

JavaSomeService.java

public int insertListV2(List<ObjectDto> list) {
    int count = 0;
    Map<String, Object> map = new HashMap<>();
    map.put("list", list);
    
    // 실행 결과 row 갯수를 리턴합니다.
    count += dao.insert("SomeMapper.insertSomething", map);
    return count;
}

 

SomeMapper.xml

<insert id="insertSomething" parameterType="java.util.Map">
   INSERT INTO schema.something 
       (id, col1, col2, col3)
   VALUES
       <foreach item="item" index="index" collection="list" separator=",">
           (#{item.id}, #{item.col1}, #{item.col2}, #{item.col3})       
       </foreach>
</insert>

 

이렇게 작성하고 호출하면 한 번에 데이터를 입력하는 것이 가능해지고 성능도 개선되는 것을 확인해보았습니다.

 

반응형
댓글
공지사항