MyBatis에는 foreach 라는 것을 이용해서 Batch Insert를 할 수 있는 기능을 제공해줍니다.
foreach를 통해서 데이터를 INSERT 하는 것과 한 건씩 여러번 INSERT 하는 성능 차이가 얼마나 날까? 라는 생각을 할 수 있습니다.
저는 처음에 insert문을 만들때 한 건씩 등록하는 로직을 제작을 하였는데 137만건 정도의 insert를 두번이상하니깐 한 건씩 등록하는건 약 1시간 30분정도 걸리더라구요.
그래서 찾아보니깐 foreach를 이용해서 insert를 하면 성능이 좋다고 합니다.
foreach를 이용해서 insert를 한 것은 약 3분정도 걸렸어요. 약 30배 이상 차이가 나는 것을 볼 수 있었습니다.
* 성능 차이가 나는 이유
1. MyBatis 인터페이스 메소드 호출 -> Mapper id 검색 -> Query 수행 x 10000
간단히 말하면 위와 같이 MyBatis가 실행되는 과정, 쿼리 실행 모두의 과정이 만번이 발생하게 되는 것입니다. 시간이 많이 걸릴 수 밖에 없습니다.
2. MyBatis 인터페이스 메소드 호출 -> Mapper id 검색 과정이 1번만 실행되고 쿼리단에서만 만번이 실행되는 것입니다. 따라서 첫 번째보다 상대적으로 상당히 빠르게 INSERT 할 수 있습니다.
* 이제 예제를 통해서 foreach문 사용방법을 알아보자!
[java]
// 등록 예제
// DB에 있는 정보들을 가져와 insert하기
@Override
public Object putInfo(InfoVO vo) throws SQLException, ApiException, Exception {
logger.info("====================== 등록 테스트[putInfo] ======================");
int limit = 10000;
String title = infoMapper.selectTitle(); //제목을 가져옴
List<InfoVO> targetList = infoMapper.selectOncoTargetList(vo); //넣을 정보들을 가져옴
List<List<InfoVO>> voTrgList = new ArrayList<List<InfoVO>>(); //만건씩 끊어서 넣을 list
//DB에 등록 시, 제목이 같다고 가정하고 제목을 동일하게 넣어두는 것
for(int j=0; j<targetList.size(); j++) {
targetList.get(j).setTitle(title);
}
// 10000건씩 list
for(int i=0; i<targetList.size(); i+=limit) {
voTrgList.add( targetList.subList(i, Math.min(i+limit, targetList.size()) ) );
}
// insert
for(List<InfoVO> list : voTrgList) {
// insert문 실행
InfoMapper.insertTarget(list);
}
}
==========================================================================
// service
public int insertTarget(List<InfoVO> list) throws SQLException, Exception;
[xml]
▶foreach문
- collection : 전달받은 인자. List or Array 형태만 가능
- item : 전달받은 인자 값을 alias 명으로 대체
- open : 구문이 시작될때 삽입할 문자열
- close : 구문이 종료될때 삽입할 문자열
- separator : 반복 되는 사이에 출력할 문자열
- index : 반복되는 구문 번호이다. 0부터 순차적으로 증가
<insert id="insertTarget" parameterType="java.util.List">
INSERT INTO test_db.test01
(test_sn, title , user_id)
VALUES
<foreach collection="list" item="infoVO" separator=",">
(#{infoVO.testSn}::numeric, #{infoVO.title }, #{infoVO.userId})
</foreach>
</insert>
'Spring > DB_MyBatis' 카테고리의 다른 글
[mybatis] foreach활용하여 다중 update하기 (0) | 2025.04.28 |
---|---|
[MyBatis] parameter type string if문 사용법 (0) | 2024.01.15 |
[ mybatis ] insert/update 쿼리 실행 후 값 가져오기(useGeneratedKeys, keyProperty, SelectKey) (0) | 2022.03.15 |
[Spring] 검색 시 특수문자(%, _ , \) 포함하여 검색하기 (0) | 2022.03.10 |
[MyBatis] 개발 생산성 향상,중복 쿼리 줄이기 <sql>,<include> 개념 및 문법 (0) | 2022.03.10 |
댓글