java-school logo

JDBC 프로그래밍 방법

다음은 JDBC 프로그래밍 방법이다. 순서대로 외운다.

  1. JDBC 드라이버 로딩
  2. Connection 맺기
  3. SQL 실행
  4. [SQL문이 select문이었다면 ResultSet을 이용한 처리]
  5. 자원 반환

아래는 각 순서에 대한 설명이다. '오라클 JDBC 테스트'의 GetEmp.java 소스를 참조한다.

1. JDBC 드라이버 로딩

Class.forName("oracle.jdbc.driver.OracleDriver");

괄호안 문자열은 오라클 JDBC 드라이버 중 시작 클래스를 나타낸다. ojdbc6.jar 파일을 풀면 oracle.jdbc.driver 패키지의 OracleDriver.class를 확인할 수 있다. Class란 클래스의 forName() static 메서드가 쓰였는데 Class는 JDBC에 속한 클래스가 아니다. Class는 클래스 정보를 알아내기 위한 클래스로 forName(String) 메서드는 클래스 로더로 하여금 인자로 들어온 문자열에 해당하는 클래스를 메모리에 로딩하게 한다. forName() 메서드는 리턴하는 값이 있으나 JDBC 프로그래밍에서는 리턴 값이 필요없다. 클래스 로더가 클래스를 찾지 못한다면, 이 메서드는 ClassNotFoundException를 발생시킨다. 결론적으로 위 코드는 oracle.jdbc.driver.OracleDriver 클래스를 메모리에 로딩시킨다. 로딩된 OracleDriver 클래스는 자기 자신을 java.sql.DriverManager에 등록한다. 이후 DriverManager의 getConnection(,,)를 호출하면서 약속된 값을 인자로 전달하면, 오라클에서 만든 Connection 구현체가 리턴된다.

2. Connection 맺기

conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:XE", "scott", "tiger");

JDBC API는 대부분 인터페이스이다. DriverManager는 우리 예제에서 유일하게 온전한 클래스다. DriverManager는 이름 그대로 데이터베이스 벤더들이 선의 JDBC API를 구현한 드라이버를 관리한다. DriverManager.getConnection(,,) 메서드는 인자로 들어오는 값에 따라서 특정 데이터베이스 벤더가 구현한 Connection 타입의 객체를 반환한다. Connection 객체가 생성은 데이터베이스와 연결이 확립되었음을 의미한다.

3. SQL 실행

// Statement를 얻는다.
stmt = conn.createStatement();
// SQL문을 실행한다.
rs = stmt.executeQuery(query);

데이터베이스와 연결이 되었다면 이젠 SQL문을 DBMS에 전달해야 한다. SQL 문을 전송하기 위해서는 Statement 구현체나 PreparedStatement 구현체를 사용한다. Statement 구현체나 PreparedStatement 구현체는 Connection 구현체를 통해서 얻을 수 있다. SQL 문이 select 문일 경우 Statement 객체의 executeQuery() 메서드를 사용하고, insert나 update 문일 경우 executeUpdate() 메서드를 사용한다.

4. [SQL문이 select문이었다면 ResultSet을 이용한 처리]

while (rs.next()) {
	String empno = rs.getString(1);
	String ename = rs.getString(2);
	...
	..

SQL문이 select 문이면 반환한 레코드를 저장할 객체가 필요하다. 이때 레코드를 담는 그릇이 ResultSet이다. ResultSet을, 테이블 형태의 데이터를 저장하는, JDBC에서만 쓰이는 컬렉션이라 생각하자. ResultSet 객체는 커서를 가지는데, 반환된 직후 ResultSet 객체의 커서는 첫 번째 레코드 이전을 가리킨다. 따라서 첫 번째 레코드를 가리키려면 next() 메서드를 실행해야 한다. next() 메서드를 실행하면 커서가 한 단계 아래로 이동하고 이때 커서가 가리키는 곳에 레코드가 있다면 true를 반환한다.

5. 자원 반환

JDBC 프로그래밍에서 자원 반환은 정말 중요하다. 객체가 더이상 쓰이지 않을 때 가베지 컬렉터가 동작한다고 했는데 예외가 있다. 가베지 컬렉터는 객체 자체가 열심히 동작하고 있다고 판단되면 그 객체를 회수하지 않는다. JDBC와 관련된 객체가 이런 객체에 속한다. 따라서 JDBC와 관련된 작업이 끝나면 생성된 객체 자원을 반환해야 한다. 그러기 위해서 자원 반환 코드 조각을 finally 블록에 구현한다. finally 블록은 익셉션이 발생하건 안 하건 실행되는 블록이다. 다음 코드를 finally 블록에 구현해야 한다.

// ResultSet를 닫는다.
rs.close();
// Statement를 닫는다.
stmt.close();
// Connection를 닫는다.
conn.close();

자원 반환 순서는 생성한 순서의 반대로 반환한다.