데이터베이스 프로그래밍 기초(4) : JSP에서 JDBC 프로그래밍하기(1)

de_sj_awa·2021년 5월 21일
0

자바에서 데이터베이스 프로그래밍을 할 때에는 JDBC API를 사용한다. JDBC는 Java Database Connectivity의 약자로서 자바에서 데이터베이스와 관련된 작업을 처리할 때 사용하는 API이다. 자바는 DBMS의 종류에 상관없이 하나의 JDBC API를 사용해서 데이터베이스 작업을 처리할 수 있기 때문에, 일단 익혀두면 모든 DBMS에 대해서 동일한 방식으로 데이터베이스 작업을 처리할 수 있게 된다.

1. JDBC의 구조

JDBC 프로그래밍에 대해서 설명하기 전에 먼저 간단하게 JDBC API의 구조에 대해서 살펴보자. JDBC API를 사용하는 어플리케이션의 개략적인 구조는 아래 그림과 같다.

JSP를 포함한 자바 어플리케이션에서 데이터베이스를 사용할 때에는 데이터베이스 종류에 상관없이 JDBC API를 이용해서 데이터베이스에 접근한다. 각각의 DBMS는 자신에게 알맞은 JDBC 드라이버를 제공하고 있다. JDBC API는 JDBC 드라이버를 거쳐 데이터베이스와 통신을 한다.

JDBC API를 사용하면 DBMS에 알맞은 JDBC 드라이버만 있으면 어떤 데이터베이스라도 사용할 수 있다. 현재 오라클, MySQL, MS-SQL 등 주요 DBMS에 알맞은 JDBC 드라이버를 제공하고 있기 때문에 JDBC 드라이버가 존재하지 않아서, JSP에서 데이터베이스 프로그래밍을 할 수 없는 상황은 발생하지 않을 것이다.

2. JDBC 드라이버 준비하기

JDBC 프로그래밍을 하려면 DBMS에 알맞은 JDBC 드라이버를 준비해야 한다. JDBC 드라이버는 클래스 형태로 존재하며 일반적으로 jar 파일로 제공된다. "C:\Program Files (x86)\MySQL\ConnectorJ 5.1" 폴더에서 mysql-connector-java-5.1.35-bin.jar 파일을 찾을 수 있을 것이다. 파일 이름의 숫자는 설치한 MySQL 버전에 따라 다르다.

웹 어플리케이션 폴더의 WEB-INF\lib 폴더에 JDBC 드라이버 파일을 복사하면 웹 어플리케이션에서 JDBC 드라이버를 사용할 수 있다.

3. JDBC 프로그래밍의 코딩 스타일

JDBC 프로그램의 전형적인 실행 순서는 다음과 같다.

  1. JDBC 드라이버 로딩
  2. 데이터베이스 커넥션 구함
  3. 쿼리 실행을 위한 Statement 객체 생성
  4. 쿼리 실행
  5. 쿼리 실행 결과 사용
  6. Statement 종료
  7. 데이터베이스 커넥션 종료

위 순서에 맞춰서 테이블로부터 정보를 읽어와 출력하는 JSP 예제를 작성해보자. 예제 소스 코드는 다음과 같다.

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.sql.DriverManager" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.Statement" %>
<%@ page import="java.sql.ResultSet" %>
<%@ page import="java.sql.SQLException" %>
<html>
<head>
    <title>회원 목록</title>
</head>
<body>

MEMBER 테이블의 내용
<table width="100%" border="1">
    <tr>
        <td>이름</td><td>아이디</td><td>이메일</td>
    </tr>
<%
    // 1. JDBC 드라이버 로딩
    Class.forName("com.mysql.jdbc.Driver");

    Connection conn = null;
    Statement stmt = null;
    ResultSet rs = null;
    
    try{
        String jdbcDriver = "jdbc:mysql://localhost:3306/chap04?"+"useUnicode=true&characterEncoding=utf8";
        String dbUser="jspexam";
        String dbPass="jsppw";
        
        String query = "select * from MEMBER order by MEMBERID";
        
        // 2. 데이터베이스 커넥션 생성
        conn = DriverManager.getConnection(jdbcDriver, dbUser, dbPass);
        
        // 3. Statement 생성
        stmt = conn.createStatement();
        
        // 4. 쿼리 실행
        rs = stmt.executeQuery(query);
        
        // 5. 쿼리 실행 결과 출력
        while(rs.next()){
%>
    <tr>   
        <td><%=rs.getString("NAME")%></td>
        <td><%=rs.getString("MEMBERID")%></td>
        <td><%=rs.getString("EMAIL")%></td>
    </tr>
<%    
        }
    }catch (SQLException ex){
        out.println(ex.getMessage());
        ex.printStackTrace();
    }finally {
        // 6. 사용한 Statement 종료
            if(rs != null) try { rs.close(); } catch(SQLException ex) {}
            if(stmt != null) try {stmt.close(); } catch (SQLException ex) {}
            
            // 7. 커넥션 종료
            if(conn != null) try { conn.close(); } catch (SQLException ex) {}
        }
%>
</table>

</body>
</html>

실행 결과는 다음과 같다.

MySQL DB 연결 과정에서 문제가 발생했는데, 에러 메시지가 'Accessed denied for'로 시작하면 다음 중 하나를 확인하기 바란다.

  • 데이터베이스를 올바르게 생성했는지
  • 데이터베이스에 접근할 때 사용한 DB 계정과 암호가 올바른지
  • 해당 계정이 데이터베이스에 접근할 권한이 있는지

4. DBMS와의 통신을 위한 JDBC 드라이버

JDBC 드라이버는 DBMS와의 통신을 담당하는 자바 클래스로서 위의 그림에서 설명했듯이 DBMS마다 별도의 JDBC 드라이버가 필요하다. 각 DBMS는 JDBC 드라이버를 jar 파일 형태로 제공한다.

JDBC 드라이버를 로딩해야 데이터베이스에 연결해서 원하는 작업을 수행할 수 있다. JDBC 드라이버를 로딩하는 방법은 다음과 같다.

try{
    Class.forName("JDBC 드라이버 클래스의 완전한 이름");
}catch(ClassNotFoundException ex){
    // 지정한 클래스가 존재하지 않은 경우 에러가 발생한다.
}

다음은 주요 데이터베이스의 JDBC 드라이버에 해당하는 클래스이다.

  • MySQL : com.mysql.jdbc.Driver
  • 오라클 : oracle.jdbc.driver.OracleDriver
  • MS SQL 서버 : com.microsoft.sqlserver.jdbc.SQLServerDriver

예를 들어, 오라클 JDBC 드라이버를 로딩할 때에는 다음과 같은 코드를 사용하면 된다.

try{
    Class.forName("oracle.jdbc.driver.OracleDriver");
}catch(ClassNotException ex){
    // 지정한 클래스가 존재하지 않을 경우 에러가 발생한다.
    // 에러 처리
}

Class.forName() 메서드는 지정한 클래스 정보를 담고 있는 Class 인인스턴스를 구해주는 기능만을 제공한다. JDBC 드라이버에 해당하는 클래스들은 Class.forName() 메서드를 통해서 로딩될 때 자동으로 JDBC 드라이버로 등록한다.

5. 데이터베이스 식별을 위한 JDBC URL

웹 주소를 구분할 때 http://www.google.com이나 http://javacan.tistory.com과 같은 URL을 사용하는 것처럼, 데이터베이스를 구분할 때에도 URL과 비슷한 형식을 갖는 JDBC URL을 사용한다. 사용하는 JDBC 드라이버에 따라서 JDBC URL의 표현 방식에 차이가 나는데 일반적인 형식은 다음과 같다.

jdbc:[DBMS]:[데이터베이스식별자]

예를 들어, 이 예제의 MySQL JDBC 드라이버는 다음과 같은 JDBC URL을 사용한다.

jdbc:mysql://HOST[:PORT]/DBNAME[?param1=value1&param2=value2&...]

여기서 [HOST]는 서버의 호스트 주소를 나타내며, [HOSTNAME]은 데이터베이스 이름을 나타낸다. [PORT]는 MySQL 서버가 사용하는 포트 번호를 나타낸다. JDBC URL 뒤에 몇 가지 설정 정보를 추가할 수 있으며, 표현 방식은 파라미터와 동일하다.

예를 들어, 로컬 PC에서 실행 중인 MySQL 서버의 chap14 데이터베이스를 나타낼 때에는 다음과 같은 JDBC URL을 사용하면 된다.

jdbc:mysql://localhost:3306/chap14

MySQL JDBC 드라이버가 MySQL 서버와 데이터를 주고받을 때 사용되는 캐릭터 셋을 올바르게 지정하지 않으면 한글이나 한자와 같은 글자가 잘못된 값으로 데이터베이스에 저장될 수 있다. 따라서, MySQL에서 한글 데이터를 올바르게 하기 위해서는 다음과 같이 추가 파라미터를 이용해서 캐릭터 셋을 알맞게 지정해주어야 한다.

jdbc:mysql://localhost:3306/chap14?useUnicode=true&characterEncoding=utf8

UTF-8의 경우 MySQL에서는 utf8을 값으로 사용하며 EUC-KR은 euckr을 값으로 사용한다. MySQL에서 지원하는 전체 캐릭터 셋 목록은 'show character set' 쿼리로 확인할 수 있다.

오라클에서 제공하는 JDBC 드라이버는 다음과 같은 형식의 JDBC URL을 사용한다.

jdbc:oracle:thin:@HOST:PORT:SID

여기서, HOST, PORT는 각각 오라클이 설치된 호스트이 주소와 포트 번호를 나타내며, SID는 사용할 데이터베이스의 SID를 나타낸다. 예를 들어, 로컬 서버에 설치된 오라클의 SID가 ORCL인 데이터베이스에 접근할 때에는 다음과 같은 JDBC URL을 사용한다.

jdbc:oracle:thin:@127.0.0.1:1521:ORCL

오라클 드라이버에는 Thin 드라이버와 OCI 드라이버가 있다. Thin 드라이버는 자바 언어로만 구현된 JDBC 드라이버로서 JDK만 설치되어 있으면 어디서든 사용할 수 있다. 반면에 OCI 드라이버는 네이티브(Native) 모듈을 사용하는 JDBC 드라이버로서 해당 모듈을 설치해주어야만 사용할 수 있다. 위 오라클 JDBC URL을 보면 jdbc:oracle:thin과 같이 'thin'이 포함되어 있는데, 이는 Thin 드라이버를 사용해서 연결함을 뜻한다.

참고

  • 최범균의 JSP2.3 웹 프로그래밍
profile
이것저것 관심많은 개발자.

0개의 댓글