본문 바로가기
Java/JDBC

JDBC) JDBC Coding 절차 (DQL, DML)

by 박채니 2022. 5. 4.

안녕하세요, 코린이의 코딩 학습기 채니 입니다.

 

개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.


JDBC란? (Java DataBase Connectivity)

- 자바 언어에서 Database에 접근할 수 있게 해주는 Programming API

 

자바에서 DB Server에 접근할 수 있도록 JDBC API를 제공 (java.sql.*) 해줍니다.

하지만 제공되는 JDBC API (java.sql.*)은 대부분 인터페이스 클래스들만을 가지고 있습니다. (인터페이스는 객체화가 불가!)

따라서 반드시 구현 클래스가 있어야 하는데, 이러한 구현 클래스들을 DB를 만든 Vender사에서 제공해줍니다.

(DB에 접속하기 위한 구현 클래스들을 Vender사에서 제공해줌 - 이를 jdbc driver라고 함)

따라서 자바는 DB의 Vender사에서 제공해주는 jdbc driver를 장착하고 DB Server에 접근할 수 있습니다.

 

저는 오라클을 사용하기 때문에 오라클이 제공해주는 jdbc drvier인 ojdbc.jar를 장착합니다.

(연동방법은 아래 참고!)

https://chanychu.tistory.com/209 

 

JDBC) 환경 설정 및 이클립스와 오라클 연동

안녕하세요, 코린이의 코딩 학습기 채니 입니다. 개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다. JDBC를 위해선 이클립스가 깔려있어야 합니다. (아래 포스팅 참고!) https://ch

chanychu.tistory.com

 


JDBC Coding 절차

① DriverManager에 해당 DBMS Driver 등록

② 해당 Driver로부터 Connection instance 획득

③ Connection instance로부터 PreparedStatement instance 획득

④ PreparedStatement 메소드를 이용하여 SQL문 실행

⑤ 실행 후 결과를 ResultSet(Select) 혹은 int형 변수(DML)로 받아서 처리

⑥ 사용한 자원 반납

 

DQL

① jdbc driver class 등록 
② Connection객체 생성
③ PreparedStatment객체 생성 & 미완성쿼리 값대입
④ executeQuery 실행 & ResultSet 리턴받기
⑤ ResultSet 처리
⑥ 자원반납 : 생성의 역순으로 반환

public class JdbcTest {

	final String driverClass = "oracle.jdbc.OracleDriver";
	final String url = "jdbc:oracle:thin:@localhost:1521:xe";	//db접속프로토콜@ip:포트:db명(sid)
	final String user = "student";
	final String password = "비밀번호";
	
	public static void main(String[] args) {
		JdbcTest instance = new JdbcTest();
		instance.test1();
	}
	
	/**
	 * DQL
	 */
	public void test1() {
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rset = null;
		String sql = "select * from member";
		
		try {
//		1. jdbc driver class 등록 
			Class.forName(driverClass);
			System.out.println("> 드라이버 클래스 등록 완료!");
			
//		2. Connection객체 생성
			conn = DriverManager.getConnection(url, user, password);
			System.out.println("> DB 연결 성공!");
			
//		3. PreparedStatment객체 생성 & 미완성쿼리 값대입
			pstmt = conn.prepareStatement(sql);
			System.out.println("> PreparedStatement 객체 생성 성공!");
			
//		4. executeQuery 실행 & ResultSet 리턴받기
			rset = pstmt.executeQuery();
			System.out.println("> 실행 및 결과집합 수신 성공!");
			
//		5. ResultSet 처리
		// next호출시 다음행이 있는 경우, true를 반환후 포인터를 다음행으로 이동
			while(rset.next()) {
				// 레코드에 컬럼명으로 접근(컬럼타입)
				String id = rset.getString("id");	// 컬럼명 대소문자는 구분하지 않음
				String name = rset.getString("name");
				String gender = rset.getString("gender");
				Date birthday = rset.getDate("birthday");	// java.sql.Date 임포트
				String email = rset.getString("email");
				int point = rset.getInt("point");	// 정수형 처리
				Timestamp regDate = rset.getTimestamp("reg_date");	// java.sql.Timestamp 임포트	
			
				System.out.printf("%s\t%s\t%s\t%s\t%s\t%s\t%s%n",
						id, name, gender, birthday, email, point, regDate);
			}
			
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		} finally {
//		6. 자원반납 : 생성의 역순으로 반환
			try {
				rset.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			try {
				pstmt.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			try {
				conn.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			System.out.println("> 자원반납 완료!");
		}
	}
}

@콘솔출력값
> 드라이버 클래스 등록 완료!
> DB 연결 성공!
> PreparedStatement 객체 생성 성공!
> 실행 및 결과집합 수신 성공!
honggd	홍길동	M	1999-09-09	honggd@naver.com	1000	2022-05-02 17:11:48.37
sinsa	신사임당	F	1995-05-05	sinsa@naver.com	1000	2022-05-02 17:12:31.805
gogd	고길동	M	1980-02-15	gogd@naver.com	1000	2022-05-02 17:13:15.411
leess	이순신	F	null	leess@naver.com	1000	2022-05-02 17:13:56.21
qwerty	쿼티	F	null	qwerty@naver.com	1000	2022-05-02 17:14:30.632
koo	입벌구	M	1989-08-09	koo@naver.com	1000	2022-05-03 20:33:18.263
> 자원반납 완료!

* driverClass → (ojdbc8.jar) oracle.jdbc 패키지에 OracleDriver 클래스 (ojdbc8.jar의 시작점과 같은 클래스)를 사용하겠다는 것!

만일, ojdbc8.jar이 프로젝트와 연결이 되어있지 않다면 Class.forName(driverClass)에서 오류가 발생 (ClassNotFoundException)

* url → 내가 접속하려고 하는 DB 주소를 담음

* id → DB에 접속할 아이디

* password → DB에 접속할 아이디의 비밀번호

 

☞ Connection 객체 생성 시 JDBC API에서 제공해주는 DriverManager의 static 메소드 getConnection에 url, id, password를 넘겨주어 DB 접속 실행!

(url이 잘못 되었거나, id/password가 잘못 되었다면 SQLException 발생)

※ SQLException은 JDBC 관련하여 최상위 예외!!

 

ResertSet은 한 행 씩 접근하므로 while(rset.next())를 이용하여 행을 받아옵니다.

(next() 호출 시 다음 행이 있는 경우 true 반환 후 포인터를 다음 행으로 이동 시켜줌)

받아올 때 컬럼의 타입과 동일하게 맞춰주고, 컬럼명으로 접근하여 정보를 가져와 출력하였습니다.

 

자원반납은 생성의 역순으로 반납해줘야 하므로, rset → pstmt → conn 순서대로 반납해주었습니다.

 

이러한 과정을 거쳐 DQL을 처리해보았습니다.

 


DML

① jdbc driver class 등록
② Connection 객체 생성 & autoCommit false로 설정 (기본값 true)
③ PreparedStatement 객체 생성 & 미완성 쿼리 값 대입
④ executeUpdate 실행 & 정수형(처리된 행 수) 리턴 값
⑤ 트랜잭션 처리 
⑥ 자원반납

public class JdbcTest {

	final String driverClass = "oracle.jdbc.OracleDriver";
	final String url = "jdbc:oracle:thin:@localhost:1521:xe";	//db접속프로토콜@ip:포트:db명(sid)
	final String user = "student";
	final String password = "비밀번호";
	
	public static void main(String[] args) {
		JdbcTest instance = new JdbcTest();
//		instance.test1();
		instance.test2("M", "leess");
	}
	
	public void test2(String gender, String id) {
		Connection conn = null;
		PreparedStatement pstmt = null;
		int result = 0;
		String sql = "update member set gender = ? where id = ?";	// ?에 전달 받은 값 대입
		
		try {
			// 1. jdbc driver class 등록
			Class.forName(driverClass);
			
			// 2. Connection 객체 생성 & autoCommit false로 설정 (기본값 true)
			conn = DriverManager.getConnection(url, user, password);
			conn.setAutoCommit(false);	// commit, rollback 처리를 직접하기 위한 설정
			
			// 3. PreparedStatement 객체 생성 & 미완성 쿼리 값 대입
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, gender);	// 첫번째 ?에 gender 대입 ? -> 'M'
			pstmt.setString(2, id);		// 두번째 ?에 id 대입 ? -> 'leess'
			
			// 4. executeUpdate 실행 & 정수형(처리된 행 수) 리턴 값
			result = pstmt.executeUpdate();	// DML이면 executeUpdate()!
			
			// 5. 트랜잭션 처리 
			conn.commit();
			System.out.println(result + "행이 수정되었습니다.");
		} catch (ClassNotFoundException | SQLException e) {
			try {
				conn.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		} finally {
			// 6. 자원반납
			try {
				pstmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}

@콘솔출력값
1행이 수정되었습니다.

 

select * from member;

실제 DB의 member 테이블에 수정된 정보로 잘 변경 되어있는 것을 확인할 수 있습니다.

 

☞ autoCommit false로 설정 → autoCommit의 기본 값은 true이지만 (DML 실행 될 때마다 commit 처리), 직접 트랜잭션 처리를 하기 위해 false로 변경

☞ int insert = 0처리된 행의 수를 반환해주므로 (executeUpdate()), 정수형 변수를 선언 및 대입

commit 시 예외가 발생하면 try 절에서 rollback 해주어 예외를 처리해줍니다.

 

이 외에는 DQL 처리 시 절차와 유사하며, 위 처럼 DML을 처리하였습니다.