Programming/Java
[Java] JDBC 대용량 데이터 처리 - addBatch, executeBatch, PreparedStatement
OriginMaster
2022. 2. 16. 22:29
반응형
- 필요성 : 10만건이 넘는 데이터를 DB에 insert할 이슈가 있었다. 기존의 Mybatis를 이용해서 처리하는 과정에서 foreach 생성만 해도 시간 소요가 상당함을 발견했다. Mapper/DAO 처리 대신 JDBC connection을 직접 코딩해주어야 하지만 속도는 훨씬 빠르다.
public void insertList(List<LinkedHashMap<String,String>> list, int processAmount) throws Exception {
Connection con = null;
PreparedStatement pstmt = null;
StringBuffer sb = new StringBuffer("INSERT INTO T_TABLE( ")
.append("M_A")
.append("M_B")
.append("M_C")
.append(") VALUES(?, ?, ?)");
String sql = sb.toString();
try{
Class.forName("core.log.jdbc.driver.OracleDriver");
con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE","SCOTT","TIGER");
//exception시 롤백할 수 있도록 auto commit false
con.setAutoCommit(false);
pstmt = con.prepareStatement(sql);
//prepareStatement for
for(int i=0; i < list.size(); i++) {
HashMap<String,String> map = list.get(0);
//pstmt.setString(index, param); // sql index 1부터 count
pstmt.setString(1, map.get("M_A"));
pstmt.setString(2, map.get("M_B"));
pstmt.setString(3, map.get("M_C"));
//addBatch 하기
pstmt.addBatch();
//파라미터 Clear
pstmt.clearParameters();
// OutOfMemory를 고려하여 processAmount 단위로 커밋
if( (i % processAmount) == 0){
// Batch 실행
pstmt.executeBatch() ;
// Batch 초기화
pstmt.clearBatch();
// 커밋
con.commit() ;
}
}
// Batch 실행
pstmt.executeBatch() ;
// Batch 초기화
pstmt.clearBatch();
// 커밋
con.commit() ;
} catch(Exception e){
this.log.error(e.getMessage());
//실패시 rollback
try {
con.rollback();
}catch(Exception e2) {
this.log.error(e2.getMessage());
}
}finally {
if(pstmt != null){pstmt.close(); pstmt = null;}
if(con != null){con.close(); con = null;}
}
}
반응형