본문 바로가기

JSP

04-1. JSP에서 JDBC프로그래밍하기 1

JDBC API : Java DataBase Connectivity의 약자. 자바에서 데이터베이스에 관련된 작업을 처리할 수 있도록 도와주는 API. 자바는 DBMS종류에 상관없이 하나의 JDBC API를 사용해서 데이터베이스 작업을 처리.

 

4.1 JDBC의 구조

자바 (웹)         ->  JDBC  –> JDBC 드라이버 –> 데이터베이스

어플리케이션           API   -> JDBC 드라이버 –> 데이터베이스

 

각각의 DBMS는 자신에게 알맞은 JDBC 드라이버를 제공. JDBC API는 JDBC드라이버를 거쳐 데이터베이스와 통신을 한다.

 

4.2 JDBC 드라이버 준비하기

 

JDBC 드라이버는 클래스 형태로 존재하며 일반적으로 Jar파일로 제공된다.

mysql-connector-java-5.1.18-bin.jar 파일을 웹 어플리케이션 디렉터리의 WEB-INF\lib 디렉터리에 복사해주면 된다.

이 장의 경우 chap12\WEB-INF\lib 디렉터리에 mysql-connector-java-5.1.18-bin.jar 파일을 복사한 뒤 예제를 실행하면 된다.

 

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

 

JDBC 프로그램의 일반적인 실행 순서

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

[리스트12.1 chap12\viewMemberList.jsp]

<< >>

 

4.4 DBMS와의 통신을 위한 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

ex)오라클 JDBC드라이버를 로딩할 때

<<

try {

  Class.forName(“oracle.jdbc.driver.OracleDriver”);

} catch(ClassNotFoundException ex) {

  //지정한 클래스가 존재하지 않을 경우 에러가 발생한다.

  //에러처리

}

>>

 

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

데이터베이스를 구분할 때 URL과 비슷한 형식을 취하는 JDBC URL사용.

JDBC URL 일반적인 형식

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

 

ex)MySQL JDBC드라이버가 사용하는 JDBC URL

jdbc:mysql://HOST[:PORT]/DBNAME[?param=value&param1=value2&…]

HOST : MySQL 서버의 호스트주소

DBNAME : 데이터베이스 이름

PORT : MySQL 서버가 사용하는 포트 번호

뒤에 몇가지 설정 정보 추가

ex) jdbc:mysql://localhost:3306/chap12

 

MySQL에서 한글데이터를 올바르게 하기 위해서 추가 파라미터를 이용해서 캐릭터 셋을 알맞게 지정해야함.

jdbc:mysql://localhost:3306/chap11?useUnicode=true&characterEncoding=euckr

 

오라클 JDBC 드라이버의 경우

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

오라클의 SID가 ORCL인 경우

jdbc:oracle:thin:@172.0.0.1:1521:ORCL

 

4.6 데이터베이스 커넥션

데이터베이스 프로그래밍을 하기 위해서는 먼저 데이터베이스와 연결된 커넥션을 구해야한다.

java.sql.Connection 클래스가 데이터베이스 커넥션을 나타내며, 커넥션은 java.sql.DriverManager 클래스가 제공하는 getConnection() 메서드를 사용해서 구할 수 있다.

DriverManager 클래스는 다음 두 개의 getConnection() 메서드를 제공한다.

  • DriverManager.getConnection(String jdbcURL)
  • DriverManager.getConnection(String jdbcURL, String user, String password)

DriverManager.getConnection() 메서드는 Connection 객체를 리턴한다. 이 Connection 객체를 사용해 필요한 작업을 할 수 있다.

Connection 객체를 생성하지 못하면 SQLException 예외를 발생시킨다. 따라서 아래와 같이 예외 처리를 해줘야 한다.

<<

Connection conn = null;

try {

    conn = DriverManager.getConnection(…);

    …

    …

} catch(SQLException ex) {

   … //예외처리

}

>>

 

note. 자바의 예외처리 (try-catch-finally 블럭사용)

<<

try {

    // 예외가 발생할 수 있는 코드의 실행

    …

    …

} catch(예외1 ex) {

   … //예외1에 대한 처리

} catch(예외2 ex) {

   … //예외2에 대한 처리

} finally {

   … //예외 발생 여부에 상관없이 가장 마지막에 실행 (주로 사용한 시스템 자원을 반납하는 코드)

}

>>

 

Connection 객체를 다 사용한 뒤에는 close() 메서드를 호출하여 Connection 객체가 사용한 시스템 자원을 반납해 주어야 한다.

<<

Connection conn = null;

try {

   String jdbcDriver = “jdbc:mysql://localhost:3306/chap11?” +

                           “useUnicode=true&characterEncoding=euc-kr”;

    Stirng dbUser = “jspexam”;

    String dbPass = “jspex”;

    conn = DriverManager.getConnection(jdbdcDriver, dbUser, dbPass);

    …

} catch(SQLException ex) {

    //에러 발생

}  finally {

    if (conn != null) try { conn.close(); } catch(SQLException ex) {}

}

>>

 

4.7 Statememt를 사용한 쿼리 실행

Connection 객체를 생성한 후에는 Connection으로부터 Statement를 생성한 뒤에 쿼리를 실행.

Statement는 Connection.createStatement() 메서드를 사용하여 생성

<<

Statement stmt = conn.createStatement();

>>

 

Statement 클래스를 생성한 후 다음 두 메서드를 사용해서 쿼리를 실행할 수 있다.

  • ResultSet executeQuery(String query) : SELECT 쿼리를 실행. 결과값을 java.sql.ResultSet 객체에 저장해서 리턴.
  • int executeUpdate(String query) : INSERT, UPDATE, DELETE 쿼리를 실행. 그 결과로 변경된 (또는 삽입된) 레코드의 개수를 리턴.

 

Statement를 사용해서 값을 변경하는 예제

먼저 아이디와 새로운 이름을 입력 받는 폼을 출력해주는 페이지

[리스트12.2 chap12\update\updateForm.jsp]

test
 <%@ page contentType = "text/html; charset=euc-kr" %>
<html>
<head><title>이름 변경폼</title></head>
<body>

<form action="/chap12/update/update.jsp" method="post">
<table border="1">
<tr>
	<td>아이디</td>
	<td><input type="text" name="memberID" size="10"></td>
	<td>이름</td>
	<td><input type="text" name="name" size="10"></td>
</tr>
<tr>
	<td colspan="4"><input type="submit" value="변경"></td>
</tr>
</table>
</form>
</body>
</html>

파라미터로부터 회원 아이디와 암호를 입력받아 MEMBER 테이블의 PASSOWRD 칼럼 값을 변경.

[리스트12.3 chap12\update\update.jsp]

<%@ page contentType = "text/html; charset=euc-kr" %>

<%@ page import = "java.sql.DriverManager" %>
<%@ page import = "java.sql.Connection" %>
<%@ page import = "java.sql.Statement" %>
<%@ page import = "java.sql.SQLException" %>

<%
	request.setCharacterEncoding("euc-kr");
	
	String memberID = request.getParameter("memberID");
	String name = request.getParameter("name");
	
	int updateCount = 0;
	
	Class.forName("com.mysql.jdbc.Driver");
	
	Connection conn = null;
	Statement stmt = null;
	
	try {
		String jdbcDriver = "jdbc:mysql://localhost:3306/chap12?" +
							"useUnicode=true&characterEncoding=euckr";
		String dbUser = "jspexam";
		String dbPass = "jspex";
		
		String query = "update MEMBER set NAME = '"+name+"' "+
					   "where MEMBERID = '"+memberID+"'";
		
		conn = DriverManager.getConnection(jdbcDriver, dbUser, dbPass);
		stmt = conn.createStatement();
		updateCount = stmt.executeUpdate(query);
	} finally {
		if (stmt != null) try { stmt.close(); } catch(SQLException ex) {}
		if (conn != null) try { conn.close(); } catch(SQLException ex) {}
	}
%>
<html>
<head><title>이름 변경</title></head>
<body>
<%  if (updateCount > 0) { %>
<%= memberID %>의 이름을 <%= name %>(으)로 변경
<%  } else { %>
<%= memberID %> 아이디가 존재하지 않음
<%  } %>

</body>
</html>
  • 라인 11~12 : memberID, password 파라미터 저장
  • 라인 27~28 : Update 퀴리 생성
  • 라인 30 : 데이터베이스와 연결된 Connection생성
  • 라인 32 : Statement의 executeUpdate()메서드를 사용하여 쿼리 실행. 실행결과로 변경된 레코드의 개수가 updateCount 변수에 저장
  • 라인 41~45 : updateCount 가 0보다 크면 변경된 값이 존재한 것으로 간주
  • 라인 34 : Statement의 사용이 끝나면 close()메서드를 호출하여 사용한 자원 반납