본문 바로가기

WEB_Programming

JDBC를 이용한 사용자 정의 SQL Object를 저장하고, 탐색하는 방법


How-to persist and retrieve user defined SQL objects using JDBC

이 과정을 수행하고 나면 다음과 같은 작업을 할 수 있다.
  • JDBC를 통해서 접속하고, 사용자 정의 SQL을 이용하는 매커니즘을 알수 있다.
  • java.sql.STRUCT 클래스를 이해하는것과 오라클 익스텐션과 상호작용하여 Oracle 객체를 운용하는 방법을 알수 있다.

소개

object type은 사용자 정의 복합 데이터타입으로 데이터 구조를 캡슐화한 것이다. 그리고 이것은 데이터조작을 필요로 하는 functions과 procedures들과 함께 동작한다. 
The data is referred to as attributes and the set of operations specified on the data are called the methods of the object type.


수행되는 샘플을 미리 보고 싶은경우

필요한경우 다음 예제를 다운로드 받으면 된다.

  • Oracle9i Database. This can be downloaded from here.
  • Oracle9i JDBC Driver. This can be downloaded from here.
  • JDK 1.3 or above. This can be downloaded from here.

설명

데이터베이스로 부터 객체 타입을 이용하여 저장이나 조회를 수행하는 2가지 방법이 있다.

  1. 표준 이용, 일반적인 JDBC 타입의 맵을 오라클 오브젝트에 매핑하는 방법 - 이 문서에서 데이터베이스로 부터 객체를 저장하거나 호출하는 것에대해서 논의할 것이다.
  2. Java 클래스를 생성하고, 커스텀 매핑을 수행하는 경우 - Oracle JPublisher 유틸리티는 커스텀 자바 클래스를 생성하고 사용하도록 해준다.

이해를 위해서 employee 객체에 대해서 이야기 해보자. employee 는 서로다른 형태의 속성 (이름, 제목, 부서번호)를 가지고 있다. 이 Object는 다음과 같다.

CREATE OR REPLACE TYPE EMP_TYPE AS OBJECT (
  NAME      VARCHAR2(50),
  TITLE     VARCHAR2(30),
  DEPT_NUM  NUMBER(2)
);
/

이제 다음과 같이 Object Type을 컬럼으로 갖는 테이블을 select하고 insert 하는 DML오퍼레이션이 수행되는 것을 확인할 수 있다. 테이블 생성은 다음과 같다.

CREATE TABLE EMP_TABLE (
  INFO EMP_TYPE
);
/


emp_tab 테이블로 부터 조회하기

emp_type객체로 부터 선택된 값을 selecting 하기위한 간단한 코드가 있다. 단순하게 하기위해서 커넥션은 이미 걸려 있다고 가정한다. 이제 emp_table에서 단순한 쿼리를 수행해볼 것이다. 5번라인에서 보는것과 같이 우리는 java.sql.Struct 인스턴스를 이용하여 결과 셋을 패치해 올 수 있다. Struct 인스턴스는 emp_type의 값을 조회해 온다.

  1. ......
  2. Statement stmt = connection.createStatement();
  3. ResultSet rs= stmt.executeQuery("SELECT * FROM emp_table");
  4. if(rs.next()) {
  5.   java.sql.Struct empType = (java.sql.Struct)rs.getObject(1);
  6.   System.out.println("Number of attributes "+ empType.getAttributes().length);
  7.   System.out.println("Name is " + empType.getAttributes()[0]);
  8.   System.out.println("Designation is " + empType.getAttributes()[1]);
  9.   System.out.println("Department is " + empType.getAttributes()[2]);
  10. }
  11. stmt.close();
  12. ......

Note: 동일한 기능을 수행하도록 Oracle 익스텐션 메소드를 이용할수도 있다. 아래와 같이 :


oracle.sql.STRUCT oracleSTRUCT=((OracleResultSet)rs).getSTRUCT(1);
oracle.sql.Datum[] attrs = oracleSTRUCT.getOracleAttributes();

System.out.println("Number of attributes.." + attrs.length);
System.out.println("Name is " + attrs[0].stringValue());
System.out.println("Designation is " + attrs[1].stringValue());

System.out.println("Department is " + attrs[2].intValue());

 

상상단에 보이는것과 같이 STRUCT객체로 값을 반환하는 방법은 OracleResultSet 객체에서 캐스팅을 수행하고 Oracle extensiond인 getSTRUCT() 메소드를 이용하여 획득한다. STRUCT혹은 oracle.sql.type 인스턴스 Struct를 이요하여 조회 하기 위해서 getOracleAttributes()메소드를 이용하여야 한다.

oracle.sql.STRUCT 크래스는 java.sql.Struct 인터페이스를 구현한 것이고, JDBC2.0 표준에 제시된 사항을 지원해준다. STRUCT 클래스는 다음과 같은 추가적인 메소드를 제공하고 있다.
  • getOracleAttributes(): oracle.sql.*은 값들 혹은 값들의 배열을 조회하도록 한다.
  • getDescriptor(): SQL타입을 위한 StructDescriptor 객체는 STRUCT 객체와 매핑된다.
  • getJavaSQLConnection(): java.sql.Connection로 현재 연결된 인스턴스 정보를 반환한다.
  • toJdbc(): Consults the default type map of the connection, to determine what class to map to, and then uses toClass().
  • toJdbc(map): Consults the specified type map to determine what class to map to, and then uses toClass().

emp_table 테이블에 값 저장하기

emp_table에 STRUCT객체를 이용하여 저장하는 내용을 보여준다. 커넥션은 이미 정의되어 있다고 가정한다.
  1. .....
  2. PreparedStatement stmt = connection.prepareStatement("INSERT INTO emp_table VALUES(?)");
  3. StructDescriptor structdesc = StructDescriptor.createDescriptor("EMP_TYPE", connection);
  4. Object[] attributes = {"Sujatha Ranganathan","Developer","20"};
  5. STRUCT empType= new STRUCT(structdesc, connection, attributes);
  6. stmt.setObject(1, empType);
  7. stmt.execute();
  8. stmt.close();
  9. .....

상단에서와 같이 STRUCT  객체를 생성하기 위해서는 StructDescriptor이 필요하다. StructDescriptor은 SQL타입을 Oracle Object 타입으로 변경해 주는 작업을 한다(line 2 참조).  다음단계는 emp_type객체에 대응할수 있는 속성의 값을 포함하도록 설정하는 것이다. 마지막으로 STRUCT객체는  StructDescriptor을 이용하고, prepared statement와 바인드 되어 동작하게 된다.

샘플 실행하기

here 에서 수행가능한 완전한 샘플을 획득한다. 이 섹션에서는 다음 명령어를 이용하여 애플리케이션을 수행할 수 있다.

Step 1 ObjectTypes.jar을 WinZip을 이용하여 압축을 풀기위해 다음 명령어를 수행한다.

> jar xvf ObjectTypes.jar

This creates a directory ObjectTypes.

Step 2 이 애플리케이션은 샘플 수행을 위한 샘플테이블이 필요하다. 테이블을 생성하고, 객체 타입을 생성하기 위해서 SQL*Plus에서 다음명령을 수행한다. scott/tiger 로 접속해서 ObjectTypes.sql을 수행한다.

sql>@ObjectTypes.sql

Step 3 Edit the file ObjectTypes.java. In the method dbConnection(), change the following line to your database connection parameters
connection = DriverManager.getConnection("jdbc:oracle:thin:@<hostname>:<port>:<SID>", "scott","tiger");

Step 4 Oracle9i JDBC 드라이버 파일을 환경변수에 CLASSPATH 에 설정한다. classes12.zip 혹은 classes12.jar 혹은 ojdbc14.jar 파일중 하나를 연결한다. 또한 PATH 환경변수를 JDK 디렉토리 bin에 걸어준다.

Step 5 자바 컴파일 수행

Example:
D:\ObjectTypes\>javac ObjectTypes.java

Step 6 실행하기

Example:
D:\ObjectTypes\>java ObjectTypes.java