JDBC 란?
- Java에서 Database관련 작업을 담당하는 Package.
JDBC의 특징
- 별도의 install 과정이 불필요.
- DB와의 연결은 Strring 형태의 URL에 의해서 수행.
- String 형태로 표준 SQL문을 전달.
- JDBC는 Spec으로 제공되며, 실재 Code는 각 Database Vender에 의해 작성되고 제공된다.
* Sun은 오직 interface로서 모든 Database에 공통으로 사용될 수 있는 작업 형식을 지정할 뿐이다.
> Sun의 JDBC Spec
- Core API : java.sql package
Client side application 개발용 라이브러리
=>DriverManager
=>Driver
=>Connection, Statement, ResultSet
=>DatabaseMetaData, ResultSetMetaData
- Extension API : javax.sql package(JDBC 2.0에 추가된 Package)
Server side application 개발용 라이브러리
=>DataSource
=>RowSet
* Oracle은 classes111.zip과 classes12.zip 두가지 package를 제공하고 있으며 각각 Version에 서로 달리 사용된다.
일반적으로 JDBC1.0만을 사용할 때는 classes111.zip을 사용하고 JDBC2.0과 함께 사용할 때는 classes12.zip을 사용한다.
(ORA_HOME/jdbc/lib)
- MetaData(Result 타입의 확인,Stored Procedure의 제거)의 사용 가능
JDBC의 장점
- JDBC를 이용하는 경우 interface기반으로 구축되기 때문에 어느 Database를 사용하더라도 동일한 코드를 작성할 수 있고 사용 중
Database를 교체하더라도 Code를 수정 작업은 거의 존재하지 않는다.
JDBC의 구분
* Version 구분
- JDBC는 현재 1.x와 2.0 Version으로 구분된다. 1.x version은 기본 기능만을 포함하고 있으며 가장 대표적인 특징은 Query의 결과
를 순차적으로 한번만 사용할 수 있고 Database와 단절된 상태로만 사용한다는 점이다. 이에 비해 2.0의 경우에는 Query의 결과를
Random Access방식으로 사용할 수 있고 직접 Database와 연결된 상태로 사용하므로 결과를 수정하므로서 Server의 Data에
대한 Delete, Update, Insert작업을 직접 수행할 수 있다.
* Version별 장 단점.
- 1.x의 장점 : Database와 연결을 지속적으로 유지할 필요가 없으므로 매우 가볍게 사용할 수 있고,
많은 Data를 처리하더라도 순차적으로 접근 후 1번만 사용하므로 Memory에 계속 Load할 필요가 없어,
작은 Memory 만으로도 작업을 수행할 수 있다.( : 2.0의 단점)
- 2.0의 장점 : Random Access가 가능하므로 Query결과를 자유롭게 사용할 수 있고,
Update, Insert, Delete작업을 직접 수행할 수 있으므로 관리가 편리하다.
* 장 단점을 고려한 사용 방법
만일 많은 Data를 읽기 전용으로 사용할 경우에는 1.x이 훨씬 유용한 방법으로 채택될 수 있다.
만일 소수의 Data를 빈번하게 읽고 갱신할 필요가 있다면 2.0이 훨씬 유용한 방법으로 채택될 수 있다.
* JDBC Driver의 종류 : 4가지 Type으로 구분한다.
- Type I : JDBC-ODBC Bridge driver
JDBC로 Database에 직접 연결하지 않고 ODBC를 통해서 작업하는 방법.
장점 : Windows환경을 재사용할 수 있다.
단점 : Windows상에서 ODBC를 설정해 주어야 한다. 속도가 가장 느리다.
- Type II : Native API party-Java driver (OCI)
JDBC명령을 각각의 Database client program에 적합하게 변환하는 방법.
장점 : 속도가 가장 빠르다.
단점 : Database Client를 설치해야 한다.
- Type III : JDBC-Net pure Java driver
Database에 종속되지 않은 Protocol로 JDBC를 번역 후 직접 연결 처리.
- Type IV : Native-protocol pure Java driver(THIN)
DB업체에서 지원하는 JDBC Driver로 JDBC문장을 개별 Protocol로 변환.
장점 : Client에 대한 어떠한 추가작업도 필요하지 않다.
단점 : OCI보다 속도가 느리다.
- 주로 작업은 OCI와 THIN을 이용.
* JDBC 작업을 위한 준비.
- Oracle을 설치하고 classes12.zip 파일을 자신의 Computer에 복사 후 CLASSPATH에 등록한다.
* JDBC의 기본 작업 절차.
- Database에 연결.
- Query전송.
- 결과를 이용한 작업 처리.
- 닫기.
* Database에 연결 작업 처리.
- Database에 연결하기 위해서는 다시 아래와 같은 과정이 필요.
- Driver 등록 : Database에 연결.
> Driver등록 : Driver등록은 자신이 사용할 Database Vender의 Driver를 java.sql package에 연결시키는 작업 과정이다.
> 이 과정에서 자신이 사용할 Type을 1차 지정하게 된다.
> Type I(JDBC-ODBC Bridge방식)
- Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
> Oracle제품 사용의 경우.
- 방법 I : Class.forName("oracle.jdbc.driver.OracleDriver");
classes12.zip에는 Oracle JDBC작업을 수행하기 위한 각종 class들이 포함되어 있고 그 중 한가지가
oracle.jdbc.driver.OracleDriver이다.
Driver가 하는 역할은 java.sql package의 interface들과 oracle이 제공하는 class들을 연결시키는 작업을 수행한다.
이 작업은 아래와 같이 다양한 표현식으로 사용 가능한다.
- 방법 II : Class.forName("oracle.jdbc.driver.OracleDriver").newInstance()
- 방법 III :
.... oraDrv = new oracle.jdbc.driver.OracleDriver()
DriverManager.registerDriver(oraDrv);
> DB연결 작업
- 앞서 등록 과정에서는 DriverManager에 자신이 사용할 DB package를 연결시켰으므로 이 과정에서 DriverManager를 통해
연결 작업을 수행하게 된다.
- 연결 작업을 수행할 때 Oracle의 경우에는 2차 Type결정 과정을 포함한다.
- 연결 객체는 java.sql.Connection으로 제공.
> 다양한 연결 방법.
- JDBC-ODBC Bridge를 사용할 경우.(미리 ODBC Data Source는 존재.)
=>Connection con = DriverManager.getConnection("jdbc:odbc:DSName","user","pw")
- THIN/OCI 방식을 사용하는 경우.
=>Connection con = DriverManager.getConnection("url","user","pw")
- url의 구성.
=>mainprotocol:subprotocol:type:연결정보
=>main protocol : jdbc(고정)
=>sub protocol : oracle (Oracle 고정)
=>type : oci8(oracle 8.x), oci7(oracle 7.x), thin
=>연결정보 : oci - tns, thin - host:port:sid
- 연결예.
=>Connection con = DriverManager.getConnection("jdbc:oracle:oci8:@COLEE","scott","tiger");
=>Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:tt","scott","tiger");
* Query 전송 작업 : Statement 생성 -> Query 전송.
- Statement 생성 작업 : 적용할 JDBC Version도 함께 설정. - 기본은 1.x
> Statement의 종류.
- default : Statement - 일반적인 Query를 직접 전송하기 위해 사용하는 Statement.
- PreparedStatement - Parameter를 통해 미리 지정된 위치에 값을 나중에 등록하는 Statement
- CallableStatement - Function, Procedure, Package를 호출하기 위해 사용하는 Statement.
- Statement생성하기.
=>Statement stmt = con.createStatement(); => 1.x 생성
=>Statement stmt = con.createStatement(int , int); => 2.0생성.
>> params : 순차적혹은 Scroll가능형태, 읽기전용혹은 쓰기 가능.
>> 상수는 ResultSet interface에 정의되어 있음.
--------------------------------------------------------------------------------------------------
| 상 수 | 의 미 |
--------------------------------------------------------------------------------------------------
| CONCUR_READ_ONLY | 읽기 전용 작업 처리 : 1.x |
--------------------------------------------------------------------------------------------------
| CONCUR_UPDATABLE | Query결과로 Update지원 : 2.0 |
--------------------------------------------------------------------------------------------------
| TYPE_FORWARD_ONLY | 순차적 접근 : 1.x |
--------------------------------------------------------------------------------------------------
| TYPE_SCROLL_INSENSITIVE | Random Access : DB변경 적용X |
--------------------------------------------------------------------------------------------------
| TYPE_SCROLL_SENSITIVE | Random Access : DB변경 적용O |
--------------------------------------------------------------------------------------------------
>> 1.x : CONCUR_READ_ONLY + TYPE_FORWARD_ONLY
- Prepared Statement 생성.
=>PreparedStatement stmt = con.prepareStatement(String sql);
=>PreparedStatement stmt = con.prepareStatement(String qry, int, int);
=>prepared statment는 미리 자신이 사용할 Query를 등록하는 방법을 사용한다.
params로 사용되는 두개의 int는 Statement와 동일하다.
- Callable Statement
=>CallableStatement stmt = con.prepareCall(String qry);
=>CallableStatement stmt = con.prepareCall(String qry, int, int);
=>callable statement는 prepared statment와 동일한 방법 사용.
- PreparedStatement&CallableStatement qry작성방법.
=>qry작성시 사용자 입력 항목은 ? 로 처리 : Data Type 구분하지 않음.
=>값 설정시에는 index로 지정하며 1부터 시작.(모든 JDBC는 1부터시작)
=>Data Type에 따라 각각의 Statement에서는 setXXX(int , value)지원.
=>예) PreparedStatement stmt = con.prepareCall("Select * From ?");
stmt.setString(1,"tabs");
- NULL 표현을 위해서는 setNull(index, type) : Type은 java.sql.Type의 상수
- CallableStatement는 "{ call PROC(?,?)}" 로 query문 지정.
=>parameter설정은 PreparedStatement와 동일.
=>function의 return 및 parameter의 registerOutParameter(index, paramType) method로 미리 등록.
=>execute후 결과 확인은 getXXX(index)로 각각 등록한 OutParameter를 읽어 들일 수 있다.
- Query수행하기.
=>executeUpdate, executeQuery, execute로 수행. - 세가지 모두 적용.
=>executeUpdate : Insert, Delete, Update, Drop, Create, Alter문 처리.
갱신 Row수 return.
=>executeQuery : Select만 처리.
=>execute : Type명확하지 않을 경우 처리. return이 true이면 ResultSet, false이면 update수.
-> stmt.getUpdateCound(), stmt.getResultSet()
* 결과 처리하기
- Select 문의 경우에는 ResultSet으로 결과를 구해서 활용할 수 있다.
- ResultSet을 활용하는 방법은 1.x을 기반으로 2.0에 추가적인 기능이 더해진다.
- 1.x 활용 방법.
> 기본 구조는 순차적인 형태로서 Enumeration과 비슷한다.
> ResultSet rs = stmt.executeQuery();
while(rs.next())
{
String name = rs.getString(1);
int age = rs.getInt(2);
Timestamp birth = rs.getTimestamp(3);
}
> 순차적인 검색만 가능하므로 한번 next되어 넘어간 record를 다시 사용할 수 없다.
> 날짜는 Date Type을 사용하고 시간은 Timestamp를 사용한다.
> 사용하는 Data Type은 java.sql package에 정의되어 있다.
> Data의 value가 NULL일 경우에는 직접 확인할 수 없고 field를 읽어 들인 후 rs.wasNull() method를 호출하므로서 알 수 있다.
- 2.0 활용 방법 : 검색.
> boolean beforeFirst() : 첫 레코드 이전의 시작위치로 이동.
> boolean afterLast() : 마지막 레코드 다음의 끝위치로 이동.
> boolean first() : 첫 레코드로 이동.
> boolean last() : 마지막 레코드로 이동.
> boolean isBeforeFirst, isAfterLast, isFirst, isLast : 현재위치가 지정된 위치인가 확인.
> boolean absolute(int row) : 지정된 레코드로 이동.
> boolean next() : 다음 레코드로 이동.
> boolean previous() : 이전 레코드로 이동.
> boolean relative(int) : 현재위치로부터 상대적인 레코드 위치로 이동.
- 2.0 활용 방법 : 데이타 갱신.
> Delete : void deleteRow()
> Update : update할 Row로 이동 후
rs.updateString("NAME","COLEE");
rs.updateRow(); or rs.cancelRowUpdates();
> Insert : 아무 위치에서나.
rs.moveToInsertRow();
rs.updateString(1,"COLEE");
rs.updateInt(2,5);
rs.insertRow();
rs.moveToCurrentRow();
* 닫기 작업.
- 작업이 종료되면 반드시 ResultSet -> Statement -> Connection순서로 close()를 호출해 주어야 한다.
* 각종 부가 정보 활용하기.
> 부가 정보는 MetaData라는 이름으로 제공된다.
> DatabaseMetaData interface : Database에 관련된 정보를 제공
- Connection으로부터 getMetaData()를 호출해서 구할 수 있다.
- Connection에 사용된 각종 정보 제공.
- Schema 리스트 제공.
- 지정 Schema로부터 접근 가능한 Table, View등 제공.
> ResultSetMetaData interface : ResultSet에 관련된 정보 제공.
- ResultSet으로부터 getMetaData()를 호출해서 구할 수 있다.
- ResultSet의 Column수 Column Name 및 Data Type 정보
- 소속 Schema Name.
- 현재 ResultSet의 상태 : 갱신 가능 여부등.
* Transaction관리.
- Transaction은 Connection으로 관리한다.
- 기본은 Auto Commit형으로 close하면 자동으로 수행한 결과를 Commit한다.
- 만일 Default인 Auto Commit을 사용하지 않고 직접 Transaction을 관리하고자 할 경우에는 Connection객체로부터
setAutoCommit(false)를 호출하고 적절한 위치에서 commit(), rollback()을 호출해 준다.
- Connection con = null;
Statement con = null;
try {
con = getConnection();
con.setAutoCommit(false);
stmt = con.createStatement();
stmt.executeUpdate("delete from test where no = '1'");
stmt.executeUpdate("delete from test where no = '2'");
con.commit();
con.setAutoCommit(true);
} catch(SQLException e) {
con.rollback();
System.out.println(e.getMessage());
} fanalliy {
if (stmt != null) stmt.close();
if (con != null) con.close();
}
* 기타.
- 대부분의 Database관련 작업은 SQLException을 처리해 주어야 한다.
- 이상의 내용은 JDBC Spec에 따른 사항이고 Oracle은 고유의 기능들(Simple Connection Pool등)을 함께 제공한다.
- 직접 JDBC를 이용하는 방법이외에도 보다 친숙한 형태로 사용하도록 하는 SQLJ를 이용하는 방법도 존재한다.
'DB > JDBC' 카테고리의 다른 글
MetaData (0) | 2007.04.04 |
---|---|
PreparedStatement (0) | 2007.04.04 |
JDBC 기초 (0) | 2007.04.03 |