jdbc - batchquery

jinkyung·2021년 1월 15일

DBMS

목록 보기
20/21

기본 설정은 무조건 자동커밋되므로 중간에 에러가 생겨도 돌아갈 수가 없다.

그래서 한번에 커밋할 수 있도록 수동커밋으로 변경.

iscommit == false는 커밋이 되지 않았다는 뜻이고, 어디선가 오류가 발생하면 예외처리로 넘어가는데

원래 상태로 롤백하기 위해 주었다.

package ex02.jdbcp.batchquery;

import java.sql.*;

public class BatchInsertEx {

	static {
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
		} catch (ClassNotFoundException e) {

			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		// 2. url, id, pass
		String url = "jdbc:oracle:thin:@localhost:1521:xe";
		String id = "bitTest";
		String pass = "bitTest";

		
		// 3. 관련 클래스 변수 선언
		Connection con = null;
		Statement stmt = null;
		ResultSet rs = null;
		boolean isCommit = false; 	//커밋이 완료되었는지의 여부
		
		try {
			// 4. 오라클 서버 접속 객체 생성
			con = DriverManager.getConnection(url, id, pass);
			
			// 5. sql문 실행 객체 생성 
			stmt = con.createStatement();
			
			// 6. 배치 쿼리 작성(한번에 여러개의 sql문을 작성하고 동시에 실행한다)
			// 6.1 jdbc의 DML문 이후에 자동커밋 설정을 수동커밋으로 변경한다. 
			con.setAutoCommit(false);
			
			stmt.addBatch("INSERT INTO professor (pno, pname, section, orders, hiredate) VALUES ('1001','송강','화학','정교수',TO_DATE('1999-12-20:09:13:25','YYYY-MM-DD:HH24:MI:SS'))");
			stmt.addBatch("INSERT INTO professor (pno, pname, section, orders, hiredate) VALUES ('1002','곤송승','화학','정교수',TO_DATE('1998-01-20:09:13:25','YYYY-MM-DD:HH24:MI:SS'))");
			stmt.addBatch("INSERT INTO professor (pno, pname, section, orders, hiredate) VALUES ('1003','진명','화학','정교수',TO_DATE('1997-08-20','YYYY-MM-DD'))");
			stmt.addBatch("INSERT INTO professor (pno, pname, section, orders, hiredate) VALUES ('1004','시진','화학','부교수',TO_DATE('2000-12-20:09:13:25','YYYY-MM-DD:HH24:MI:SS'))");
			stmt.addBatch("INSERT INTO professor (pno, pname, section, orders, hiredate) VALUES ('1005','노지심','화학','부교수',TO_DATE('1995-03-20:09:13:25','YYYY-MM-DD:HH24:MI:SS'))");
			
			//7.실행
			int[] counts = stmt.executeBatch();	//각각의 sql문이 몇개행에 적용되었는지 
			isCommit = true;					//커밋이 완료되었다는 의미 
			con.commit();						//"commit" sql문 실행 
			con.setAutoCommit(true);			//수동커밋 -> 자동커밋 설정 변경 
				
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			// 전체 5개 sql문이 정상실행되지 않으면 모두 롤백(취소) 처리 한다. 
				try {
					if(!isCommit) con.rollback();	//true가 아니면 롤백해라. 문장 실행 중에 하나라도 문제가 생기면 catch를 거쳐  finally로 가서 rollback을 해버린다.
					
				//아래 부분은 객체 생성이 된 객체들을 닫기 처리한다. 
					if(rs != null) rs.close();
					if(stmt != null) stmt.close();
					if(con != null)	con.close();
							
				} catch (SQLException e) {
					e.printStackTrace();
				}
		}
		
				
	}

}

addBatch는 쿼리 실행을 하지 않고

쿼리 구문을 메모리에 올려두었다가, 실행 명령이 있으면 한번에 DB쪽으로 쿼리를 날린다.

-은행 예제

counts는 왜 배열이어야하는지..?

executeBatch() 메소드가 업데이트 수를 세서 배열로 리턴하니까..

package ex02.jdbcp.batchquery;

import java.sql.*;

public class BatchInsertEx {

	static {
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
		} catch (ClassNotFoundException e) {

			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		// 2. url, id, pass
		String url = "jdbc:oracle:thin:@localhost:1521:xe";
		String id = "bitTest";
		String pass = "bitTest";

		
		// 3. 관련 클래스 변수 선언
		Connection con = null;
		Statement stmt = null;
		boolean isCommit = false; 	//커밋이 완료되었는지의 여부
		
		try {
			// 4. 오라클 서버 접속 객체 생성
			con = DriverManager.getConnection(url, id, pass);
			
			// 5. sql문 실행 객체 생성 
			stmt = con.createStatement();
			
			// 6. 배치 쿼리 작성(한번에 여러개의 sql문을 작성하고 동시에 실행한다)
			// 6.1 jdbc의 DML문 이후에 자동커밋 설정을 수동커밋으로 변경한다. 
			con.setAutoCommit(false);
			
			String str0 = "UPDATE ibk SET money = money-50000 WHERE sname='홍길동'";
			String str1 = "UPDATE kb SET money = money+50000 WHERE sname='홍길동'";
			stmt.addBatch(str0);
			stmt.addBatch(str1);
			
			//7.실행
			int[] counts = stmt.executeBatch();	//각각의 sql문이 몇개행에 적용되었는지 
			isCommit = true;					//커밋이 완료되었다는 의미 
			con.commit();						//"commit" sql문 실행 
			con.setAutoCommit(true);			//수동커밋 -> 자동커밋 설정 변경 
			for (int i = 0; i < counts.length; i++) {
				System.out.println(""+ (i+1) + " 명령" + counts[i] + "행 적용");  //배열 개수 
			}
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			// 전체 5개 sql문이 정상실행되지 않으면 모두 롤백(취소) 처리 한다. 
				try {
					if(!isCommit) con.rollback();		//true가 아니면 롤백해라. 문장 실행 중에 하나라도 문제가 생기면 catch를 거쳐  finally로 가서 rollback을 해버린다.
					
				//아래 부분은 객체 생성이 된 객체들을 닫기 처리한다. 
					if(stmt != null) stmt.close();
					if(con != null)	con.close();
							
				} catch (SQLException e) {
					e.printStackTrace();
				}
		}
		
				
	}

}

update문을 에러가 나도록 바꿔보았다.

package ex02.jdbcp.batchquery;

import java.sql.*;

public class BatchInsertEx {

	static {
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
		} catch (ClassNotFoundException e) {

			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		// 2. url, id, pass
		String url = "jdbc:oracle:thin:@localhost:1521:xe";
		String id = "bitTest";
		String pass = "bitTest";

		
		// 3. 관련 클래스 변수 선언
		Connection con = null;
		Statement stmt = null;
		boolean isCommit = false; 	//커밋이 완료되었는지의 여부
		
		try {
			// 4. 오라클 서버 접속 객체 생성
			con = DriverManager.getConnection(url, id, pass);
			
			// 5. sql문 실행 객체 생성 
			stmt = con.createStatement();
			
			// 6. 배치 쿼리 작성(한번에 여러개의 sql문을 작성하고 동시에 실행한다)
			// 6.1 jdbc의 DML문 이후에 자동커밋 설정을 수동커밋으로 변경한다. 
			con.setAutoCommit(false);
			
			String str0 = "UPDATE ibk SET money = money-50000 WHERE sname='홍길동'";
			String str1 = "-UPDATE kb SET money = money+50000 WHERE sname='홍길동'";
			stmt.addBatch(str0);
			stmt.addBatch(str1);
			
			//7.실행
			int[] counts = stmt.executeBatch();	//여기서 에러가 발생. 밑으로 실행시키지 않는다.
			isCommit = true;					
			con.commit();						
			con.setAutoCommit(true);			
			for (int i = 0; i < counts.length; i++) {
				System.out.println(""+ (i+1) + " 명령" + counts[i] + "행 적용");  
			}
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			// 전체 5개 sql문이 정상실행되지 않으면 모두 롤백(취소) 처리 한다. 
				try {
                  //if(isCommit==false)와 같은 말
					if(!isCommit) {  //그러므로 isCommit은 아직 false, !isCommit은 if(true)가 되어 롤백 실행.
						con.rollback();
						System.out.println("원상태로 롤백하였습니다!!!");
						}		
					
				//아래 부분은 객체 생성이 된 객체들을 닫기 처리한다. 
					if(stmt != null) stmt.close();
					if(con != null)	con.close();
							
				} catch (SQLException e) {
					e.printStackTrace();
				}
		}						
	}
}

0개의 댓글