반응형
* 강좌를 시작하기전에.....

JDBC를 이용하여 DB를 엑세스해서 프로그래밍을 하는 방법의 기초에 대해서 강의합니다.
따라서 이번 강좌는 JDBC를 처음 사용하고 하는 분들에게 적합한 강좌입니다.


* JDBC 프로그래밍의 5 단계

  1. DriverManager에 해당 DBMS Driver를 등록
  2. 해당 Driver로 부터 Connection 객체 획득
  3. Connection 객체로부터 Statement 객체 획득
  4. Statement의 method를 이용하여 SQL실행
  5. ResultSet 으로 받아서 처리(executeUpdate 의 경우엔 제외)
  6. 객체 close() (ResultSet, Statement, Connection)
그럼 각 단계에 대해서 자세히 알아 보도록 하겠습니다.


* 1. DriverManager에 해당 DBMS Driver를 등록

Driver를 DriverManager에 등록하는 방법은 3가지가 있습니다.
Class.forName() 메소드를 이용하는 방법, Driver객체를 생성하는 방법, registerDriver() 메소드를 이용하는 방법 이렇게 3가지의 방법이 있지만 가장 일반적으로 사용하고 쉬운 방법인 Class.forName() 메소드를 이용하는 방법에 대해서만 설명하도록 하겠습니다.

해당 JDBC 드라이버를 등록하려면 당연히 JDBC 드라이버가 필요합니다. 해당 데이터베이스의 드라이버 파일을 먼저 클래스 패스에 잡으시기 바랍니다. 오라클의 경우는 www.oracle.com 에서 다운로드 받을수도 있고 오라클 설치시 같이 설치 되므로 오라클 디렉토리를 잘 살펴 보기 바랍니다.

다음으로 mySQL의 경우는 http://sourceforge.net/project/showfiles.php?group_id=15923으로 가셔서 다운받으시기 바랍니다.

이제 JDBC 드라이버를 DriverManager에 등록하는 방법에 대해서 알아 보겠습니다.

Class.forName("org.gjt.mm.mysql.Driver"); -> mySQL 의 경우
Class.forName("oracle.jdbc.driver.OracleDriver"); -> Oracle thin 드라이버의 경우

Class 는 java.lang 패키지에 있는 클래스 입니다. 자세한 내용이 궁금하신 분은 api문서를 참고 하시구요... forName 메소드에 parameter로 쓰인 String은 당연히 DBMS의 종류에 따라 틀려지겠지요? 어째든 위의 메소를 실행시키고나면 자동으로 드라이버 객체가 생성이되고, 자신을 DriverManager에 등록하는 처리가 이루어지게 됩니다.


* 2. 해당 Driver로 부터 Connection 객체 획득

Connection이라는 것은 DBMS에 연결된 session을 의미 합니다. Connection 객체를 획득하는 방법은 DriverManager의 getConnection() 메소드를 이용하면 되는데 그 형식은 다음과 같습니다.

Connection con=DriverManager.getConnection(String jdbcURL,String id,String password);
			
getConnection 메소드는 몇가지로 오버로딩되어 있으니 궁금하신분은 API문서를 참고 하십시요..

다음과 같은 형식으로 사용합니다.


String url="jdbc:mysql://localhost/dbname";  // dbname에는 사용하는 database 이름 

Connection con=DriverManager(url,"root","1234");  // root 계정, 패스워드는 1234 


* 3. Connection 객체로 부터 Statement 객체 획득

하나의 Connection으로 부터 여러개의 Statement의 생성이 가능합니다. 이후에 Statement로 부터 SQL을 실행하게 됩니다. 아래의 그림을 보시면 이해가 되리라 생각됩니다.



Connection con=DriverManager.getConnection("jdbc:mysql://localhost/dbname","root","password");
  
Statement st1=con.createStatement();

ResultSet rs1=st1.executeQuery("select * form names");

Statement st2=con.createStatement();

ResultSet rs2=st2.executeQuery("select * form users");

Statement st3=con.createStatement(); 

ResultSet rs3=st3.executeQuery("select * form emails");
따라서 위와 같이 사용이 가능하죠. Statement에는 3가지 종류가 있는데 그중 첫번째가 지금 사용한 Statement 입니다. 두번째로 PreparedStatement 가 있고 마지막으로 CallableStatement가 있다. 그중 CallableStatement는 저장 프로시져 (stored procedure)를 호출하는데 사용되는 것인데, 여기에서는 초급강좌인 만큼 다루지 않습니다.
PreparedStatement는 다음과 같이 사용합니다.

Connection con=DriverManager.getConnection("jdbc:mysql://localhost/dbname","root","password");
  
PreparedStatement ps=con.prepareStatement("update juso set si=? where zip=?); // 밑줄친 부분 주의

ps.setString(1,"Seoul");  // 첫번재 ? 이 1번이 됩니다.

ps.setString(2,request.getParameter("zip")); // 두번째 " ? "

// setString 말고도, setDate, setArray, setCharacterStream등 여러가지가 있습니다.

ps.executeUpdate();
위와같은 쿼리문(값이 변하는)을 Statement로 처리한다면 PreparedStatement 문에 비해서 String 객체를 더 많이 생성해야 해야 하고, PreparedStatement사용시에는 DB에서의 처리시에도(특히 오라클에서) 쿼리문이 캐싱되어 보다 높은 퍼포먼스를 제공하게 됩니다.


* 4. Statement의 메소드를 이용해서 SQL문의 실행

Statement 클래스에서는 쿼리문의 실행을 위해서 몇가지 메소드를 제공하는데, executeQuery()와 executeUpdate() 두개의 메소드만 알면 충분히 활용이 가능합니다.

ResultSet rs=stmt.executeQuery("select * from users");
			
위와 같은 방식으로 사용되며 executeQuery()는 "select"문을 사용할때에만 사용되는 것이죠. 실행 결과는 ResultSet에 저장되며 저장된 정보의 처리 방법은 아래 에서 다루도록 하겠습니다.
또다른 메소드인 executeUpdate()는 select 외에 update,delete,insert 등의 쿼리문을 사용할때 이용되어 집니다. 다음과 같이 사용하시면 됩니다.
stmt.executeUpdate("insert into users(id,password) values('ab','bc')");
			


* 5. ResultSet으로 받아 서 처리하기

위에서 설명했다 시피 executeQuery()를 실행하면 ResultSet 타입의 객체를 반환합니다. 이 객체는 실행된 쿼리문의 결과 같을 가지고 있는데 ResultSet의 몇가지 메소드를 이용하면 ResultSet에 저장된 정보를 사용할수 있습니다. select쿼리를 실행 했으므로 하나이상의 row를 지니고 있는데.. 현재 row에서 다음 row로 넘기려면 rs.next() 와 같이 사용하면 됩니다.(첫번째 row도 next()를 사용해야 합니다.)

각 row가 선택이 되었으면 각컬럼의 데이터를 불러 오면 되는데, 두가지의 방법이 있습니다.
첫번째방법은

String name=rs.getString(1); (name에 해당하는 항목의 첫번재 컬럼에 있을경우)

이와같이 데이터의 컬럼 위치로 검색합니다. getString의 String 에는 Int,Double, 등과 같은 자료형을 사용하면 해당 자료형에 맞는 데이터를 리턴하여 줍니다. (getString(), getInt(), getDouble() 등등....)
또다른 방법은 컬럼의 이름을 직접 서술하는 방법인데, 다음과 같이 사용됩니다.

String name=rs.getString("name");

이러게 하면 rs ResultSet에 저장되 었던 name컬럼의 데이터가 name에 저장됩니다.


* 6. 객체 close() 하기 (ResultSet, Statement, Connection)

Java는 메모리 관리를 따로 하지 않아도 자체적으로 garbage collection 기능이 있어 사용되지 않는 객체는 자동적으로 처리된다. 그러나, Sun은 JDBC 드라이버와 같이 외부 지원되는 드라이버에 대해서는 생성된 객체를 코드 내에서 소멸시키도록 권장하고 있다. JDBC API는 이를 위해 close() 메쏘드를 제공하는데, close() 메쏘드를 사용해야 할 클래스는 Connection, Statement, PreparedStatement, ResultSet 등이다. 따라서, 데이터베이스에 접속하여 SQL 구문을 모두 수행했다면 다음처럼 close() 메쏘드를 사용하여 객체를 모두 소멸시키도록 한다. - webdox

rs.close();
st.close();
con.close();

위와 같이 사용하며, con (Connection) 과 st (Statement or PreparedStatement)는 반드시 close 되어야 합니다. 위에서 설명한 바와 같이 Statement 와 ResultSet 은 1:1 대응 이기 때문에 ResultSet 은 Statement 가 소멸되면 자동으로 소멸됩니다. (아예 처리를 하지 말라는 얘기는 아닙니다. -안전을 위해서)


* 그리고....

대부분의 Servlet/JSP 웹 애플리케이션 에서는 Connection 을 Pool 로서 관리를 하는데, 이는 매 요청시 마다 데이터베이스에 접속하고 해제하는 일을 수행하는데 있어 발생하는 부하를 줄여 주고, 일정 갯수 이상의 커넥션수를 넘지 않도록 유지시켜 주기 위해서 입니다.
이러한 Connection Pool 은 몇가지 공개된것도 있고 직접 제작할수도 있으나, 여기 에서는 생략하도록 하겠습니다.

<출처- http://www.aboutjsp.com/lec/jdbc.jsp >

+ Recent posts