[Servlet] 03-2 | JDBC 프로그래밍 5가지 단계
JDBC (Java DataBase Connectivity), 즉 java.sql 패키지를 이용하여 프로그램과 데이터베이스를 연동하려면 5가지 단계가 필요합니다. 이번 글에서는 JDBC 프로그래밍의 5가지 단계를 알아보겠습니다.
- 예제에서 사용하는 데이터베이스: MySQL 8
JDBC 프로그래밍 5가지 단계는 다음과 같습니다.
- 1단계: JDBC 드라이버 객체 생성 및 등록
- 2단계: 데이터베이스와의 커넥션(Connection) 획득
- 3단계: 데이터베이스에 SQL문을 담아 보낼 PreparedStatemet 생성
- 4단계: PreparedStatement를 통해 데이터베이스에 SQL문 전송
- 5단계: 데이터베이스와의 커넥션 해제
다음은 JDBC 프로그래밍 5단계를 구현한 전체 코드입니다.
위 코드를 자세하게 살펴보겠습니다.
JDBC 프로그래밍을 위해 준비해야 할 변수들은 다음과 같습니다.
- driver 변수: DBMS 개발사에서 제공하는 jar 형태의 JDBC 드라이버 내부에 있는 Driver 클래스의 이름을 담을 변수
*MySQL 5버전) Driver 클래스의 위치: "com.mysql.jdbc" 패키지
*MySQL 8버전) Driver 클래스의 위치: "com.mysql.cj.jdbc" 패키지 - jdbcUrl 변수: 데이터베이스와 연동하기 위해 필요한 URL 주소를 명시
*MySQL: "jdbc:mysql://{서버 IP 주소}:{MySQL 포트 번호(3306)}/{연동하려는 데이터베이스의 이름}
- 옵션이 있을 경우 ? 뒤에 명시함. 여러 옵션이 나올 경우 & 으로 구분함.
- 예시) jdbc:mysql://localhost:3306/myproject?characterEncoding=UTF-8&serverTimezone=UTC - db_user, db_pwd 변수: 데이터베이스에 접속할 때 필요한 사용자 이름과 비밀번호를 명시
1단계 드라이버 객체 생성 및 등록
JDBC 프로그래밍에서 가장 먼저 하는 작업은 드라이버 객체를 등록하는 것입니다. JDBC 프로그래밍에서 사용하는 드라이버 클래스는 DBMS 개발사에서 제공하는 jar 형태의 JDBC 드라이버 파일 내부에 있습니다. 이 JDBC 드라이버 파일은 웹 사이트에서 직접 다운받아 웹 어플리케이션에 직접 추가하는 방법도 있고, Maven이나 Gradle과 같은 빌드 도구를 이용하여 원격 저장소에서 파일을 끌어와 쓰는 방법도 있습니다. 이와 관련된 자세한 내용은 참고 자료에 있는 도서 등을 참조해 주시기 바랍니다.
드라이버 객체를 생성할 때, String 자료형으로 된 드라이버 클래스의 이름을 이용합니다. Class라는 클래스의 forName이라는 메서드를 이용하면 클래스 이름을 가지고 그 클래스의 객체를 생성할 수 있습니다.
*Clsss.forName 메서드는 인수로 입력받은 클래스가 존재하지 않아 클래스 생성에 실패할 경우를 대비하여 ClassNotFoundException이라는 예외 처리를 강요합니다.
드라이버 객체를 등록하는 또 다른 방법으로는 java.sql 패키지에 위치한 DriverManager 클래스의 registerDriver 메서드를 이용하는 것입니다. 이 방법을 사용할 경우 DriverManager.registerDriver 메서드의 인수로 드라이버 객체를 생성하여 넣어줘야 합니다.
*DriverManager.registerDriver 메서드는 SQLException이라는 예외 처리를 강요합니다.
이번 글에서는 Class.forName 메서드로 드라이버 객체를 생성하도록 하겠습니다.
2단계 DB와 커넥션 연결
드라이버 객체를 생성했다면 다음은 데이터베이스와의 커넥션(Connection)을 얻을 차례입니다.
java.sql 패키지에 있는 Connection 클래스의 객체를 담을 변수는 try문 밖에서도 접근할 수 있도록 try문 밖에서 선언해줍니다.
Connection 객체를 생성할 때는 DriverManager 클래스의 getConnection 메서드를 이용합니다. 메서드의 인수로는 위에서 준비해두었던 JDBC URL(변수 jdbcUrl)과 데이터베이스 사용자 이름(변수 db_user), 비밀번호(변수 db_pwd)를 넣습니다.
*DriverManager.getConnection 메서드는 SQLException 예외 처리를 강요합니다.
3단계 PreparedStatement 생성
데이터베이스와의 Connection을 얻었다면 이제 데이터베이스에 보낼 SQL문을 담을 PreparedStatement를 생성할 차례입니다.
java.sql 패키지에 있는 PreparedStatement 클래스의 객체를 담을 변수 또한 try문 밖에서도 접근할 수 있도록 try문 밖에서 선언해줍니다.
PreparedStatement 객체는 Connection 객체의 prepareStatement 메서드를 이용하여 생성합니다. 이 메서드의 인수로는 데이터베이스에 보낼 SQL문을 넣습니다. 다만 구체적인 값을 담는 대신 파라미터(`?`)가 포함된 SQL문을 넣습니다.
4단계 SQL 전송
PreparedStatement 객체를 생성했다면 다음은 이 객체에 담을 SQL문을 완성할 차례입니다. PreparedStatement의 setString, setInt, setDate 등의 메서드를 이용하여 SQL문의 파라미터에 값을 채워줍니다.
SQL문을 완성했다면 SQL문을 데이터베이스에 전송합니다. 이때 PreparedStatement의 메서드를 이용하면 되는데 어떤 SQL문인지에 따라 사용하는 메서드가 달라집니다.
- executeUpdate: INSERT, UPDATE, DELETE문 -> 반환형: int (수행된 SQL문에 의해 영향을 받은 레코드의 수)
- executeQuery: SELECT -> 반환형: ResultSet (수행된 SQL문에 의해 조회된 일종의 테이블)
5단계 연결 해제
SQL문 수행이 종료되면 데이터베이스 연동을 위해 생성했던 모든 객체들을 반납해야 합니다. Connection의 경우 데이터베이스로부터 생성할 수 있는 Connection의 수가 제한되어 있기 때문에 프로그램이 종료되기 직전에 반드시 데이터베이스와의 연결을 해제해야 합니다.
try문 안에 있는 메서드들의 수행이 성공(try문)하였든 실패(catch문)하였든 생성되었던 PreparedStatement와 Connection 객체는 모두 반납되어야 하기 때문에 이들 객체를 반납하는 코드는 finally문에 작성합니다. finally에 있는 코드는 try~catch문을 빠져나가기 위해 최종적으로 거쳐야 하는 공통의 출입구입니다.
PreparedStatement를 Connection으로부터 얻었으므로 PreparedStatement를 먼저 반납한 후에 Connection을 반납합니다. 그리고 PreparedStatement나 Connection 객체가 생성되지 않은 경우도 있을 것이므로 이들 객체를 반납하는 코드를 if문으로 감싸서 객체들이 null이 아닌 경우에만 close 메서드가 수행되도록 처리합니다.
참고 자료
도서
- 채규태, <04장 JDBC 프로그래밍>, <<채쌤의 Servlet&JSP 프로그래밍 핵심>>, 쌤즈, 2022년, 90~101쪽