기록공간

JDBC 프로그래밍 절차 및 구현 본문

DataBase/JDBC

JDBC 프로그래밍 절차 및 구현

입코딩 2020. 10. 31. 16:11
반응형

1. 드라이버 로딩 : Class.forName()

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

 

2. 커넥션 할당받기 : DriverManager.getConnection()

 

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

   - conn.createStatement() 또는 conn.prepareStatement()

 

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

 

   ○ DML(Insert, Update, Delete) 문인 경우 (데이터 변동이 생기는 상황)

       : int udpateCount = stmt.executeUpdate(sql);

         -> 입력한 매개변수 sql에 영향받은 레코드 수(적용된 행의 개수) updateCount 반환

         -> ※ JDBC를 통해 DML을 수행하는 경우에는 자동으로 COMMIT 된다.

 

   ○ Select 문인 경우 (데이터 변동이 없는 상황)

       : ResultSet rs = stmt.executeQuery(sql);

        -> 결과 집합의 형태로 ResultSet 반환

 

ex) 사원 정보를 담는 테이블에 1980-04-17 이후에 고용 사원의 사원번호와 이름을 검색

     SELECT EMPNO, ENAME
     FROM EMP
     WHERE HIREDATE >= TO_DATE('1980-04-17', 'YYYY-MM-DD');

     JDBC를 통해 받은 ResultSet의 결과 => 7495 홍길동 8749 김순자 ... 9000 강부자

 

5. (Select 구문의 경우)

   ResultSet의 논리적 커서 이동을 통해 각 컬럼의 데이터를 바인딩해 온다.

 

   boolean b = rs.next();

   -> 커서 이동.

       커서가 위치한 지점에 레코드가 존재하면 true 반환, 없으면 false 반환.

       커서는 가장 선두 첫 번째 레코드 직전에 위치하고 있다가 [next()] 메소드가 호출되면 진행한다.

 

ex)
                        커서위치        next 호출후 커서위치
                          ▼                   ▽
ResultSet => 7495 홍길동 8749 김순자 ... 9000 강부자

 

6. 사용을 마친 리소스 반납

    rs.close();                   -> ResultSet을 사용했을 경우

    stmt.close();                -> Statement를 사용했을 경우

 

    dbConn.close();

    (null 체크를 통해 close() 해 주는 것을 권장한다

    , finally 블럭에서 구현하는 것을 권장한다.)

 

싱글톤 패턴을 이용한 JDBC 클래스 구현 

JDBC 기능을 쓸 때마다 매번 드라이버를 초기화해줄 필요 없이(매번 초기화할 경우 그에 따른 오버헤드 비용이 크다) 최초 한 번만 초기화하고 그 기능을 계속해서 사용할 수 있도록 싱글톤 패턴을 활용하여 클래스를 구현한다. 이 드라이버 클래스 한 개의 객체로만 존재할 수 있으며 기능을 사용하는 경우 자동으로 초기화된다.

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

// ※ 싱글톤(singleton) 디자인 패턴을 이용한 Database 연결 객체 생성 전용 클래스
//    --> DB 연결 과정이 가장 부하가 크기 때문에
//        연결이 필요할 때 마다 객체를 생성하는 것이 아니라
//        한 번 연결된 객체를 계속 사용할 수 있도록 처리

package com.util;

// 커넥션 패키지
import java.sql.Connection;
import java.sql.DriverManager;

public class DBConn 
{
	// 변수 선언
	private static Connection dbConn;
	//-- 자동으로 초기화 지원 -> null
	
	// 메소드 정의
	public static Connection getConnection() // throws ClassNotFoundException, SQLException
	{
		// 한 번 연결된 객체를 계속 사용...
		// 즉, 연결되지 않은 경우에만 연결을 시도하겠다는 의미
		// -> singleton(디자인 패턴)
		if (dbConn == null)
		{
			try
			{
				String url = "jdbc:oracle:thin:@211.238.142.165:1521:xe";
				//String url = "jdbc:oracle:thin:@localhost:1521:xe";
				// [211.238.142.150] 는 오라클 서버의 IP 주소를 기재하는 부분
				// [1521] 은 오라클 port number
				// [xe]는 오라클 sid(express edition 은 xe)
				
				String user = "scott";  //-- 오라클 사용자 계정 이름
				String pwd = "tiger";   //-- 오라클 사용자 계정 암호
				
				
				Class.forName("oracle.jdbc.driver.OracleDriver");
				//-- OracleDriver 클래스에 대한 객체 생성
				//   드라이버 로딩 -> JVM에 전달
				// forName은 예외가 throw 되기 때문에 try catch나 throw해줘야 한다.
				// ClassNotFoundException
				
				
				dbConn = DriverManager.getConnection(url, user, pwd);
				//-- 오라클 서버 실제 연결
				//   위 (line 32 ~ 41)는... 연결을 위한 환경을 설정하는 과정
				//   갖고 있는 인자값(매개변수)은 오라클 주소, 계정명, 패스워드
				//   SQLException
				
			} catch(Exception e) // (ClassNotFoundException, SQLException)
			{
				System.out.println(e.toString());
				//-- 오라클 서버 연결 실패 시... 오류 메세지 출력 부분
			}
		}
		
		return dbConn;
	
	}//end getConnection()
	
	// getConnection() 메소드의 오버로딩 -> 연결
    // 사용자가 url 계정 비번 입력하면 그쪽으로 연결해줄게~
	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()
	
	// 메소드 정의 -> 연결 종료 메소드
	public static void close()
	{
		// dbConn 변수(멤버 변수)는 
		// Database 가 연결된 상태일 경우 Connection 을 갖는다.
		// 연결되지 않은 상태라면 null 인 상태가 된다.
		if(dbConn != null)
		{
			try
			{
				// 연결 객체의 isClosed() 메소드를 통해 연결상태 확인
				//-- 연결이 닫혀있는 경우 true 반환
				//   연결이 닫히지 않은 경우 false 반환
				// 닫혀 있는 상황이 맞는게 아니라면 -> 열려있다면
				if(!dbConn.isClosed())
				{
					dbConn.close();
					//-- 연결 객체의 cloase() 메소드 호출을 통해 연결 종료
				}
				
			} catch(Exception e)
			{
				System.out.println(e.toString());
			}
		}
		
		// 핵심 
		// dbConn을 null로
		dbConn = null;
		
	}//end close()
	
}
/*=============================
	Test001.java
	- Database 연결 테스트
=============================*/


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();
	}
}

 

JDBC 클래스 사용 예제

이제 위에서 살펴봤던 JDBC 클래스를 사용하는 예를 코드를 통해 간단하게 살펴보려고 한다. 우선 예제를 위한 테이블을 DBMS에 만들도록 한다.

 

-- 예제 테이블 생성
CREATE TABLE 
TBL_JDBC_TEST
( SID   NUMBER
, NAME  VARCHAR2(10)
, TEL   VARCHAR2(20)

);
--==>> Table TBL_JDBC_TEST이(가) 생성되었습니다.

-- SID에 기본키 제약조건 추가
ALTER TABLE TBL_JDBC_TEST
ADD CONSTRAINT JDBC_TEST_SID_PK PRIMARY KEY(SID);
--==>> Table TBL_JDBC_TEST이(가) 변경되었습니다.

식별 번호(기본키), 이름, 그리고 전화번호를 담고 있는 간단한 테이블을 만들었다. 이제 Java 코드를 통해 이 테이블에 데이터를 추가, 수정, 삭제 그리고 검색을 해보도록 하자. 그 전에 우선 기능별로 SQL문을 작성하고 가자.

 

-- 데이터 추가
INSERT INTO TBL_JDBC_TEST(SID, NAME, TEL) VALUES(1, '이름', '전화번호')
;

-- 데이터 수정
UPDATE TBL_JDBC_TEST SET SID = 1, NAME = '수정이름', TEL = '수정전화번호'  WHERE SID = 1
;

-- 데이터 삭제
DELETE FROM TBL_JDBC_TEST WHERE SID = 1
;

-- 데이터 검색
SELECT SID, NAME, TEL FROM TBL_JDBC_TEST
;

SQL문을 이렇게 한줄로 구성하는 이유는 Java 코드 내에 SQL문을 복사하기 더 유용하기 때문이다. 또한 Java 코드에서의 SQL문을 사용할 때에는 세미콜론(;)을 붙이지 않으므로 세미콜론은 개행을 통해 밑으로 내려줘야 나중에 복사하기 더 편해진다. 

 

이제 각 기능별로 JDBC 코드를 작성해보고 결과를 확인해 보도록 하겠다.

 

데이터 추가

 

코드

package com.test;

import java.sql.Connection;
import java.sql.Statement;

import com.util.DBConn;

public class Test
{
	public static void main(String[] args)
	{
		try
		{
			Connection conn = DBConn.getConnection();
		
			if(conn != null)
				System.out.println("DB 연결 성공!");
			
			int result = 0;
			
			// 쿼리문 전송을 위한 Statement 생성
			Statement stmt = conn.createStatement();
			
			// 데이터 추가 쿼리문
			String sql = "INSERT INTO TBL_JDBC_TEST(SID, NAME, TEL)"
					  + " VALUES(1, '이름', '전화번호')";
			
			result = stmt.executeUpdate(sql);
			
			if(result > 0) 
				System.out.println("데이터 추가 성공!");
			else
				System.out.println("데이터 추가 실패!");
			
			stmt.close();
			DBConn.close();
			System.out.println("DB 연결 종료");
			
		} catch(Exception e)
		{
			System.out.println(e.toString());
		}
	}
}

 

실행결과

 

실행 후 테이블 확인

 

데이터 수정

 

코드

package com.test;

import java.sql.Connection;
import java.sql.Statement;

import com.util.DBConn;

public class Test
{
	public static void main(String[] args)
	{
		try
		{
			Connection conn = DBConn.getConnection();
		
			if(conn != null)
				System.out.println("DB 연결 성공!");
			
			int result = 0;
			
			// 쿼리문 전송을 위한 Statement 생성
			Statement stmt = conn.createStatement();
			
			// 데이터 수정 쿼리문
			String sql = "UPDATE TBL_JDBC_TEST"
					+ " SET NAME = '김승범', TEL = '수정전화번호'"
					+ " WHERE SID = 1";
			
			result = stmt.executeUpdate(sql);
			
			if(result > 0) 
				System.out.println("데이터 수정 성공!");
			else
				System.out.println("데이터 수정 실패!");
			
			stmt.close();
			DBConn.close();
			System.out.println("DB 연결 종료");
			
		} catch(Exception e)
		{
			System.out.println(e.toString());
		}
	}
}

 

실행 결과

 

실행 후 테이블 확인

 

데이터 삭제

 

코드

package com.test;

import java.sql.Connection;
import java.sql.Statement;

import com.util.DBConn;

public class Test
{
	public static void main(String[] args)
	{
		try
		{
			Connection conn = DBConn.getConnection();
		
			if(conn != null)
				System.out.println("DB 연결 성공!");
			
			int result = 0;
			
			// 쿼리문 전송을 위한 Statement 생성
			Statement stmt = conn.createStatement();
			
			// 데이터 삭제 쿼리문
			String sql = "DELETE FROM TBL_JDBC_TEST"
					  + " WHERE SID = 1";
			
			result = stmt.executeUpdate(sql);
			
			if(result > 0) 
				System.out.println("데이터 삭제 성공!");
			else
				System.out.println("데이터 삭제 실패!");
			
			stmt.close();
			DBConn.close();
			System.out.println("DB 연결 종료");
			
		} catch(Exception e)
		{
			System.out.println(e.toString());
		}
	}
}

 

실행 결과

 

 

실행 후 테이블 확인

 

데이터 조회

 

현재 아무런 데이터가 존재하지 않으므로 미리 데이터를 넣어 놓는다.

 

INSERT INTO TBL_JDBC_TEST(SID, NAME, TEL)
VALUES(1, '김승범', '010-1111-2222');

INSERT INTO TBL_JDBC_TEST(SID, NAME, TEL)
VALUES(2, '안혜리', '010-2222-3333');

INSERT INTO TBL_JDBC_TEST(SID, NAME, TEL)
VALUES(3, '이진주', '010-4444-5555');

INSERT INTO TBL_JDBC_TEST(SID, NAME, TEL)
VALUES(4, '김종호', '010-6666-5555');

INSERT INTO TBL_JDBC_TEST(SID, NAME, TEL)
VALUES(5, '이예슬', '010-2222-3333');

COMMIT;

 

코드

package com.test;

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

import com.util.DBConn;

public class Test
{
	public static void main(String[] args)
	{
		try
		{
			Connection conn = DBConn.getConnection();
		
			if(conn != null)
				System.out.println("DB 연결 성공!");
			
			// 쿼리문 전송을 위한 Statement 생성
			Statement stmt = conn.createStatement();
			
			// 데이터 추가 쿼리문
			String sql = "SELECT SID, NAME, TEL"
					  + " FROM TBL_JDBC_TEST";
			
			ResultSet rs = stmt.executeQuery(sql);
			
			System.out.println("번호     이름    전화번호");
			
			while(rs.next())
			{
				System.out.printf("%d	%s	%s\n"
									, rs.getInt("SID")
									, rs.getString("NAME")
									, rs.getString("TEL"));
			}
			
			rs.close();
			stmt.close();
			
			DBConn.close();
			System.out.println("DB 연결 종료");
			
		} catch(Exception e)
		{
			System.out.println(e.toString());
		}
	}
}

 

실행 결과

 

반응형

'DataBase > JDBC' 카테고리의 다른 글

CallableStatement  (0) 2020.11.08
PreparedStatement  (0) 2020.11.08
DAO, DTO 그리고 Process  (0) 2020.11.07
JDBC 개념정리  (0) 2020.10.31
Comments