From 645a410e24af6749397d487019f7ad00063fc1ab Mon Sep 17 00:00:00 2001 From: "hehihoho3@gmail.com" Date: Thu, 28 Nov 2024 09:21:03 +0900 Subject: [PATCH] =?UTF-8?q?=EB=AC=B8=EC=9E=90=EC=A0=84=EC=86=A1=20insert?= =?UTF-8?q?=20batch=20=EB=A1=9C=20=EA=B5=AC=ED=98=84=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../msgdata/service/impl/MjonMsgDataDAO.java | 104 ++++++++++++++++++ .../service/impl/MjonMsgDataServiceImpl.java | 22 +++- 2 files changed, 124 insertions(+), 2 deletions(-) diff --git a/src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataDAO.java b/src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataDAO.java index 8449df12..cc6d863e 100644 --- a/src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataDAO.java +++ b/src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataDAO.java @@ -1,7 +1,16 @@ package itn.let.mjo.msgdata.service.impl; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.List; +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import egovframework.rte.psl.dataaccess.EgovAbstractDAO; @@ -17,6 +26,10 @@ import itn.let.uss.umt.service.MberManageVO; @Repository("MjonMsgDataDAO") public class MjonMsgDataDAO extends EgovAbstractDAO { + + @Autowired + private DataSource dataSource; + @SuppressWarnings("unchecked") public List selectCcmCmmCodeList() throws Exception{ @@ -380,4 +393,95 @@ public class MjonMsgDataDAO extends EgovAbstractDAO { return result; } + + /** + * 다량 데이터를 Batch 처리로 MJ_MSG_DATA 테이블에 INSERT + * + * @param mjonMsgSendVOList - 삽입할 데이터 리스트 + * @return 성공적으로 삽입된 데이터 건수 + */ + public int insertMsgDataInfo_jdbc_advc(List mjonMsgSendVOList) { + String sql = "INSERT INTO MJ_MSG_DATA " + + "(MSG_ID, MSG_GROUP_ID, USER_ID, AGENT_CODE, CUR_STATE, REQ_DATE, CALL_TO, CALL_FROM, SUBJECT, SMS_TXT, MSG_TYPE) " + + "VALUES (?, ?, ?, ?, 0, ?, ?, ?, ?, ?, ?)"; + int totalInsertedCount = 0; + + try (Connection connection = dataSource.getConnection(); + PreparedStatement pstmt = connection.prepareStatement(sql)) { + + connection.setAutoCommit(false); // Auto-commit 비활성화 + + int batchSize = 5000; // Batch 크기 설정 + int count = 0; + + // 데이터 리스트 순회하며 PreparedStatement에 추가 + for (MjonMsgSendVO vo : mjonMsgSendVOList) { + pstmt.setString(1, vo.getMsgId()); + pstmt.setString(2, vo.getMsgGroupId()); + pstmt.setString(3, vo.getUserId()); + pstmt.setString(4, vo.getAgentCode()); + // reqDate 변환 후 설정 + Timestamp timestamp = convertToTimestamp(vo.getReqDate()); + pstmt.setTimestamp(5, timestamp); + + pstmt.setString(6, vo.getCallTo()); + pstmt.setString(7, vo.getCallFrom()); + pstmt.setString(8, vo.getSubject()); + pstmt.setString(9, vo.getSmsTxt()); + pstmt.setString(10, vo.getMsgType()); + + pstmt.addBatch(); // Batch에 추가 + count++; + + // Batch 크기마다 실행 + if (count % batchSize == 0) { + int[] batchResults = pstmt.executeBatch(); + totalInsertedCount += getSuccessCount(batchResults); + } + } + + // 남은 데이터 실행 + int[] batchResults = pstmt.executeBatch(); + totalInsertedCount += getSuccessCount(batchResults); + + connection.commit(); // 트랜잭션 커밋 + + } catch (SQLException e) { + throw new RuntimeException("JDBC Batch insert failed", e); + } + return totalInsertedCount; // 처리된 전체 데이터 수 반환 + } + + + + public Timestamp convertToTimestamp(String reqDate) { + try { + // 입력 형식이 yyyy/MM/dd HH:mm:ss인 경우 변환 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"); + LocalDateTime localDateTime = LocalDateTime.parse(reqDate.trim(), formatter); + + // LocalDateTime -> Timestamp로 변환 + return Timestamp.valueOf(localDateTime); + } catch (Exception e) { + throw new IllegalArgumentException("날짜 형식이 올바르지 않습니다: " + reqDate, e); + } + } + + /** + * Batch 실행 결과에서 성공한 건수 계산 + * + * @param batchResults - Batch 실행 결과 배열 + * @return 성공적으로 실행된 건수 + */ + private int getSuccessCount(int[] batchResults) { + int successCount = 0; + for (int result : batchResults) { + // 성공적인 실행일 경우 값이 1 또는 Statement.SUCCESS_NO_INFO + if (result >= 0 || result == java.sql.Statement.SUCCESS_NO_INFO) { + successCount++; + } + } + return successCount; + } + } diff --git a/src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataServiceImpl.java b/src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataServiceImpl.java index 50867dc6..ac472d15 100644 --- a/src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataServiceImpl.java +++ b/src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataServiceImpl.java @@ -4168,21 +4168,39 @@ public class MjonMsgDataServiceImpl extends EgovAbstractServiceImpl implements M // 시작 시간 측정 long startTime = System.currentTimeMillis(); + System.out.println("==================== insert 시작 ===================="); log.info("mj_msg_data insert start [{}]", mjonMsgSendVOList.size()); // 분할 최대건수가 되면 디비에 입력하기 - int instCnt = mjonMsgDataDAO.insertMsgDataInfo_advc(mjonMsgSendVOList); +// int instCnt = mjonMsgDataDAO.insertMsgDataInfo_advc(mjonMsgSendVOList); +// int instCnt = mjonMsgDataDAO.insertMsgDataInfo_jdbc_advc(mjonMsgSendVOList); + // + int instCnt = 0; + int batchSize = 5000; + // Batch 처리 + for (int i = 0; i < mjonMsgSendVOList.size(); i += batchSize) { + System.out.println(" i :: "+ i); + // Batch 크기만큼 리스트를 잘라냄 + List batchList = mjonMsgSendVOList.subList( + i, Math.min(i + batchSize, mjonMsgSendVOList.size()) + ); + + // DAO 메서드 호출 + int insertedCount = mjonMsgDataDAO.insertMsgDataInfo_advc(batchList); + instCnt += insertedCount; // 총 삽입된 건수 누적 + } + // 종료 시간 측정 long endTime = System.currentTimeMillis(); // 실행 시간 계산 (밀리초 -> 초로 변환) double executionTimeInSeconds = (endTime - startTime) / 1000.0; // 실행 시간 출력 - System.out.println("Execution time: " + executionTimeInSeconds + " seconds"); + System.out.println("Execution time :: " + executionTimeInSeconds + "초 " + "// insert Cnt :: "+instCnt); // mjonMsgSendVOList.stream().forEach(t-> System.out.print(t.toString()+"\n") ); // mjonMsgSendVOList.stream().forEach(t-> System.out.print(t.toString()+"\n") );