JDBC 프로그래밍 절차

2020. 11. 7. 23:02

JDBC프로그래밍 절차

JDBC 프로그래밍을 하기 위한 절차는 크게 여섯개의 과정으로 나뉜다.

 

① 드라이버 로딩 :

 

Class.forName() - Oracle Driver 를 Java 에서 사용하기 위해 드라이버를 JVM 에 로딩하는 과정

 

② 커넥션 할당받기 :

 

DriverManager.getConnection()

 

③ 쿼리문 전송을 위한 Statement 또는 PreparedStatement 할당받기 :

 

conn.createStatement() 또는 conn.preparedStatement() 또는 conn.prepareCall()

 

④ Statement 또는 PreparedStatement 를 통한 쿼리문 전송

  

 ○ DML(insert, update, delete) 문인 경우
      : int updateCount = stmt.executeUpdate(sql);
        → 영향받은 레코드 수(적용된 행의 갯수) 반환
   
 ○ select 문인 경우 
      : ResultSet rs = stmt.executeQuery(sql);
        → 결과 집합의 형태로 ResultSet 반환

 

⑤ (select 구문의 경우) ResultSet 의 논리적 커서 이동을 통해 각 컬럼의 데이터를 바인딩 해 온다.

 

   boolean b = rs.next();
   → 커서 이동.
      커서가 위치한 지점에 레코드가 존재하면 true 반환, 없으면 false 반환.
      커서는 가장 선두 첫 번째 레코드 직전에 위치하고 있다가 『next()』 메소드가 호출되면 진행한다.

 

⑥ 사용을 마친 리소스 반납

  
rs.close();            → ResultSet 를 사용했을 경우
st.mtclose();         → Statement 를 사용했을 경우
dbConn.close();
(null 체크하여 close() 해 주는 것을 권장. finally 블럭에서 구현하는 것을 권장.)


이제 이 절차들을 소스코드로 세세히 살펴보자.

 

우선 데이터베이스와 자바의 연결을 위해 연결 객체 생성 전용 클래스인 DBConn을 만든다.

DB 연결 과정이 가장 부하가 크기 때문에 연결이 필요할 때 마다 객체를 생성하는 것이 아닌

한 번 연결된 객체를 계속 사용할 수 있도록 싱글톤이라는 디자인 패턴을 이용한다.

 

/*==================
    DBConn.java 
===================*/

package com.util;

import java.sql.Connection;
import java.sql.DriverManager;

public class DBConn
{
	// 변수 선언
	private static Connection dbConn;
	//-- 자동으로 초기화 지원 → null
	
	// 메소드 정의
	public static Connection getConnection()
	{
		// 한 번 연결된 객체를 계속 사용...
		// 즉, 연결되지 않은 경우에만 연결을 시도하겠다는 의미
		// → singleton(디자인 패턴)
		if(dbConn == null)
		{
			try
			{
				String url = "jdbc:oracle:thin:@xxx.xxx.xxx.xxx:1521:xe";
				// 『xxx.xxx.xxx.xxx』는 오라클 서버의 IP 주소를 기재하는 부분
				// 『1521』은 오라클 port number
				// 『xe』는 오라클 sid(express edition 은 xe)	
				
				String user = "scott";	//-- 오라클 사용자 계정 이름
				String pwd = "tiger";	//-- 오라클 사용자 계정 암호
				
				Class.forName("oracle.jdbc.driver.OracleDriver");
				//-- OracleDriver 클래스에 대한 객체 생성
				//   드라이버 로딩 → JVM에 전달
				
				dbConn = DriverManager.getConnection(url, user,pwd);
				//-- 오라클 서버 실제 연결
				//   위 (line 32 ~ 41)는... 연결을 위한 환경을 설정하는 과정
				//   갖고 있는 인자값(매개변수)은 오라클 주소, 계정명, 패스워드
				
			} catch(Exception e) //(ClassNotFoundException, SQLException)
			{
				System.out.println(e.toString());
				//-- 오라클 서버 연결 실패 시... 오류 메세지 출력하는 부분
			}
			
			// 구성된 연결 객체 반환
			return dbConn;	
			
		}
		return dbConn;
		
	}//end getConnection()
	
	// getConnection() 메소드의 오버로딩 → 
	public static Connection getConnection(String url, String user, String pwd)
	{
		if(dbConn == null)
		{
			try 
			{
				Class.forName("oracle.jdbc.driver.OracleDriver");
				dbConn = DriverManager.getConnection(url, user, pwd);
			} catch (Exception e)
			{
				System.out.println(e.toString());
			}
		}
		
		// 구성된 연결 객체 반환
		return dbConn;
		
	}//end getConnection(url, user, pwd)
	
	// 메소드 정의 → 연결 종료 메소드
	public static void close()
	{
		// dbConn 변수(멤버 변수)는
		// Database 가 연결된 상태일 경우 Connection 을 갖는다.
		// 연결되지 않은 상태라면 null 인 상태가 된다.
		if(dbConn != null)
		{
			try
			{
				// 연결 객체의 isClosed() 메소드를 통해 연결상태 확인
				//-- 연결이 닫혀있는 경우 true 반환
				//   연결이 닫히지 않은 경우 false 반환
				if(!dbConn.isClosed())
				{
					dbConn.close();
					//-- 연결 객체의 close() 메소드 호출을 통해 연결 종료
				}
				
			} catch(Exception e)
			{
				System.out.println(e.toString());
			}
		}
		
		// 연결 객체 초기화
		dbConn = null;
	
	}//end close()
		
}

 

이제 이 클래스를 이용해 객체를 생성해 데이터베이스에 연결을 시도해보자.

/*====================
   DBConn연결 테스트
======================*/
package com.test;

import java.sql.Connection;

import com.util.DBConn;

public class Test001
{
	public static void main(String[] args)
	{
		Connection conn = DBConn.getConnection();
		
		if (conn != null)
		{
			System.out.println("데이터베이스 연결 성공~!!!");
		}
		
		DBConn.close();
	}
}

 

실행 결과


이제 여섯가지 단계중 두가지 단계인 드라이버 로딩 및 커넥션 할당받기를 완료하였다.

다음 단계인 쿼리문 전송을 위한 처리를 실습하기 앞서 Statement()에 대해 알아보자.

 

쿼리문을 처리하기 위한 과정을 크게 세가지로 바라본다면,

 

① 작업 객체를 만든다.

   여기서 말하는 작업객체란 Statement 객체이다.

   Connection클래스의 createStatement()메소드로 Statement 객체로 

   반환 받을 수 있다.

 

② 쿼리문을 작성한다.

    문자열 변수를 실행하고자 할 쿼리문으로 초기화 한다.

    ※주의 

     1. 쿼리문 끝에 『;』을 붙이지 않는다.

     2. 자바에서 실행한 DML 구문은 내부적으로 자동 COMMIT 된다.

     3. 오라클에서 트랜잭션 처리가 끝나지 않으면 데이터 액션 처리가 이루어 지지 않는다.

        (즉, 오라클에서 직접 쿼리문을 테스트할 경우 COMMIT 또는 ROLLBACK 을 반드시 수행할 수 있도록 한다.)

    

③ 작업객체를 활용하여 쿼리문을 실행한다.

    생성된 작업객체를 활용하여 쿼리를 실행할 때에는 두가지 경우가 있다.

    

     1. DML구문(INSERT, DELETE, UPDATE) 을 실행하는 경우

        Statement 객체의 executeUpdate(sql) 메소드를 사용한다.

        파라미터의 쿼리를 수행한 후 적용된 행의 갯수를 반환한다.

        ※ 주의

        데이터 입력 쿼리는 한 번 실행하면 다시 실행하지 못한다. 즉, 다시 실행하면 에러 발생한다.
        (기본키 제약조건이 설정되어 있으므로... )

 

     2. SELECT문을 실행하는 경우

        Statement 객체의 executeQuery(sql) 메소드를 사용한다.

        파라미터의 쿼리를 수행한 후 결과값을 ResultSet으로 반환한다.

        반환된 ResultSet을 커서를 이용하여 데이터를 확인할 수 있다.

 

 

DML구문 실행 예

package com.test;

import java.sql.Connection;
import java.sql.Statement;
import java.util.Scanner;

import com.util.DBConn;

public class Test003
{
	public static void main(String[] args)
	{
		Scanner sc = new Scanner(System.in);
		Connection conn = DBConn.getConnection();
		
		do 
		{
			System.out.println("번호를 입력하세요(-1 종료) : ");
			String sid = sc.next();
			
			// 반복문의 조건을 무너뜨리는 코드 구성
			if (sid.contentEquals("-1"))
				break;
			
			System.out.println("이름을 입력하세요 : ");
			String name = sc.next();
			
			System.out.println("전화번호를 입력하세요 : ");
			String tel = sc.next();
			
			if (conn != null)	// 연결이 이루어진 상황이라면...
			{
				System.out.println(">> 데이터베이스 연결 성공~!!!");
				
				try
				{
					// 작업 객체 생성
					Statement stmt = conn.createStatement();
					
					// 쿼리문 준비
					String sql = String.format("INSERT INTO TBL_MEMBER(SID, NAME, TEL)"
											+ " VALUES(%s, '%s', '%s')"
							, sid, name, tel);
					
					// 쿼리문 수행
					// - 특정 내용을 데이터베이스에 적용해야 하는 경우
					//   → 『executeUpdate()』 메소드 사용
					int result = stmt.executeUpdate(sql);
					
					if (result > 0)
						System.out.println("회원 정보가 입력되었습니다.");
					
					stmt.close();
					
				} catch (Exception e)
				{
					System.out.println(e.toString());					
				}
			}
			
		} while( true);
		
		sc.close();
		DBConn.close();
		
		System.out.println("데이터베이스 연결 닫힘~!!!");
		System.out.println("프로그램 종료됨~!!!");
		
	}
}

실행 결과

 

이클립스 & SQL Developer 실행결과

SELECT문 실행 예

public class Test004
{
	public static void main(String[] args)
	{
		// 데이터베이스 연결 객체 생성
		Connection conn = DBConn.getConnection();
		
		if (conn != null)
		{
			System.out.println(">> 데이터베이스 연결 성공~!!!");
			
			try
			{
				// 작업 객체 생성
				Statement stmt = conn.createStatement();
				
				// 쿼리문 준비
				String sql = "SELECT SID, NAME, TEL FROM TBL_MEMBER ORDER BY 1";
				
				// 쿼리문 수행 → 결과집합 수신
				ResultSet rs = stmt.executeQuery(sql);
				
				// executeQuery() 메소드를 사용하면
				// 질의 결과를 ResultSet 객체로 가져올 수 있다.
				// 하지만, ResultSet 객체가 질의에 대한 결과물 모두를
				// 한꺼번에 받아서 가지고 있는 구조가 아니다
				// 단지, 데이터베이스로부터 획득한 질의 결과물에 대한
				// 관리가 가능한 상태가 되는 것이다.
				// 이 때문에... ResultSet 을 수신했다고 해서
				// 데이터베이스와의 연결을 끊게 되면
				// ResultSet 객체는 더 이상 질의 결과를 관리할 수 없게 된다.
				
				// ResultSet 의 다음 값의 존재 여부 확인(반환) → true / false
				// 반복문을 활용한 ResultSet 컨트롤
				while(rs.next())
				{
					String sid = rs.getString("SID");			// String sid = rs.getString(1)
					String name = rs.getString("NAME");			// String name = rs.getString(2)
					String tel = rs.getString("TEL");			// String tel = rs.getString(3)
					
					String str = String.format("%3s %8s %12s", sid, name, tel);
					
					System.out.println(str);
					
				}
				
				rs.close();		// 결과집합 리소스 반납
				stmt.close();	// 작업객체 리소스 반납		
			
			
			} catch(Exception e)
			{
				System.out.println(e.toString());
			}
		} // end if
		
		DBConn.close();			// 연결객체 리소스 반납
		
		System.out.println("데이터베이스 연결 닫힘");
		System.out.println("프로그램 종료됨~!!!");
		
		
	}
}

 

실행 결과

이클립스 & SQL Developer 실행결과

'JDBC' 카테고리의 다른 글

DAO와 DTO를 이용한 JDBC 실습(2)  (0) 2020.11.09
DAO와 DTO를 이용한 JDBC 실습(1)  (0) 2020.11.08
DAO와 DTO란?  (0) 2020.11.08
JDBC 사전 설정  (0) 2020.11.07
JDBC란?  (0) 2020.11.07

+ Recent posts