이호영 이호영 2024-11-28
문자전송 insert batch 로 구현 테스트
@645a410e24af6749397d487019f7ad00063fc1ab
src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataDAO.java
--- src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataDAO.java
+++ 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 @@
 @Repository("MjonMsgDataDAO")
 public class MjonMsgDataDAO extends EgovAbstractDAO {
 
+
+	@Autowired
+	private DataSource dataSource;
+	
 	@SuppressWarnings("unchecked")
 	public List<MjonMsgDataVO> selectCcmCmmCodeList() throws Exception{
 		
@@ -380,4 +393,95 @@
 		return result;
 	}
 	
+
+	/**
+	 * 다량 데이터를 Batch 처리로 MJ_MSG_DATA 테이블에 INSERT
+	 *
+	 * @param mjonMsgSendVOList - 삽입할 데이터 리스트
+	 * @return 성공적으로 삽입된 데이터 건수
+	 */
+	public int insertMsgDataInfo_jdbc_advc(List<MjonMsgSendVO> 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;
+	}
+	
 }
src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataServiceImpl.java
--- src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataServiceImpl.java
+++ src/main/java/itn/let/mjo/msgdata/service/impl/MjonMsgDataServiceImpl.java
@@ -4168,21 +4168,39 @@
 
 		// 시작 시간 측정
 		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<MjonMsgSendVO> 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") );
 		
Add a comment
List