본문 바로가기

언어공부/JDBC&오라클&SQL

JDBC - JDBC를 이용한 데이터베이스 사용 절차

JDBC -  JDBC를 이용한 데이터베이스 사용 절차에 대해서 알아보자.

JDBC를 이용한 데이터베이스 사용절차

전의 포스팅에서 JDBC를 이용한 데이터베이스 조작은 아래와 같다고 했다.

 

 

더 자세히 작성해 보자면 아래와 같다.

  1. URL로 지정된 JDBC 드라이버를 적재(load)한다.
  2. 사용자 이름과 패스워드를 가지고 데이터베이스에 연결한다.
  3. SQL문장을 작성하여 전송하고 실행한다. SQL 명령어의 결과로 생성되는 결과 집합을 얻는다.
  4. 결과 집합을 화면에 표시하거나 결과 집합을 처리한다. 사용이 끝나면 연결을 해제한다.

<드라이버 클래스 적재(=jdbc 드라이버 클래스 로드)>

 

첫 번째 단계는 드라이버 클래스를 등록해 프로그램 안으로 드라이버 클래스 파일을 적재해야 한다. Class클래스의 forName()이라는 메소드를 사용할 수 있으며, 설치한 JDBC드라이버를 등록하려면 다음과 같은 문장을 사용한다.

 

try{
	Class.forName("oracle.jdbc.OracleDriver");//각자 드라이버 클래스 파일 적재
}catch(ClassNotFoundException e){
	System.out.println("드라이버를 찾을 수 없습니다.");
}

 

forName() 메소드는 ClassNotFoundException을 발생할 수 있기 때문에 반드시 try/catch블록을 사용해야 한다.

 

 

위의 "oracle.jdbc.OracleDriver"에서 oracle.jdbc는 패키지 폴더명, oracledriver는 jdbc 드라이버 클래스 명을 뜻한다.

 

<데이터베이스와 연결>

 

드라이버를 적재했으면 드라이버를 통하여 데이터베이스 시스템과 연결할 수 있다. 연결하기 위해서는 DriverManager클래스의 정적 메소드인 getConnection()을 호출한다. 이 메소드는 데이터베이스 연결을 확립하게 되고 매개변수(데이터베이스 URL, 사용자 아이디, 패스워드)를 요구한다.

 

String url="jdbc:oracle:thin:@127.0.0.1:1521:xe";
//오라클 접속 주소, 1521 오라클 접속 포트 번호, xe는 데이터 베이스 명
String user="root";//오라클 사용자명
String password="password";//사용자 비번
Connection con=null;//데이터 베이스 연결 con

try {
	Class.forName("oracle.jdbc.OracleDriver");
    //jdbc 드라이버 클래스 로드
    System.out.println("드라이버 적재 성공");
	con=DriverManager.getConnection(url, user, password);
    //데이터베이스 연결 객체인 Connection 객체 생성
    System.out.println("데이터베이스 연결 성공");
    }catch(Exception e){e.printStackTrace();}

 

url매개변수는 "jdbc:subprotocol:subname"을 가진다. 위 코드에서는 subprotocol은 oracle이고, subname은 데이터베이스 이름인 xe이다. 만약 네트워크에 있는 데이터베이스 파일이라면 완전한 URL이 된다. 로컬 컴퓨터에 있는 데이터 베이스라면 "jdbc:oracle://localhost/xe"와 같이 된다.

 

사용자 아이디와 패스워드는 데이터베이스 서버에 등록되어 있어야 한다. 여기서 getConnection()메소드는 SQLException을 발생할 수 있기 때문에 try/catch블록을 사용해야 한다.

 

<SQL문장 실행>

 

데이터베이스로 연결한 후에는 SELECT와 같은 SQL문장들을 실행할 수 있다. 이때 사용되는 것이 Connection, Statement, ResultSet 인터페이스이다.

 

  • Connection 인터페이스 : 자바와 데이터베이스 사이의 연결을 담당한다.
  • Statement 인터페이스 : SQL문장을 실행한다.
  • ResultSet 인터페이스 : SQL문장의 실행결과를 가지고 있다. (SELECT문에서만 사용, 수행 후 결과 레코드 행 저장)

예를 들어 SELECT문장을 실행시키려면 다음과 같은 문장을 사용해야 한다.

(만약, UPDATE, DELETE, INSERT문이면 executeUpdate()메소드를 사용하며, ResultSet인터페이스를 사용하지 않는다.)

 

Statement s = con.createStatement(); //문장 객체 생성
String sql = "SELECT * FROM books ORDER BY book_id;" //SQL 문장 생성
ResultSet rows = s.executeQuery(sql); //SQL 문장 실행

 

여기서 쿼리의 실행으로 생성되는 결과 집합은 rows라는 변수에 저장된다.

 

<결과 집합에서 이동>

 

결과 집합에서 레코드를 하나씩 접근하여 작업을 해야한다. executeQuery메소드에 의하여 반환된 ResultSet 객체에는 SELECT문장에 의하여 추출된 모든 레코드가 들어있다. 하지만 한 번에 하나의 레코드만 접근할 수 있기 때문에 아래와 같이 결과 집합에서 레코드를 하나씩 처리한다.

 

while(rows.next()){//next()는 다음 레코드 행이 존재하면 참.
	//현재 레코드를 처리한다.
}

 

<결과 집합 처리>

 

다음은 레코드에서 컬럼의 값을 추출한다. 해당 코드는 while문 안에 작성하며, 많은 메소드들이 있는데, 두가지의 카테고리로 나눌 수 있다. 하나는 컬럼을 이름으로 접근하고, 다른 하나는 컬럼을 번호로 접근한다. 만약 번호를 안다면 숫자로 접근하는 것이 더 효율적이다.

 

while(rows.next()) {//next()는 다음 레코드 행이 존재하면 참.
	System.out.println(rs.getInt("id")+"\t"+rs.getString("name"));//이름으로 접근
	//각 컬럼에 저장된 레코드값이 정수 숫자이면 getInt()메소드로 가져오고, 
    //문자열이나 날짜형은 getString()메소드로 가져온다.
}
//================================================================================
while(rows.next()) {//next()는 다음 레코드 행이 존재하면 참.
	System.out.println(rs.getInt(1)+"\t"+rs.getString(2));//번호로 접근
	//각 컬럼에 저장된 레코드값이 정수 숫자이면 getInt()메소드로 가져오고, 
    //문자열이나 날짜형은 getString()메소드로 가져온다.
}

 

자바에서는 인덱스 번호가 0부터 시작하지만 SQL에서는 1부터 시작한다.

 

<데이터베이스와 연결 끊기>

 

마지막으로 결과 집합 사용 후 연결을 해제해야 한다. 보통 try-catch-finally문에서 finally에 try-catch문으로 작성한다.

전체적으로 코드를 작성하면 아래와 같다.

 

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class BoardList02 {

	public static void main(String[] args) {
		String driver="oracle.jdbc.driver.OracleDriver";
        //oracle.jdbc.driver는 패키지명, OracleDriver는 jdbc 드라이버 클래스명
		String url="jdbc:oracle:thin:@127.0.0.1:1521:xe";
        //오라클 접속 주소, 1521 오라클 접속 포트 번호, xe는 데이터 베이스 명
		String user="root";//오라클 사용자명
		String password="password";//사용자 비번
		
		Connection con=null;
		Statement st=null;
		ResultSet rs=null;//select문 수행 후 결과 레코드 행을 저장할 rs
		String sql=null;
		
		try {
			Class.forName(driver);//jdbc 드라이버 클래스 로드 실행
			con=DriverManager.getConnection(url, user, password);//데이터 베이스 연결 con생성
			st=con.createStatement();
			sql="select * from find_board order by bno desc";//번호를 기준으로 내림차순 정렬
			rs=st.executeQuery(sql);
			
			System.out.println("no \t title \t name \t cont \t date");
			System.out.println("============================================");
			while(rs.next()) {//next()는 다음 레코드 행이 존재하면 참.
				System.out.println(rs.getInt("bno")+"\t"+rs.getString("btitle")+"\t"+rs.getString("bname")+"\t"+
						rs.getString("bcont")+"\t"+rs.getString("bdate"));//getNSString()메소드도 잘쓰임.
				//각 컬럼에 저장된 레코드값이 정수 숫자이면 getInt()메소드로 가져오고, 문자열이나 날짜형은 getString()메소드로 가져온다.
			}
		}catch(Exception e) {e.printStackTrace();}
		finally {
			try {
				if(rs !=null) rs.close();
				if(st !=null) st.close();
				if(con !=null) con.close();//생성 역순으로 close해줌
			}catch(Exception e) {e.printStackTrace();}
		}
	}
}