Tibero JDBC 개발자안내서 Tibero 5 Copyright 2013 TIBERO Co., Ltd. All Rights Reserved.
Copyright Notice Copyright 2013 TIBERO Co., Ltd. All Rights Reserved. 대한민국경기도성남시분당구서현동 272-6 우 ) 463-824 Restricted Rights Legend All TIBERO Software (Tibero ) and documents are protected by copyright laws and the Protection Act of Computer Programs, and international convention. TIBERO software and documents are made available under the terms of the TIBERO License Agreement and may only be used or copied in accordance with the terms of this agreement. No part of this document may be transmitted, copied, deployed, or reproduced in any form or by any means, electronic, mechanical, or optical, without the prior written consent of TIBERO Co., Ltd. 이소프트웨어 (Tibero ) 사용설명서의내용과프로그램은저작권법, 컴퓨터프로그램보호법및국제조약에의해서보호받고있습니다. 사용설명서의내용과여기에설명된프로그램은 TIBERO Co., Ltd. 와의사용권계약하에서만사용이가능하며, 사용권계약을준수하는경우에만사용또는복제할수있습니다. 이사용설명서의전부또는일부분을 TIBERO의사전서면동의없이전자, 기계, 녹음등의수단을사용하여전송, 복제, 배포, 2차적저작물작성등의행위를하여서는안됩니다. Trademarks Tibero is a registered trademark of TIBERO Co., Ltd. Other products, titles or services may be registered trademarks of their respective companies. Tibero 는 TIBERO Co., Ltd. 의등록상표입니다. 기타모든제품들과회사이름은각각해당소유주의상표로서참조용으로만사용됩니다. Open Source Software Notice This product includes open source software developed and/or licensed by "OpenSSL," "RSA Data Security, Inc.," "Apache Foundation," "Jean-loup Gailly and Mark Adler," and "Paul Hsieh's hash". Information about the afore mentioned and the related open source software can be found in the "${INSTALL_PATH}/license/oss_licenses" directory. 본제품은 OpenSSL, RSA Data Security, Inc., Apache Foundation 및 Jean-loup Gailly와 Mark Adler 및 Paul Hsieh's hash 에의해개발또는라이선스된오픈소스소프트웨어를포함합니다. 관련상세정보는제품의디렉터리 ${INSTALL_PATH}/license/oss_licenses 에기재된사항을참고해주십시오. 안내서정보안내서제목 : Tibero JDBC 개발자안내서발행일 : 2013-02-25 소프트웨어버전 : Tibero 5 안내서버전 : 2.1.4
내용목차 안내서에대하여... vii 제1장 Tibero JDBC 소개... 1 1.1. JDBC... 1 1.2. tbjdbc... 1 1.2.1. 동작구조... 2 1.2.2. 기본경로... 2 1.2.3. 제약사항... 3 제2장 JDBC 표준지원... 5 2.1. JDBC 2.0... 5 2.1.1. 인터페이스메소드... 5 2.1.2. 주요기능... 6 2.2. JDBC 3.0... 7 2.2.1. 인터페이스메소드... 7 2.2.2. 주요기능... 8 2.3. JDBC 4.0... 9 2.3.1. 인터페이스메소드... 9 2.3.2. 주요기능... 10 제3장 tbjdbc의사용... 11 3.1. 개발과정... 11 3.2. 데이터타입... 13 3.3. tbjdbc Stream... 14 3.3.1. 컬럼에대한 Stream 생성... 15 3.4. 내장함수호출... 16 3.4.1. PSM의사용... 16 3.4.2. Java Stored Procedure의사용... 16 3.5. 예외처리... 17 제4장 DataSource 객체와데이터베이스 URL... 19 4.1. DataSource 객체... 19 4.1.1. DataSource 객체의속성... 19 4.1.2. DataSource 객체의추가속성... 20 4.2. DataSource 객체를이용한연결... 21 4.2.1. JNDI를사용하지않는방법... 21 4.2.2. JNDI를사용한방법... 22 4.3. 데이터베이스 URL과데이터베이스지시자... 22 제5장 분산트랜잭션... 25 5.1. 개요... 25 5.2. 구성요소... 25 5.3. 전역트랜잭션과지역트랜잭션간의변환... 26 5.4. Tibero XA 패키지... 27 Tibero iii
5.5. XA 인터페이스의구성요소... 27 5.5.1. XADataSource 인터페이스... 27 5.5.2. XAConnection 인터페이스... 28 5.5.3. XAResource 인터페이스... 28 5.5.4. XID 인터페이스... 28 5.5.5. XAResource 메소드... 29 5.6. 분산트랜잭션예제... 33 제6장 결과집합확장기능... 37 6.1. JDBC 2.0 표준... 37 6.1.1. Scrollability, Positioning, Sensitivity... 37 6.1.2. Updatability... 38 6.2. Scrollable, Updatable 결과집합생성... 38 6.2.1. Statement 객체생성... 38 6.2.2. 결과집합특성확인... 38 6.2.3. 제약사항... 39 6.3. Scrollable 결과집합탐색... 39 6.4. Updatable 결과집합탐색... 40 6.4.1. INSERT... 41 6.4.2. UPDATE... 41 6.4.3. DELETE... 42 제7장 Row Set... 43 7.1. 개요... 43 7.2. Row Set Listener... 43 7.3. Cached Row Set... 44 7.3.1. RowSet 객체생성... 44 7.3.2. 열데이터탐색... 45 7.3.3. 제약사항... 45 제8장 LOB 데이터처리... 47 8.1. 개요... 47 8.2. LOB 지시자... 47 8.2.1. LOB 지시자얻어오기... 47 8.2.2. LOB 지시자넘겨주기... 48 8.3. LOB 데이터읽고쓰기... 49 8.4. 임시 LOB... 50 8.5. API 목록... 52 8.5.1. 표준 API... 52 8.5.2. 확장 API... 52 제9장 Failover와로드밸런싱... 55 9.1. Failover... 55 9.1.1. Failover 기능활성화... 55 9.1.2. Failover 옵션설정... 55 iv Tibero JDBC 개발자안내서
9.2. 로드밸런싱... 57 제10장 SSL... 59 10.1. 개요... 59 10.2. SSL의사용... 59 10.2.1. Tibero 서버설정... 59 10.2.2. tbjdbc 설정... 59 제11장 사용자정의데이터타입... 61 11.1. 개요... 61 11.2. Array 타입... 61 11.2.1. Array 데이터타입선언... 61 11.2.2. Array 데이터타입 IN... 62 11.2.3. Array 데이터타입 OUT... 63 11.3. Struct 타입... 63 11.3.1. Struct 데이터타입선언... 63 11.3.2. Struct 데이터타입 IN... 64 11.3.3. Struct 데이터타입 OUT... 65 색인... 67 Tibero v
안내서에대하여 안내서의대상 본안내서는 Tibero ( 이하 Tibero ) 에서제공하는 JDBC 기능을이용하여프로그램을개발하려는애플리 케이션개발자를대상으로기술한다. 안내서의전제조건 본안내서를원활히이해하기위해서는다음과같은사항을미리알고있어야한다. 데이터베이스의이해 RDBMS 의이해 Java 프로그래밍의이해 안내서의제한조건 본안내서는 JDBC 애플리케이션프로그램을실무에적용하거나운용하는데필요한모든사항을포함하고있지않다. 따라서 JDBC를활용한운용과관리또는고급프로그래밍에대해서는각제품안내서를참고하기바란다. 안내서에대하여 vii
안내서구성 Tibero JDBC 개발자안내서는총 10개의장으로이루어져있다. 각장의주요내용은다음과같다. 제1장 : Tibero JDBC 소개 JDBC의기본개념과 Tibero에서제공하는 Tibero JDBC를소개한다. 제 2 장 : JDBC 표준지원 tbjdbc 가지원하는 JDBC 표준을기능별로기술한다. 제 3 장 : tbjdbc 의사용 tbjdbc 를사용하는기본적인방법을기술한다. 제 4 장 : DataSource 객체와데이터베이스 URL DataSource 객체를이용하여데이터베이스에연결하는방법과데이터베이스 URL 을기술한다. 제 5 장 : 분산트랜잭션 분산트랜잭션기능을기술한다. 제 6 장 : 결과집합확장기능 결과집합의확장기능을기술한다. 제 7 장 : Row Set Row Set 기능을기술한다. 제 8 장 : LOB 데이터처리 LOB 데이터를처리하는방법을기술한다. 제 9 장 : Failover 와로드밸런싱 Failover 와로드밸런싱기능을기술한다. 제 10 장 : SSL SSL 의기본개념과사용방법을기술한다. 제 11 장 : 사용자정의타입 사용자정의데이터타입을사용하는방법을기술한다. viii Tibero JDBC 개발자안내서
안내서규약 표기 <AaBbCc123> <Ctrl>+C [Button] 진하게 " "( 따옴표 ) ' 입력항목 ' 하이퍼링크 > +---- ---- 참고 의미프로그램소스코드의파일명, 디렉터리 Ctrl과 C를동시에누름 GUI의버튼또는메뉴이름강조다른관련안내서또는안내서내의다른장및절언급화면 UI에서입력항목에대한설명메일계정, 웹사이트메뉴의진행순서하위디렉터리또는파일있음하위디렉터리또는파일없음참고또는주의사항 [ 그림 1.1] [ 표 1.1] AaBbCc123 그림이름 표이름 명령어, 명령어수행후화면에출력된결과물, 예제코드 { } [ ] 필수인수값 옵션인수값 선택인수값 안내서에대하여 ix
시스템사용환경 요구사항 Platform HP-UX 11i (PA-RISC, ia64) Solaris (SPARC 9/Solaris 9) AIX (PPC 5L/AIX 5.3) GNU (X86, 64, IA64) Linux kernel 2.6 이상 Windows(x86) 32bit/64bit Hardware 최소 1.5GB 하드디스크공간 512MB 이상메모리공간 Compiler PSM (C99 지원필요 ) tbesql/c (C99 지원필요 ) x Tibero JDBC 개발자안내서
관련안내서 안내서 Tibero 설치안내서 Tibero tbcli 안내서 Tibero 애플리케이션개발자안내서 Tibero External Procedure 안내서 Tibero tbesql/c 안내서 Tibero tbesql/cobol 안내서 Tibero tbpsm 안내서 Tibero tbpsm 참조안내서 Tibero 관리자안내서 Tibero tbadmin 안내서 Tibero 유틸리티안내서 Tibero 설명설치시필요한시스템요구사항과설치및제거방법을기술한안내서이다. Call Level Interface인 tbcli의개념과구성요소, 프로그램구조를소개하고 tbcli 프로그램을작성하는데필요한데이터타입, 함수, 에러메시지를기술한안내서이다. 각종애플리케이션라이브러리를이용하여애플리케이션프로그램을개발하는방법을기술한안내서이다. External Procedure를소개하고이를생성하고사용하는방법을기술한안내서이다. C 프로그래밍언어를사용해데이터베이스작업을수행하는각종애플리케이션프로그램을작성하는방법을기술한안내서이다. COBOL 프로그래밍언어를사용해데이터베이스작업을수행하는각종애플리케이션프로그램을작성하는방법을기술한안내서이다. 저장프로시저모듈인 tbpsm의개념과문법, 구성요소를소개하고, tbpsm 프로그램을작성하는데필요한제어구조, 복합타입, 서브프로그램, 패키지와 SQL 문장을실행하고에러를처리하는방법을기술한안내서이다. 저장프로시저모듈인 tbpsm의패키지를소개하고, 이러한패키지에포함된각프로시저와함수의프로토타입, 파라미터, 예제등을기술한참조안내서이다. Tibero의동작과주요기능의원활한수행을보장하기위해 DBA가알아야할관리방법을논리적또는물리적측면에서설명하고, 관리를지원하는각종도구를기술한안내서이다. SQL/PSM 처리와 DBA를위한시스템관리기능을제공하는 GUI 기반의툴인 tbadmin을소개하고, 설치및사용방법을기술한안내서이다. 데이터베이스와관련된작업을수행하기위해필요한유틸리티의설치및환경설정, 사용방법을기술한안내서이다. Tibero를사용하는도중에발생할수있는각종에러의원인과해결방법을기술한안내서이다. 안내서에대하여 xi
안내서 설명 에러참조안내서 Tibero 참조안내서 Tibero SQL 참조안내서 Tibero의동작과사용에필요한초기화파라미터와데이터사전, 정적뷰, 동적뷰를기술한참조안내서이다. 데이터베이스작업을수행하거나애플리케이션프로그램을작성할때필요한 SQL 문장을기술한참조안내서이다. xii Tibero JDBC 개발자안내서
연락처 Korea TIBERO Co., Ltd. 272-6, Seohyeon-dong, Bundang-gu, Seongnam-si, Gyeonggi-do, 463-824 South Korea Tel: +82-31-779-7113 Fax: +82-31-779-7119 Email: info@tmax.co.kr Web (Korean): http://www.tibero.com 기술지원 : http://technet.tmax.co.kr USA TmaxSoft, Inc. 560 Sylvan Avenue Englewood Cliffs, NJ 07632 U.S.A Tel: +1-201-567-8266 Fax: +1-201-567-7339 Email: info@tmaxsoft.com Web (English): http://www.tmaxsoft.com Japan TmaxSoft Japan Co., Ltd. 5F Sanko Bldg, 3-12-16 Mita, Minato-Ku, Tokyo, 108-0073 Japan Tel: +81-3-5765-2550 Fax: +81-3-5765-2567 Email: info@tmaxsoft.co.jp Web (Japanese): http://www.tmaxsoft.co.jp 안내서에대하여 xiii
China TmaxSoft China Co., Ltd. Beijing Silver Tower, RM 1508, 2# North Rd Dong San Huan, Chaoyang District, Beijing, China, 100027 China Tel: +86-10-6410-6145~8 Fax: +86-10-6410-6144 Email: info.cn@tmaxsoft.com Web (Chinese): http://www.tmaxsoft.com.cn xiv Tibero JDBC 개발자안내서
제 1 장 Tibero JDBC 소개 본장에서는 JDBC 의기본개념과 Tibero 에서제공하는 Tibero JDBC( 이하 tbjdbc) 를소개한다. 1.1. JDBC JDBC(Java Database Connectivity) 는 Java로개발된프로그램안에서 SQL 문장을실행하기위해데이터베이스를연결해주는 API(Application Program Interface) 이다. JDBC를사용하면, 다음과같은이점이있다. 어떠한관계형데이터베이스에서도 SQL 문장을사용할수있다. DBMS 벤더별로데이터베이스에접근하는프로그램을따로만들필요가없다. 업무프로그램을 Java 로작성하면, 플랫폼별로다르게작성하지않아도된다. Java 로작성된애플리케이션은어디에서나동작할수있다. Java의기능을확장할수있다. 예를들어, 원격데이터베이스에서얻은정보를애플릿으로구성하거나하나이상의내부데이터베이스를연결하는데에도사용할수있다. 또한, 다른곳에저장된정보도 JDBC를이용하여쉽게접근할수있으며, 새로운애플리케이션을개발하는데걸리는시간도단축할수있다. 1.2. tbjdbc Tibero에서는다음장에서설명할 JDBC 표준을준수함은물론별도의 API를추가로제공하고있다. 이렇게구성된 API를 tbjdbc(tibero의 Java database connectivity) 라한다. tbjdbc는다음과같은특징이있다. 클래스와인터페이스메소드로이루어져있다. SQL 표준인 SQL-99 를지원한다. DBMS 종류와관계없이독립적으로프로그램을개발할수있다. tbjdbc 는 Java 패키지 (java.sql.*, javax.sql.*) 를상속한다. JDBC 의버전은 Java 표준스펙에따라달라진다. 제 1 장 Tibero JDBC 소개 1
JDBC 3.0 (J2SE 1.4) JDBC 4.0 (Java SE 6) 1.2.1. 동작구조 JDBC 표준을이용하여애플리케이션프로그램개발자는해당 JDBC 표준에맞는 Driver를만들어배포할수있다. JDBC는다음과같이네가지타입의 Driver를제공한다. 타입 JDBC-ODBC Bridge Driver Native-API Driver Net-Protocol Driver Native-Protocol Driver 설명 JDBC로데이터베이스에직접연결하지않고 ODBC를사용한다. JDBC 명령을 DBMS 고유의클라이언트프로그램에맞게변환한다. 데이터베이스에종속되지않은프로토콜 (WAS용) 로 JDBC를변환한후, WAS에서연결하여처리한다. DBMS 벤더에서지원하는 JDBC Driver로, JDBC 문장을 DBMS 고유의프로토콜로변환한다. tbjdbc는데이터베이스서버를설치하지않아도 100% Java로작성된애플리케이션프로그램을개발할수있는 JDBC Driver를제공한다. 위표에서설명한 Native-Protocol Driver( 또는 Thin Driver) 타입의 Driver 이다. tbjdbc는다음과같이동작한다. 1.2.2. 기본경로 Tibero 를서버에설치한후 tbjdbc 는 $TB_HOME/client/lib/jar 디렉터리에생성된다. 단, JDK 버전에따 라생성되는파일명이다르다. 2 Tibero JDBC 개발자안내서
JDK 버전 1.3 설명 - tibero5-jdbc-13.jar: tbjdbc 파일 - tibero5-jdbc-13-dbg.jar: tbjdbc 파일 1.4 - tibero5-jdbc-14.jar: tbjdbc 파일 - tibero5-jdbc-14-dbg.jar: 디버깅용 tbjdbc 파일 5 - tibero5-jdbc-5.jar: tbjdbc 파일 - tibero5-jdbc-5-dbg.jar: 디버깅용 tbjdbc 파일 6 이상 - tibero5-jdbc.jar: tbjdbc 파일 - tibero5-jdbc-dbg.jar: 디버깅용 tbjdbc 파일 1.2.3. 제약사항 tbjdbc 를사용할때, 다음과같은제약사항이있다. 데이터베이스서버를설치할때반드시자동으로생성되는 tbjdbc 를사용한다. 이전버전에대한호환성 (backward compatibility) 을제공하지않는다. JDK 1.3 이상이반드시설치되어있어야한다. 다음의위치에서 JDK 를다운로드할수있다. http://www.oracle.com/technetwork/java/javase/downloads/index.html 만약시스템이 Oracle 사의 JDK 를사용하지않는다면, 각각의시스템에적합한 JDK 를찾아설치한다. 예를들어 HP-UX 는 HP, AIX 는 IBM 에서 JDK 를다운로드받아설치한다. 시스템별로 JDK 를설치하는방법은다음위치에서확인할수있다. http://www.oracle.com/technetwork/java/javase/downloads/jdk-6u26-download-400750. html 제 1 장 Tibero JDBC 소개 3
제 2 장 JDBC 표준지원 tbjdbc 는 JDBC 4.0 을준수하고있다. 다만, 표준에따르면필수적으로구현해야하는부분과벤더별로 구현여부를선택가능한부분을구분하여명시하고있으며, 이러한추가기능에대해서는지원하지않을 수도있다. 본장에서는 tbjdbc 가지원하는 JDBC 표준을기능별로설명한다. 2.1. JDBC 2.0 2.1.1. 인터페이스메소드 tbjdbc 에서지원하는주요한인터페이스메소드는다음과같다. java.sql.array java.sql.blob java.sql.callablestatement java.sql.clob java.sql.connection java.sql.databasemetadata java.sql.driver java.sql.preparedstatement java.sql.resultset java.sql.resultsetmetadata java.sql.statement java.sql.struct 에서지원하지않는인터페이스메소드는다음과같다. 제 2 장 JDBC 표준지원 5
java.sql.ref java.sql.sqldata java.sql.sqlinput java.sql.sqloutput 2.1.2. 주요기능 다음은 JDBC 2.0 표준지원하는주요기능에대한설명이다. 결과집합 tbjdbc에서지원하는결과집합기능은다음과같다. Scrolling 기능 Scrolling 기능을지원하는스크롤가능한결과집합 (Scrollable ResultSet) 을생성할수있다. 이기능은결과집합을전방향또는후방향으로탐색할수있다. 또한, 결과집합내에서상대적이거나절대적인위치이동도할수있다. 결과집합타입 결과집합은다음과같이세가지타입으로지정할수있다. 타입 Forward-only Scroll-insensitive Scroll-sensitive 설명최초생성될때의데이터값으로고정되며, 오직정방향으로만탐색할수있다. Forward-only 결과집합과마찬가지로최초생성될때의데이터값으로고정되지만, 스크롤가능한결과집합의특성을가지므로정방향, 역방향, 상대위치, 절대위치등으로탐색할수있다. 데이터베이스변화에민감하며, 데이터가변경되는경우즉시결과집합에반영된다. 따라서새로운데이터를볼수있다. Concurrency 타입 결과집합에대해다음과같이두가지 Concurrency 타입을지정할수있다. 타입 Read-only Updatable 설명데이터를수정할수없다. 따라서여러트랜잭션때문에발생할수있는잠금 (Lock) 현상은없다. 데이터를수정할수있다. 단, 서로다른사용자가같은데이터에접근할경우, 잠금현상때문에동시수행을할수없다. 6 Tibero JDBC 개발자안내서
Batch update Batch update 기능은여러개의 DML 문장을한꺼번에처리할수있는기능이다. 또한, 개별로 INSERT 문을수행하거나준비된문장 (Prepared Statement) 을사용하여파라미터만바꿔가며수행할수도있다. 이때문에시스템성능향상에많은도움을준다. 데이터타입 tbjdbc는 BLOB(Binary Large OBject) 과 CLOB(Character Large OBject) 데이터타입을지원한다. 사용자는 BLOB과 CLOB 데이터타입의데이터를받아오기위해 getclob(), getblob() 메소드를사용할수있으며, 데이터를저장하기위해 setclob(), setblob() 메소드를추가로사용할수있다. 2.2. JDBC 3.0 2.2.1. 인터페이스메소드 tbjdbc 에서지원하는주요한인터페이스메소드는다음과같다. java.sql.parametermetadata java.sql.savepoints tbjdbc 에서지원하는 javax.sql 패키지의인터페이스메소드는다음과같다. javax.sql.connectioneventlistener javax.sql.connectionpooldatasource javax.sql.datasource javax.sql.pooledconnection javax.sql.rowset javax.sql.rowsetinternal javax.sql.rowsetlistener javax.sql.rowsetmetadata javax.sql.rowsetreader 제 2 장 JDBC 표준지원 7
javax.sql.rowsetwriter javax.sql.xaconnection javax.sql.xadatasource 2.2.2. 주요기능 지원기능 tbjdbc 는 JDBC 3.0 표준의일부를제외한모든기능을지원한다. 다음은 JDBC 3.0 표준지원하는주요기능에대한설명이다. 저장점 Savepoint 인터페이스를구현하여임의의트랜잭션에대한저장점설정과커밋및롤백기능을제공한다. 단, 특정한저장점을해제하는 Connection.releaseSavepoint java.sql 메소드는제공하지않는다. 문장풀링 (Pooling) 접속풀링과관련된문장의풀링을제공한다. 접속풀링 (Pooling) ConnectionPoolDataSource 인터페이스를통해서 PooledConnection 을얻어올수있다. 사용자는 DataSource 객체에의해 PooledConnection 이어떠한특성을갖고생성될지를결정할수있다. 파라미터메타데이터 ParameterMetaData 인터페이스를구현한 JDBC 클래스는준비된문장 (Prepared Statement) 에서사용한파라미터개수의정보를제공한다. 단데이터타입과속성 (Property) 에대한메타데이터 (metadata) 는제공하지않는다. 자동생성키 SQL 문장을실행한후결과집합으로부터 getgeneratedkeys 함수를사용하여결과로우에대한키 또는사동으로생성된컬럼의값을얻는다. 이름있는파라미터 CallableStatement 객체의파라미터를저장할때파라미터이름으로구별할수있는이름있는파라미 터 (named parameter) 기능을지원한다. 결과집합의유지성 8 Tibero JDBC 개발자안내서
결과집합이열려있는동안에커밋이발생했을때, 결과집합을그대로유지할지아니면닫을지를설정 한다. tbjdbc 에서는결과집합을유지하는방법만을지원한다. 복수개의결과집합반환 한 SQL 문장이여러개의결과집합을열수있도록지원한다. BLOB 와 CLOB 객체에존재하는데이터의수정 updatexxx API 를통해 BLOB 와 CLOB 객체에포함된데이터를수정하는기능을제공한다. 미지원기능 tbjdbc 에서지원하지않는기능은다음과같다. BOOLEAN, DATALINK, URL 데이터타입 REF 객체의수정 그룹변환및데이터타입의매핑 2.3. JDBC 4.0 2.3.1. 인터페이스메소드 tbjdbc 에서지원하는주요한인터페이스메소드는다음과같다. java.sql.nclob java.sql.rowid java.sql.sqlxml java.sql.wrapper tbjdbc 에서지원하는 javax.sql 패키지의인터페이스메소드는다음과같다. javax.sql.statementeventlistener 제 2 장 JDBC 표준지원 9
2.3.2. 주요기능지원기능 다음은 JDBC 4.0 표준지원하는주요기능에대한설명이다. XML 데이터타입 SQLXML 인터페이스를통해 SQL:2003에추가된 XML 데이터타입을사용할수있다. 자동드라이버검출 자동으로드라이버를로딩할수있게되어 Class.forName 를사용한 java.sql.driver 클래스의로드없 이도드라이버객체를사용할수있다. 국가별캐릭터세트지원 데이터베이스에서별도로지정해사용하는국가별캐릭터세트를지원하기위한 API 가추가되었다. 향상된 SQLException 연쇄적으로연결된예외를생성할수있게되어보다자세한원인을전달해줄수있으며, 새로운종류 의예외타입이추가되었다. 향상된 Blob/Clob 기능 Blob/Clob 객체를생성 / 해제할수있는 API 를지원한다. SQL ROWID 데이터타입의지원 RowId 인터페이스를이용하여 SQL ROWID 타입을사용할수있다. 실제 JDBC 객체에대한접근허용 Wrapper 인터페이스를이용하여애플리케이션서버나접속풀링환경에서도실제 JDBC 객체에접근 해사용할수있다. 접속풀링환경에서실제접속상태에대한통지 접속풀링환경에서실제접속이닫히거나유효하지않게되었을때, 그상태를풀링된문장에통지해 준다. 미지원기능 tbjdbc 에서지원하지않는기능은다음과같다. 사용자정의타입조회및계층구조검색 10 Tibero JDBC 개발자안내서
제 3 장 tbjdbc 의사용 본장에서는 tbjdbc 를사용하여애플리케이션프로그램을개발하는과정을순서대로설명하고, 추가로 데이터타입, Stream 등을설명한다. 3.1. 개발과정 다음은 tbjdbc를사용하여애플리케이션프로그램을개발하는과정이다. 1. 패키지임포트기본이되는 Java 패키지와 tbjdbc 패키지를임포트한다. /* 기본 Java 패키지 */ import java.sql.*; /* tbjdbc 패키지 */ import com.tmax.tibero.jdbc.*; import com.tmax.tibero.jdbc.ext.*; 2. 데이터베이스연결 데이터베이스에연결하기위해서 Connection 객체를생성한다. Connection 객체를생성하기위해서 tbjdbc 를로딩한후, DriverManager 를이용한다. Class.forName("com.tmax.tibero.jdbc.TbDriver"); Connection conn = DriverManager.getConnection("jdbc:tibero:thin:@localhost:8629", "tibero", "tmax"); 또는다음과같이 DataSource 객체를이용하여 Connection 객체를생성한다. 3. Statement 객체생성 데이터베이스에연결되면, Connection 객체를이용하여 Statement 객체를생성한다. Statement stmt = conn.createstatement(); PreparedStatement pstmt = conn.preparestatement("select empno, name FROM emp"); CallableStatement cstmt = conn.preparecall("begin... END;"); 4. 질의문수행과 ResultSet 객체받기 질의문을수행하고 ResultSet 객체를받는다. 제 3 장 tbjdbc 의사용 11
ResultSet rs = stmt.executequery("select * FROM ALL_OBJECTS;"); 5. ResultSet 객체처리 ResultSet 객체는 next() 메소드를이용하여모든로우에접근할수있다. 이때 getxxx() 메소드를호출하면원하는타입별로로우데이터를가져올수있다. 만약 next() 메소드가 false라면, 더는결과집합이존재하지않음을의미한다. while (rs.next()) { System.out.println(rs.getString(1)); System.out.println(rs.getInt(2)); } 6. 커밋또는롤백수행기본적으로 DML 문 (INSERT, UPDATE, DELETE) 을수행한다음에는자동으로커밋된다. 이러한기능을 auto-commit이라고한다. 사용자는 Connection 클래스에서제공하는다음의메소드를이용하여이기능을임의로해제할수있다. void setautocommit(boolean flag) 이메소드를이용하여 auto-commit 기능을비활성화하면, 사용자는반드시 DML 문을사용한다음커 밋이나롤백을수행해야한다. 그래야데이터베이스에적용된다. conn.commit(); conn.rollback(); 7. ResultSet 객체와 Statement 객체소멸 ResultSet 객체와 Statement 객체는반드시소멸시켜야한다. 왜냐하면, tbjdbc 내부에는별도의 final izer 메소드가없기때문이다. 이때문에예상치못한시점에심각한메모리누수현상이발생할수있고, 데이터베이스내부커서의최대허용범위를초과하여에러가발생할수도있다. rs.close(); stmt.close(); 8. 데이터베이스연결해제마지막으로모든작업이끝나면반드시데이터베이스연결을해제해야한다. 그렇지않으면현재세션이연결된상태로남아있기때문에다음연결시에는최대허용세션을초과할수있다. 따라서데이터베이스연결에실패할수도있다. conn.close(); 12 Tibero JDBC 개발자안내서
3.2. 데이터타입 tbjdbc 는 JDBC 타입을지원할뿐만아니라 Interval 타입을추가로제공한다. 다음은 JDBC 타입과 tbjdbc 타입과의대응관계를나타내는표이다. JDBC 타입 ( 표준 ) java.sql.types.char java.sql.types.varchar java.sql.types.longvarchar java.sql.types.numeric java.sql.types.decimal java.sql.types.bit java.sql.types.tinyint java.sql.types.smallint java.sql.types.integer java.sql.types.bigint java.sql.types.real java.sql.types.float java.sql.types.double java.sql.types.binary java.sql.types.varbinary java.sql.types.longvarbinary java.sql.types.date java.sql.types.time java.sql.types.timestamp java.sql.types.blob java.sql.types.clob java.sql.types.nclob java.sql.types.nchar java.sql.types.nvarchar java.sql.types.sqlxml com.tmax.tibero.jdbc.da ta.datatype.varray com.tmax.tibero.jdbc.da ta.datatype.cursor Java 타입 ( 표준 ) java.lang.string java.lang.string java.lang.string java.math.bigdecimal java.math.bigdecimal boolean byte short int long float double double byte[] byte[] byte[] java.sql.date java.sql.time java.sql.timestamp java.sql.blob java.sql.clob java.sql.nclob java.sql.nchar java.sql.nvarchar java.sql.sqlxml java.sql.array - tbjdbc 타입 java.lang.string java.lang.string java.lang.string java.math.bigdecimal java.math.bigdecimal boolean byte short int long float double double byte[] byte[] byte[] java.sql.date java.sql.time java.sql.timestamp com.tmax.tibero.jdbc.tbblob com.tmax.tibero.jdbc.tbclob com.tmax.tibero.jdbc.tbnclob java.lang.string java.lang.string com.tmax.tibero.jdbc.tbsqlxml com.tmax.tibero.jdbc.tbarray com.tmax.tibero.jdbc.tbresultset 제 3 장 tbjdbc 의사용 13
JDBC 타입 ( 표준 ) com.tmax.tibero.jdbc.da ta.datatype.itv_dts com.tmax.tibero.jdbc.da ta.datatype.itv_ytm com.tmax.tibero.jdbc.da ta.datatype.rowid com.tmax.tibero.jdbc.da ta.datatype.timestamp_tz com.tmax.tibero.jdbc.da ta.datatype.timestamp_ltz Java 타입 ( 표준 ) - - - java.sql.timestamp java.sql.timestamp tbjdbc 타입 com.tmax.tibero.jdbc.tbintervaldts com.tmax.tibero.jdbc.tbintervalytm com.tmax.tibero.jdbc.tbrowid com.tmax.tibero.jdbc.tbtimes tamptz java.sql.timestamp Tibero에서 TIME 데이터타입을지원하지만 DATE 데이터타입을사용하기를권장한다. TIME 컬럼에대해서 PreparedStatement.setTime() 메소드로지정할수없다. PreapredStatement.setTime() 은 DATE 데이터타입의컬럼에대해서지원하고있다. TIME 컬럼에대한값을지정하기위해서는문자열을 TIME 값으로변환하는 TO_TIME 함수를통해서입력할수있다. 3.3. tbjdbc Stream tbjdbc에서는특정데이터타입에대해다음과같은 Stream 기능을제공한다. 컬럼에대한 Stream 생성 - CHAR, VARCHAR, RAW, NCHAR, NVARCHAR - LONG, LONG RAW - LOB Stream 소멸 tbjdbc 에서는다음과같이 4 종류의 Stream 메소드를제공한다. 메소드 getasciistream getbinarystream getunicodestream getcharacterstream 반환값 Java.io.InputStream Java.io.InputStream Java.io.InputStream Java.io.Reader 설명 ASCII 형태로변환된데이터 Stream. byte 형태로변환된데이터 Stream. Unicode 형태로변환된데이터 Stream. 이메소드는 JDBC 4.0에서폐기 (deprecated) 되었으므로호환성을고려하여가급적사용하지않는것이좋다. 문자열형태로변환된데이터 Reader. 14 Tibero JDBC 개발자안내서
각각의메소드를이용하면해당데이터타입에서허용하는최대크기까지점진적으로데이터를읽을수 있다. 메소드에서반환되는객체는 InputStream 과 Reader 이고, read() 메소드를사용하면데이터를읽을 수있다. 3.3.1. 컬럼에대한 Stream 생성 CHAR, VARCHAR, RAW 컬럼에 Stream 메소드를사용하는경우전체데이터를한꺼번에받아와서 Stream 객체로생성한다. 반면, LONG이나 LONG RAW, LOB 컬럼에대해서는최초일부의데이터 (Chunk, 32KB) 만읽어온후 Stream 객체를생성한다. 읽어온크기를넘는데이터에대해서는서버로부터 Chunk 단위로다시읽어온다. 다음은 getbinarystream() 을이용하여데이터를읽어오는예이다. ResultSet rs = stmt.executequery("select name, image FROM backgrounds"); while (rs.next()) { InputStream imageis = rs.getbinarystream(2); try { FileOutputStream fos = new FileOutputStream(rs.getString(1)); int chunk = 0; while ((chunk = imageis.read())!= -1) fos.write(chunk); } catch (Exception e) { e.printstacktrace(); } finally { if (fos!= null) fos.close(); } } 다음은 getbinarystram() 대신 getbytes() 를이용하여데이터를읽어오는예이다. getbytes() 는해당컬럼 에저장된모든데이터를한꺼번에받아오기때문에그크기만큼메모리를차지한다는점을주의해야한 다. ResultSet rs = stmt.executequery("select name, image FROM backgrounds"); while (rs.next()) { bytes[] images = rs.getbytes(2); try { FileOutputStream fos = new FileOutputStream(rs.getString(1)); fos.write(images); } catch (Exception e) { 제 3 장 tbjdbc 의사용 15
} e.printstacktrace(); } finally { if (fos!= null) fos.close(); } 3.4. 내장함수호출 3.4.1. PSM 의사용 tbjdbc 에서는 PSM 을사용할수있다. 다음과같이 SQL-92 의 ESCAPE 문법과 PSM 문법을제공한다. // SQL92 ESCAPE 문법 CallableStatement cstmt = conn.preparecall("{call proc(?)}"); CallableStatement cstmt = conn.preparecall("{? = call func(?)}"); // PSM 문법 CallableStatement cstmt = conn.preparecall("begin proc(?); end;"); CallableStatement cstmt = conn.preparecall("begin? := func(?); end;"); 다음은 PSM 문법을사용하여내장함수를호출하는예이다. create or replace function concat(x varchar2, y varchar2) return varchar2 is begin return x y; end; CallableStatement cstmt = conn.preparecall("begin? := concat(?,?); end;"); cstmt.regiteroutparameter(1, Types.VARCHAR); cstmt.setstring(2, "Tmax"); cstmt.setstring(3, "Tibero"); cstmt.executeupdate(); String result = cs.getstring(1); 3.4.2. Java Stored Procedure 의사용 이전절에서설명한방법과같이 Java Stored Procedure 를사용할수있다. 16 Tibero JDBC 개발자안내서
참고 Java Stored Procedure 에대한자세한내용은 "Tibero External Procedure 안내서 " 를참고한다. 3.5. 예외처리 tbjdbc에서는예외상황을처리하기위해 java.sql.sqlexception 클래스객체를정의할수있다. 예외상황은 tbjdbc 내부에서발생할수도있고, 데이터베이스내부에서발생할수도있다. 예외상황의내용은에러코드와에러가발생한위치등의정보가포함되어있다. 예외상황에대한정보를얻기위해다음과같은메소드가제공된다. 메소드 getmessage() getsqlstate() geterrorcode() printstacktrace() 설명에러가발생한원인이다. SQL 상태정보이다. 에러코드이다. 에러가발생한스택의트레이스정보 (Stack trace) 이다. 다음은위의메소드를사용하여예외상황을처리하는예이다. try { stmt.execute("drop table not_exist_table"); } catch (SQLException e) { System.out.println("ERROR[" + e.geterrorcode + "]" + e.getmessage()); e.printstacktrace(); } 실행하면다음과같은정보가화면에출력된다. ERROR[-7071] Schema object'not_exist_table' does not exist or is of imcompatible type. com.tmax.tibero.jdbc.tbsqlexception: Schema object 'NOT_EXIST_TABLE' does not exist or is of incompatible type. at com.tmax.tibero.jdbc.msg.common.tbmsgerror.readerrorstackinfo(tbmsgerror.java :108) at com.tmax.tibero.jdbc.msg.tbmsgereply.deserialize(tbmsgereply.java:61) at com.tmax.tibero.jdbc.comm.tbstream.readmsgbody(tbstream.java:327) at com.tmax.tibero.jdbc.comm.tbcommtype4.executedirect(tbcommtype4.java:460) at com.tmax.tibero.jdbc.tbstatement.executeinternal(tbstatement.java:1051) at com.tmax.tibero.jdbc.tbstatement.execute(tbstatement.java:560) at TestSimple.main(TestSimple.java:102) 제 3 장 tbjdbc 의사용 17
제 4 장 DataSource 객체와데이터베이스 URL DataSource 객체는데이터베이스의모든리소스를지칭하는포괄적인개념으로 JDBC 2.0 표준의확장 API로처음소개되었다. 여기서설명하는 DataSource는하나의데이터베이스에대응된다. 본장에서는 tbjdbc에서제공하는 DataSource 객체를이용하여데이터베이스에연결하는방법과데이터베이스 URL에대해설명한다. 4.1. DataSource 객체 javax.sql.datasource 에정의된기본인터페이스는다음과같다. public interface DataSource { Connection getconnection() throws SQLException; Connection getconnection(string username, String password) throws SQLException;... } Tibero에서는 com.tmax.tibero.jdbc.ext 패키지를제공하고있다. 즉각종 DataSource 객체의속성을설정할수있는메소드를제공하여애플리케이션프로그램개발자의편의를제공하고있다. 4.1.1. DataSource 객체의속성 다음은 DataSource 객체에설정할수있는속성이다. 속성 databasename datasourcename description networkprotocol password portnumber servername user 타입 String String String String String int String String 설명서버에존재하는특정데이터베이스의이름이다. DataSource의이름이다. DataSource에대한설명이다. 서버와통신하는네트워크프로토콜의이름이다. ( 기본값 : TCP) 서버접속을위한패스워드이다. 서버리스너의포트번호이다. 데이터베이스의이름이다. 서버접속을위한사용자이름이다. 제 4 장 DataSource 객체와데이터베이스 URL 19
다음은위표에서설명한 DataSource 객체의속성을설정할수있는메소드이다. public synchronized String getdatabasename() public synchronized void setdatabasename(string databasename) public synchronized String getdatasourcename() public synchronized void setdatasourcename(string datasourcename) public synchronized String getdescription() public synchronized void setdescription(string description) public synchronized String getnetworkprotocol() public synchronized void setnetworkprotocol(string networkprotocol) public synchronized String getpassword() public synchronized void setpassword(string password) public synchronized String getportnumber() public synchronized void setportnumber(int portnumber) public synchronized String getservername() public synchronized void setservername(string servername) public synchronized String getuser() public synchronized void setuser(string user) 4.1.2. DataSource 객체의추가속성 다음은추가로설정할수있는 DataSource 객체의속성이다. 속성 drivertype logwriter 타입 String java.io.printwriter 설명 JDBC Driver 의타입이다. DataSource 객체를위한 Log Writer 이다. 20 Tibero JDBC 개발자안내서
속성 maxstatements URL 타입 int String 설명 애플리케이션프로그램캐시에서저장할문장의최댓값이다. 데이터베이스연결을위한데이터베이스 URL 이다. 다음은위표에서설명한 DataSource 객체의추가속성을설정할수있는메소드이다. String getdrivertype() void setdrivertype(string drivertype) PrintWriter getlogwriter() void setlogwriter(printwriter writer) int getmaxstatements() void setmaxstatements(int maxstatements) String geturl() void seturl(string url) 4.2. DataSource 객체를이용한연결 DataSource 객체를이용하여데이터베이스에연결하는방법은 JNDI를사용하지않는방법과사용하는방법이있다. JNDI(Java Naming and Directory Interface) 는 Java로작성된애플리케이션프로그램이 DNS, NDS 등과같은네이밍, 디렉터리서비스에접근하기위한 API이다. 4.2.1. JNDI 를사용하지않는방법 다음은 JNDI를사용하지않고 DataSource 객체를사용하여데이터베이스에연결하는가장일반적인방법이다. 방법은 TbDataSource 객체를생성한후기본속성을설정하면된다. 예를들면다음과같다. TbDataSource ds = new TbDataSource(); ds.setdrivertype("thin"); ds.setservername("tmaxh4"); ds.setnetworkprotocol("tcp"); 제 4 장 DataSource 객체와데이터베이스 URL 21
ds.setdatabasename("tibero"); ds.setportnumber("8888"); ds.setuser("tibero"); ds.setpassword("tmax"); Connection conn = ds.getconnection(); 4.2.2. JNDI 를사용한방법 다음은 JNDI 를사용하여데이터베이스에연결하는예이다. 1. TbDataSource 객체를생성한후, 기본속성을설정한다. TbDataSource ds = new TbDataSource(); ds.setdrivertype("thin"); ds.setservername("tmaxh4"); ds.setnetworkprotocol("tcp"); ds.setdatabasename("tibero"); ds.setportnumber("8888"); ds.setuser("tibero"); ds.setpassword("tmax"); 2. 초기화된 DataSource 객체를 JNDI 에등록한다. Context ctx = new InitialContext(); ctx.bind("tibero/webdb", ds); InitialContext() 를호출하면 JNDI를참조하는 context 객체가생성되고, ctx.bind() 를호출하면 DataSource 객체와 JNDI 이름이연결된다. 즉이것은위에서연결시킨 'tibero/webdb' 만을이용하여다음의예처럼언제든지데이터베이스에연결할수있다는말이다. TbDataSource ds = (TbDataSource)ctx.lookup("tibero/webdb"); Connection conn = ds.getconnection(); 4.3. 데이터베이스 URL 과데이터베이스지시자 데이터베이스 URL(Uniform Resource Locator) 은다음과같이문자열값으로사용한다. jdbc:tibero:thin:@database_sepcifier Tibero 에서제공하는데이터베이스지시자 (database_specifier) 는다음과같이사용할수있다. hostname:port:[service_name] 22 Tibero JDBC 개발자안내서
또한, 여러개의데이터베이스연결을지정하기위한 DESCRIPTION 형태도제공한다. (DESCRIPTION= (LOAD_BALANCE=ON) (FAILOVER=ON) (ADDRESS_LIST= (ADDRESS=(PROTOCOL=TCP)(HOST=dbsvr1)(PORT=8629)) (ADDRESS=(PROTOCOL=TCP)(HOST=dbsvr2)(PORT=7629))... )) 위의예에서 LOAD_BALANCE와 FAILOVER 기능은선택적으로적용할수있다. 단, ADDRESS_LIST는하나이상의 ADDRESS를반드시명시해야한다. 제 4 장 DataSource 객체와데이터베이스 URL 23
제 5 장분산트랜잭션 본장에서는 tbjdbc 에서제공하는분산트랜잭션 (distributed transaction) 기능을설명한다. 분산트랜잭 션의대표적인예로는 XA(Extended Architecture) 가있으며이와관련된설명을주로한다. 5.1. 개요 분산트랜잭션이란보통전역트랜잭션이라고도불리는데, 통합으로관리되는하나이상의트랜잭션집합을말한다. 분산트랜잭션에참여하는트랜잭션은동일한데이터베이스에존재할수도있고, 다른데이터베이스에존재할수도있다. 이러한각각의트랜잭션을트랜잭션브랜치 (branch) 라고한다. 분산트랜잭션은 JDBC 2.0 표준의확장 API로서접속풀링기능을기반으로제공되거나 X/Open DTP(Distributed Transaction Processing) 규약의 XA 표준으로제공되기도한다. 분산트랜잭션은다음과같은특징이있다. 분산트랜잭션은개별트랜잭션을관리하기위해외부의트랜잭션관리자를이용한다. 트랜잭션관리자는 Java Transaction API 표준을구현한소프트웨어요소로서여러벤더 (vendor) 에서 XA 호환 JTA 모듈을제공한다. XA 기능은애플리케이션프로그램과는별도로구분되며, 대부분애플리케이션프로그램서버 (application server) 와같은 Middle-tier 에서사용된다. 리소스매니저 (Resource Manager) 는데이터나다른종류의리소스를지칭하는용어로본장에서는데 이터베이스를가리킨다. 5.2. 구성요소 본절에서는 XA 기능을구성요소별로설명한다. XA datasource XA datasource는 Connection pool datasource나다른 datasource와비슷한개념과기능을가진다. 분산트랜잭션에서사용되는각각의리소스매니저 ( 데이터베이스 ) 에는하나의 XA datasource 객체가존재하고, 이 XA datasoure가 XA connection을생성한다. XA connection XA connection 은 Pooled connection 의확장이며, 개념이나기능면에서는비슷하다. 제 5 장분산트랜잭션 25
XA connection 은물리적인데이터베이스연결에대한임시핸들이되고, 하나의 XA connection 은하나 의데이터베이스세션에해당한다. XA resource XA resource는분산트랜잭션의각트랜잭션브랜치를조합하기위해트랜잭션관리자에의해사용된다. 각각의 XA connection으로부터하나의 XA resource 객체를얻어올수있고, 1:1 관계를가진다. 따라서하나의 XA resource 객체는하나의데이터베이스세션에해당된다. 하나의 XA resource 객체는실행중인오직하나의트랜잭션브랜치만있을수있다. 그러나실행중인트랜잭션과는별개로정지된트랜잭션도있을수있다. 각각의 XA resource 객체는해당세션에서수행되며시작, 종료, 준비, 커밋, 롤백등의기능이있다. XID 각각의트랜잭션브랜치를구분하기위해 XID ( 트랜잭션 ID) 를사용하고, 하나의 XID 는트랜잭션브랜 치 ID 와분산트랜잭션 ID 로구성된다. 5.3. 전역트랜잭션과지역트랜잭션간의변환 JDBC 3.0 표준에서는전역트랜잭션과지역트랜잭션사이에서커넥션을공유할수있고, 각각으로변환할수있다. 일반적으로커넥션은다음의세가지모드중에반드시하나를갖는다. 모드 NO_TXN LOCAL_TXN 설명현재커넥션을사용하는활성화된트랜잭션이없는모드이다. auto-commit 모드를비활성화시킨상태로현재커넥션을사용하는활성화된트랜잭션이있는모드이다. 커넥션모드에따라 prepare(), commit(), rollback(), forget(), end() 메소드를 호출할수없고, XAException 이발생한다. GLOBAL_TXN 현재커넥션을사용하는활성화된트랜잭션이있는모드이다. 커넥션모드에따라 commit(), rollback(), setautocommit(), setsavepoint() 메소드를호출할수없고, SQLException 이발생한다. 각커넥션은실행상태에따라다음과같이세가지모드사이에서자동으로바뀐다. 단, 커넥션이초기화 될때에는항상 NO_TXN 모드로동작한다. 26 Tibero JDBC 개발자안내서
현재모드 NO_TXN 으로변환 LOCAL_TXN 으로변환 GLOBAL_TXN 으로변환 NO_TXN - auto-commit 모드를비활성 XAConnection 에서얻은 화시키고 DML 문을수행했 XAResource 에 end() 메소 을때 드를호출했을때 LOCAL_TXN DDL 문이수행되거나 com - 불가능 mit() 또는 rollback() 메소드 를호출했을때 GLOBAL_TXN XAConnection 에서얻은 불가능 - XAResource 에 end() 메소드 를호출했을때 5.4. Tibero XA 패키지 Tibero에서는 XA 표준에따른분산트랜잭션패키지인 com.tmax.tibero.jdbc.ext 내부에다음과같은클래스를지원한다. TbXAConnection TbXADataSource TbXAException TbXAResource TbXid 5.5. XA 인터페이스의구성요소 본절에서는 JDBC 2.0 표준패키지에정의된 XA 인터페이스의구성요소를설명한다. 5.5.1. XADataSource 인터페이스 javax.sql.xadatasource 에정의된인터페이스는다음과같다. public interface XADataSource { XAConnection getxaconnection() throws SQLException; XAConnection getxaconnection(string user, String password) throws SQLException;... } 제 5 장분산트랜잭션 27
tbjdbc 에서는 com.tmax.tibero.jdbc.ext.tbxadatasource 클래스로제공된다. 또한, TbConnectionPool DataSource 를확장하여일반적인 DataSource 에서사용할수있는커넥션의특성을사용할수도있다. 5.5.2. XAConnection 인터페이스 javax.sql.xaconnection 에정의된인터페이스는다음과같다. public interface XAConnection extends PooledConnection { javax.transaction.xa.xaresource getxaresource() throws SQLException; } tbjdbc에서는 com.tmax.tibero.jdbc.ext.tbxaconnection 클래스로제공된다. 5.5.3. XAResource 인터페이스 javax.transaction.xa.xaresource 에정의된인터페이스는다음과같다. public interface XAResource { void commit(xid xid, boolean onephase) throws XAException; void end(xid xid, int flags) throws XAException; void forget(xid xid) throws XAException; int prepare(xid xid) throws XAException; int rollback(xid xid) throws XAException; void start(xid xid, int flags) throws XAException; boolean issamerm(xaresource xares) throws XAException; } tbjdbc에서는 com.tmax.tibero.jdbc.ext.tbxaresource 클래스로제공된다. 5.5.4. XID 인터페이스 트랜잭션관리자는 XID 객체를생성하고, 이를이용하여분산트랜잭션의브랜치를관리한다. 각각의트랜잭션브랜치는개별적으로 XID를부여받는다. XID는다음의정보를포함한다. 포맷지시자 (4byte) Java 트랜잭션관리자를가리키며, NULL이될수없다. 이정보를얻기위한메소드는다음과같다. public int getformatid() 28 Tibero JDBC 개발자안내서
전역트랜잭션지시자 (64byte) 동일한분산트랜잭션에속하는트랜잭션브랜치의경우모두같은값을가진다. 이정보를얻기위한메소드는다음과같다. public byte[] getglobaltransactionid() 브랜치지시자 (64byte) 이정보를얻기위한메소드는다음과같다. public byte[] getbrachequalifier() javax.transaction.xa.xid 에정의된인터페이스는다음과같다. public TbXid(int formatid, byte[] globalid, byte[] branchid) throws XAException tbjdbc 에서는 com.tmax.tibero.jdbc.ext.tbxid 클래스로제공된다. 5.5.5. XAResource 메소드 Start XAResource 인터페이스에서설정할수있는메소드는다음과같다. XID와관련된트랜잭션의특정브랜치를시작하거나이미존재하는트랜잭션을재시작혹은변경사항을조인시키기위해사용하는메소드이다. 문법 void start(xid xid, int flags) 파라미터 파라미터 xid flags 설명 현재리소스객체와관련된글로벌트랜잭션의 ID 이다. flags 파라미터는반드시다음의값중의하나여야한다. - XAResource.TMNOFLAGS: 새로운트랜잭션브랜치가시작된다. - XAResource.TMJOIN: 이미존재하는트랜잭션브랜치에다음동작을조인시킨다. - XAResource.TMRESUME: 정지된트랜잭션을다시시작시킨다. - TbXAResource.TBRTMSERIALIZABLE: Serializable 트랜잭션을시작시킨다. 제 5 장분산트랜잭션 29
파라미터 설명 - TbXAResource.TBRTMREADONLY: Read-only 트랜잭션을시작시킨다. - TbXAResource.TBRTMREADWRITE: Read/write 트랜잭션을시작시킨다. - TbXAResource.TBRTRANSLOOSE: Loosely-coupled 트랜잭션을시작시킨다. End XID 와관련된트랜잭션의특정브랜치에대한종료상태 ( 정상혹은실패 ) 를알리거나이미존재하는트랜 잭션을멈추기위해사용하는메소드이다. 문법 void end(xid xid, int flags) 파라미터 파라미터 xid flags 설명 현재리소스객체와관련된글로벌트랜잭션의 ID 이다. flags 파라미터는반드시다음의값중의하나여야한다. - XAResource.TMSUCCESS: 현재트랜잭션브랜치가성공했음을알린다. - XAResource.TMFAIL: 현재트랜잭션브랜치가실패했음을알린다. - XAResource.TMSUSPEND: 현재트랜잭션브랜치를정지시킨다. Prepare 현재의트랜잭션브랜치에서수행된변경사항을적용하기위해준비하는과정으로 Two-phase commit 과정의첫번째단계이다. 만약분산트랜잭션내부에오직하나의트랜잭션만있는경우라면 prepare() 를수행할필요가없다. 문법 int prepare(xid xid) 파라미터 파라미터 xid 설명 현재리소스객체와관련된글로벌트랜잭션의 ID 이다. 30 Tibero JDBC 개발자안내서
반환값 이메소드는반드시다음의값중의하나를반환한다. 반환값 XAResource.XA_RDONLY XAResource.XA_OK 설명현재의트랜잭션브랜치는 read-only 모드로동작하므로 SELECT 문만수행할수있다. 현재의트랜잭션브랜치에서는어떠한수정작업도수행할수있다. Commit 현재의트랜잭션브랜치의변화를반영하는과정으로 Two-phase commit 과정의두번째단계이다. 단, 모든트랜잭션브랜치가 prepare를완료한후에수행된다. 문법 void commit(xid xid, boolean isonephase) 파라미터 파라미터 xid isonephase 설명 현재리소스객체와관련된글로벌트랜잭션의 ID 이다. isonephase 파라미터에설정된값에따라다음과같이동작한다. - true: Two-phase commit 과정이아닌 One-phase commit 과정으로동작한다. - false: Two-phase commit 과정으로동작한다. Rollback 현재의트랜잭션브랜치의변화를롤백시킨다. 문법 void rollback(xid xid) 파라미터 파라미터 xid 설명 현재리소스객체와관련된글로벌트랜잭션의 ID 이다. 제 5 장분산트랜잭션 31
Forget 리소스매니저가지정한트랜잭션브랜치를무시하도록한다. 문법 void forget(xid xid) 파라미터 파라미터 xid 설명 현재리소스객체와관련된글로벌트랜잭션의 ID 이다. Recover 현재준비가완료되었거나수행이끝난트랜잭션브랜치의목록을반환한다. 문법 Xid[] recover(int flag) 파라미터 파라미터 flag 설명 flags 파라미터는반드시다음의값중의하나여야한다. - XAResource.TMSTARTSCAN: 현재준비가완료된트랜잭션을반환한다. - XAResource.TMENDSCAN: 현재수행이끝난트랜잭션을반환한다. - XAResource.TMNOFLAGS: 모든트랜잭션을반환한다. issamerm 두개의 XA 리소스객체가동일한리소스매니저에속해있는지의여부를반환한다. 문법 boolean issamerm(xaresource aresource) 파라미터 파라미터 aresource 설명 현재리소스객체와비교할리소스객체이다. 32 Tibero JDBC 개발자안내서
5.6. 분산트랜잭션예제 다음은두개의트랜잭션브랜치로이루어진 Two-phase 분산트랜잭션환경을구현하는순서이다. 1. 트랜잭션브랜치 #1 을시작한다. 2. 트랜잭션브랜치 #2 를시작한다. 3. 트랜잭션브랜치 #1 에서 DML 문장을수행한다. 4. 트랜잭션브랜치 #2 에서 DML 문장을수행한다. 5. 트랜잭션브랜치 #1 의트랜잭션을종료한다. 6. 트랜잭션브랜치 #2 의트랜잭션을종료한다. 7. 트랜잭션브랜치 #1 을준비한다. 8. 트랜잭션브랜치 #2 를준비한다. 9. 트랜잭션브랜치 #1 을커밋한다. 10. 트랜잭션브랜치 #2 를커밋한다. 다음의예는위순서에맞게구현된 Java 프로그램소스코드이다. import java.sql.*; import javax.sql.xaconnection; import javax.transaction.xa.xaresource; import com.tmax.tibero.jdbc.ext.*; public class TwoBranchXA { public static void main(string args[]) throws SQLException { createbasetable(); try { // Create XADataSource instance TbXADataSource xads1 = new TbXADataSource(); xads1.seturl("jdbc:tibero:thin:@localhost:7629"); xads1.setuser("tibero"); xads1.setpassword("tmax"); TbXADataSource xads2 = new TbXADataSource(); 제 5 장분산트랜잭션 33
xads2.seturl("jdbc:tibero:thin:@localhost:8629"); xads2.setuser("wrpark"); xads2.setpassword("tmax"); // Get the XA connection XAConnection xacon1 = xads1.getxaconnection(); XAConnection xacon2 = xads2.getxaconnection(); // Get the physical connection Connection conn1 = xacon1.getconnection(); Connection conn2 = xacon2.getconnection(); // Get the XA resource XAResource xars1 = xacon1.getxaresource(); XAResource xars2 = xacon2.getxaresource(); // Create the Xid Xid xid1 = createxid(1); Xid xid2 = createxid(2); // Start the resource xars1.start(xid1, XAResource.TMNOFLAGS); xars2.start(xid2, XAResource.TMNOFLAGS); // Execute SQL operations execute1(conn1); execute2(conn2); // End both the branches xars1.end(xid1, XAResource.TMSUCCESS); xars2.end(xid2, XAResource.TMSUCCESS); // Prepare the resource manager int pre1 = xars1.prepare(xid1); int pre2 = xars2.prepare(xid2); // Commit or rollback if (pre1 == XAResource.XA_RDONLY pre1 == XAResource.XA_OK) xars1.commit(xid1, false); else xars1.rollback(xid1); if (pre2 == XAResource.XA_RDONLY pre2 == XAResource.XA_OK) xars2.commit(xid2, false); else xars2.rollback(xid2); 34 Tibero JDBC 개발자안내서
// Clear conn1.close(); conn1 = null; conn2.close(); conn2 = null; } } xacon1.close(); xacon1 = null; xacon2.close(); xacon2 = null; } catch (Exception se) { se.printstacktrace(); } 제 5 장분산트랜잭션 35
제 6 장결과집합확장기능 본장에서는 JDBC 2.0 표준에서제공하는기능인 Scrollable, Updatable 결과집합의확장기능을설명한 다. 6.1. JDBC 2.0 표준 JDBC 2.0 표준에서는 scrollability, positioning, sensitivity, updatability 에대한확장기능을제공한다. 결과집합타입에의해 scrollability, positioning, sensitivity 가결정된다. 동시성타입에의해 updatability 가결정된다. 6.1.1. Scrollability, Positioning, Sensitivity Scrollability, Positioning은결과집합에대해정방향뿐만아니라역방향으로도움직일수있고, 상대위치나절대위치등의임의의위치로움직일수있는기능이다. 여기서상대위치는현재열의위치로부터정방향또는역방향으로의이동을말하고, 절대위치는결과집합의시작이나끝에서부터의이동을말한다. 주의 Scrollablility 기능을사용할경우결과집합의모든열은사용자의메모리에로드되기때문에이를주 의해야한다. 그리고될수있으면용량이큰데이터를갖는결과집합은사용하지말것을권장한다. Scrollability, Positioning 결과집합을생성할때는반드시 Sensitivity를설정해야하는데, 이는현재의결과집합에관계없이데이터베이스에적용된변경사항을반영할것인지의여부를결정한다. Sensitivity는데이터베이스에적용된변경사항이바로적용되어새로운데이터를볼수있다. 반면에 In sensitivity는최초결과집합이생성된시점의데이터만볼수있다. 결과집합을생성할때결정할수있는결과집합의타입은다음과같다. ResultSet.TYPE_FORWARD_ONLY ResultSet.TYPE_SCROLL_SENSITIVE ResultSet.TYPE_SCROLL_INSENSITIVE 제 6 장결과집합확장기능 37
6.1.2. Updatability Updatability 는결과집합에직접수정한후에데이터베이스에반영할수있는기능이다. 예를들어새로운 열을추가하거나기존의열을지우거나수정하는것이이에해당된다. 주의 이기능은데이터베이스에접근해야하므로, 잠금 (Lock) 설정이필요할수도있다는점을주의해야 한다. 결과집합을생성할때결정할수있는동시성타입은다음과같다. ResultSet.CONCUR_UPDATABLE ResultSet.CONCUR_READ_ONLY 6.2. Scrollable, Updatable 결과집합생성 6.2.1. Statement 객체생성 tbjdbc 에서는 Connection 클래스에다음과같은메소드를제공한다. Statement createstatement(int resultsettype, int resultsetconcurrency) PreparedStatement preparestatement(string sql, int resultsettype, int resultsetconcurrency) CallableStatement preparecall(string sql, int resultsettype, int resultsetconcurrency) 다음은 Statement 객체를생성하는예이다. Statement stmt = conn.createstatement(resultset.type_scroll_sensitive, ResultSet.CONCUR_UPDATABLE); ResultSet rs = stmt.executequery("select empno FROM emp"); 6.2.2. 결과집합특성확인 Statement, PreparedStatement, CallableStatement 객체를생성한후에는다음의메소드를사용하여결과집합타입과동시성타입을확인할수있다. int getresultsettype() throws SQLException int getresultsetconcurrent() throws SQLException 38 Tibero JDBC 개발자안내서
6.2.3. 제약사항 Updatable 결과집합을생성할때는다음과같은제약사항이존재한다. 오직하나의테이블에대한질의문만사용할수있고, 조인 (join) 은사용할수없다. 'SELECT *' 와같은형태는사용할수없고, 'SELECT T.*' 와같은형태만사용할수있다. 오직테이블의컬럼에대해서만질의문을사용할수있다. Scroll-sensitive 결과집합을생성할때는다음과같은제약사항이존재한다. 오직하나의테이블에대한질의문만사용할수있다. 'SELECT *' 와같은형태는사용할수없고, 'SELECT t.*' 와같은형태만사용할수있다. 6.3. Scrollable 결과집합탐색 다음은 Scrollable 결과집합을위해제공되는메소드로, 새로운위치로이동할수있다. 메소드 boolean next() throws SQLException boolean previous() throws SQLException boolean first() throws SQLException boolean last() throws SQLException boolean absolute(int row) throws SQLException 설명현재위치에서다음열로이동한다. 만약더는다음열이존재하지않는경우 false를반환한다. 현재위치에서이전열로이동한다. 만약더는이전열이존재하지않는경우 false를반환한다. 결과집합의첫번째열로이동한다. 만약열데이터가하나도없을경우 false를반환한다. 결과집합의마지막열로이동한다. 만약열데이터가하나도없을경우 false를반환한다. 결과집합의처음이나마지막열의위치에서부터정해진값만큼절대위치로이동한다. 만약입력값이양수인경우에는처음열부터정방향으로이동하고, 음수인경우에는마지막열부터역방향으로이동한다. 만약결과집합의개수보다더큰양수값을사용할경우에는마지막열다음으로이동하며, 이는 afterlast() 와같은효과를가진다. 마찬가지로결과집합의개수보다더큰음수값을사용할경우에는 beforefirst() 와같은효과를가진다. boolean relative(int row) throws SQLException 현재열의위치로부터시작하여양수값이면정방향으로이동하고, 음수값 이면역방향으로이동한다. 제 6 장결과집합확장기능 39
메소드 설명 만약결과집합의개수보다더큰양수값을사용할경우에는마지막열다음으로이동하며, 이는 afterlast() 와같은효과를가진다. 마찬가지로결과집합의개수보다더큰음수값을사용한경우에는 beforefirst() 와같은효과를가진다. 주의할점은반드시현재열의위치가적절해야한다는것이다. 처음열의위치이전이나마지막열의위치다음에서부터상대위치로의이동은할수없으며, SQLException을발생시킨다. void beforefirst() throws SQLException void afterlast() throws SQLException 결과집합의첫번째열이전으로이동한다. 이는정방향으로결과집합을탐색할때의상태이며바로사용할수있는열데이터는없다. 결과집합의마지막열다음으로이동한다. 이는역방향으로결과집합을탐색할때의상태이며바로사용할수있는열데이터는없다. 현재의위치정보를알기위해 tbjdbc 에서는다음과같은메소드를제공한다. 메소드 int getrow() throws SQLException boolean isfirst() throws SQLException boolean islast() throws SQLException boolean isbeforefirst() throws SQLException boolean isafterlast() throws SQLException 설명현재열의위치를반환하며, 적합한열의위치가아닌경우에는 0을반환한다. 현재열의위치가첫번째열인지확인한다. 현재열의위치가마지막열인지확인한다. 현재열의위치가첫번째열의이전열인지확인한다. 현재열의위치가마지막열의다음열인지확인한다. 6.4. Updatable 결과집합탐색 사용자는 Updatable 결과집합을이용하여열의데이터를업데이트할수있고, 삭제할수도있으며, 새로운열의데이터를입력할수도있다. UPDATE나 INSERT를수행한후에는반드시별도의단계를거쳐데이터베이스에변경사항을반영해야한다. 그렇지않으면변경된모든데이터는소멸된다. 반면에 DELETE를수행한경우에는별도의단계없이즉시데이터베이스에반영된다. 40 Tibero JDBC 개발자안내서
6.4.1. INSERT INSERT 작업은다음의과정을거쳐데이터베이스에반영된다. 1. movetoinsertrow() 메소드를이용하여 INSERT를수행하기위한임시열데이터저장공간으로이동한다. 결과집합은기존의열의위치를내부적으로기억하고있으므로 movetocurrentrow() 메소드를사용할경우원래열의위치로이동할수있다. 2. 적절한 updatexxx() 메소드를수행하여컬럼의데이터를작성한다. 만약특정컬럼의데이터를작성하 지않는다면, NULL 상태로남아있게된다. 3. insertrow() 메소드를수행하여데이터베이스에반영한다. 만약 INSERT를수행한후에이를취소하고싶다면, 다른열의위치로이동하여원래의데이터로복원하면된다. 그러나반드시다음의사항을주의해야한다. insertrow() 메소드를수행한경우데이터베이스에반영이되므로롤백하기전에는취소되지않는다. 어떠한결과집합의타입도 INSERT 작업에의해수행된열의데이터를볼수없다. 다음은 INSERT 작업을수행하는예이다. rs.movetoinsertrow(); rs.updatestring(1, "tibero"); rs.insertrow(); rs.movetocurrentrow(); 6.4.2. UPDATE UPDATE 작업은다음의두단계를거쳐야데이터베이스에최종으로반영된다. 1. updatexxx() 메소드를수행한다. 2. updaterow() 메소드를수행하여데이터베이스에반영한다. 이때 auto-commit 모드에따라커밋이될수도있다. 만약 UPDATE를수행한후에이를취소하고싶다면, cancelrowupdates() 메소드를수행하거나다른열의위치로이동할경우원래의데이터로복원하면된다. 그러나, updaterow() 메소드를수행한경우라면데이터베이스에반영이되므로롤백하기전에는취소되지않음을주의해야한다. 다음은 UPDATE 작업을수행하는예이다. 제 6 장결과집합확장기능 41
rs.absolute(5); rs.updatestring(1, "tibero"); rs.updaterow(); 6.4.3. DELETE 다음의메소드를사용하여 DELETE 작업을수행할수있다. void deleterow() throws SQLException DELETE 작업을수행할때는반드시다음의사항을주의해야한다. DELETE 작업을수행할경우 데이터베이스에바로적용되므로 auto-commit 모드의설정값에따라바로커밋이될수도있다. 사용자에의해지워진열데이터의경우데이터베이스에는반영되지만결과집합자체에는남아있게된다. 반대로 Scrollable 결과집합인경우에는바로재조정이일어난다. 즉현재열의위치는바로이전의열의데이터를가리키게되고, 다음열의위치는자동으로당겨지게된다. 다음은 DELETE 작업을수행하는예이다. rs.absolute(5); rs.deleterow(); 42 Tibero JDBC 개발자안내서
제 7 장 Row Set 본장에서는 tbjdbc 에서제공하는 Row Set 기능을설명한다. 7.1. 개요 Row Set이란문자그대로로우데이터의집합을포함하는객체이다. javax.sql.rowset 인터페이스메소드를통해접근할수있다. 일반적으로 Row Set은다음과같이세가지로나뉜다. Cached Row Set tbjdbc에서는현재이 Row Set만제공한다. JDBC Row Set Web Row Set 7.2. Row Set Listener Row Set에서는여러개의리스너를등록하여사용할수있다. 등록할때는 addrowsetlistener() 메소드를사용하고, 제거할때는 removerowsetlistener() 메소드를사용하면된다. 이때사용되는리스너는반드시 javax.sql.rowsetlistener 인터페이스를통해서구현되어야한다. RowSetListener 인터페이스에서제공하는이벤트는다음과같이세가지이다. 이벤트 cursormoved rowchanged rowsetchanged 설명 next() 나 previous() 등의메소드를통해열의이동이있을때마다발생한다. 새로운열이추가되거나기존의열이수정되거나삭제될때발생한다. 전체 Row Set이생성되거나변경될때발생한다. RowSetListener 인터페이스의이벤트를사용하는방법은다음의예와같다. 1. 리스너클래스를생성한다. public class MyListener implements RowSetListener { public void cursormoved(rowsetevent event) { 제 7 장 Row Set 43
} // do work } public void rowchanged(rowsetevent event) { // do work } public void rowsetchanged(rowsetevent event) { // do work } 2. 리스너를 RowSet 객체에등록한다. MyListener mlistener = new MyListener(); rowset.addrowsetlistener(mlistener); 7.3. Cached Row Set Cached Row Set 은모든열을캐시에저장하고, 데이터베이스와의연결을유지하지않도록구현된 Row Set 의한형태이다. tbjdbc 에서는 TbCachedRowSet 클래스로제공된다. 7.3.1. RowSet 객체생성 RowSet 객체는 execute() 메소드를통해사용할수있는준비를마치며, 그이후에는 java.sql.resultset 객체를사용하는방법과동일하게사용할수있다. 본절에서는 RowSet 객체를생성하는과정을두가지로나누어설명한다. 질의문을이용한 RowSet 객체생성 다음의예는질의문을이용하여 RowSet 객체를생성하는과정이다. 1. TbCachedRowSet 객체를생성한다. TbCachedRowSet rowset = new TbCachedRowSet(); 2. URL, 사용자이름, 패스워드, 질의문을설정한후에 execute() 메소드를수행하여 RowSet 객체를생성 한다. rowset.seturl("jdbc:tibero:thin:@localhost:8629"); rowset.setusername("tibero"); rowset.setpassword("tmax"); rowset.setcommand("select * FROM emp"); rowset.execute(); 44 Tibero JDBC 개발자안내서
결과집합을이용한 RowSet 객체생성 다음의예는기존에존재하는결과집합을이용하여 RowSet 객체를생성하는과정이다. 1. TbCachedRowSet 객체를생성한다. TbCachedRowSet rowset = new TbCachedRowSet(); 2. 결과집합객체 (rset) 를이용하여 populate() 메소드를수행하여 RowSet 객체를생성한다. ResultSet rset = pstmt.executequery(); rowset.populate(rset); 7.3.2. 열데이터탐색 RowSet 객체를이용하여정방향이나역방향으로이동하면서열의데이터를탐색할수있다. 예를들면다음과같다. rowset.beforefirst(); while (rowset.next()) { System.out.println(rowset.getString(1)); } rowset.afterlast(); while (rowset.previous()) { System.out.println(rowset.getString(1)); } 또한, 열의데이터를삽입, 삭제, 수정할수도있다. 단, acceptchanges() 메소드를수행해야커밋이실행 된다. 예를들면다음과같다. rowset.absolute(5); rowset.movetoinsertrow(); rowset.updatestring(1, "tibero"); rowset.insertrow(); rowset.acceptchanges(); 7.3.3. 제약사항 Updatable 결과집합에적용되는제약사항과동일하게적용된다. 제 7 장 Row Set 45
제 8 장 LOB 데이터처리 본장에서는 tbjdbc 에서 LOB 데이터를처리하는방법을설명한다. 8.1. 개요 JDBC 표준에서는 LOB 데이터를처리하기위해두가지타입을제공한다. BLOB( 바이너리데이터 ) 와 CLOB( 문자열데이터 ) 가이에해당한다. tbjdbc에서는이두가지타입을효율적으로처리하기위해지시자 (locator) 라는개념을사용한다. 일반적으로 LOB 데이터는데이터베이스에저장된후에지시자를생성하여데이터가저장된위치를찾아갈수있도록한다. 따라서사용자는이지시자만을사용하여필요할때마다 LOB 데이터를읽고쓸수있다. 이때문에시스템성능을향상시키는데도움을줄수있다. 다음은 tbjdbc에서제공하는 LOB 클래스이다. com.tmax.tibero.jdbc.tbblob com.tmax.tibero.jdbc.tbclob 8.2. LOB 지시자 8.2.1. LOB 지시자얻어오기 JDBC 표준에서제공하는 ResultSet 객체나 CallableStatement 객체의메소드를이용하여 LOB 지시자를얻어올수있다. ResultSet 객체 ResultSet.getBlob() ResultSet.getClob() ResultSet.getObject() 다음은 ResultSet 객체를이용하여 LOB 지시자를얻어오는예이다. ResultSet rs = stmt.executequery("select document, image FROM library"); while (rs.next()) { Clob document = rs.getclob(1); 제 8 장 LOB 데이터처리 47
// 또는 Clob document = (Clob)rs.getObject(1); } Blob image = rs.getblob(2); // 또는 Blob image = (Blob)rs.getObject(1); CallableStatement 객체 CallableStatement.getBlob() CallableStatement.getClob() CallableStatement.getObject() 다음은 CallableStatement 객체를이용하여 LOB 지시자를얻어오는예이다. CallableStatement cstmt = conn.preparecall("{call proc(?)}"); cstmt.registeroutparameter(1, Types.CLOB); cstmt.execute(); Clob document = cstmt.getclob(1); // 또는 Clob document = (Clob)cstmt.getObject(1); 8.2.2. LOB 지시자넘겨주기 JDBC 표준에서제공하는 PreparedStatement 객체나 CallableStatement 객체의메소드를이용하여 LOB 지시자를넘겨줄수있다. PreparedStatement 객체 PreparedStatement.setBlob() PreparedStatement.setClob() PreparedStatement.setObject() 다음은 PreparedStatement 객체를이용하여 LOB 지시자를넘겨주는예이다. PreparedStatement pstmt = conn.preparestatement("insert INTO library VALUES (?,?)"); pstmt.setclob(1, document); // 또는 pstmt.setobject(1, document, Types.CLOB); pstmt.setblob(2, image); // 또는 pstmt.setobject(1, image, Types.BLOB); pstmt.executeupdate(); CallableStatement 객체 48 Tibero JDBC 개발자안내서
CallableStatement.setBlob() CallableStatement.setClob() CallableStatement.setObject() 다음은 CallableStatement 객체를이용하여 LOB 지시자를넘겨주는예이다. CallableStatement cstmt = conn.preparecall("{call proc(?,?)}"); cstmt.setclob(1, document); // 또는 cstmt.setobject(1, document, Types.CLOB); cstmt.setblob(2, image); // 또는 cstmt.setobject(1, image, Types.BLOB); cstmt.execute(); 8.3. LOB 데이터읽고쓰기 LOB 지시자를얻어오면 JDBC 표준에서제공하는 API를이용하여데이터를읽고쓸수있다. LOB 데이터는보통 byte 배열이나스트림형태로읽어올수있는데, 일반적인스트림형태와달리데이터베이스서버내부에데이터가있으므로연결이유지되는한언제든지접근할수있다. JDBC 표준에서는 LOB 데이터를읽고쓸수있도록다음과같은 API를제공한다. InputStream Clob.getAsciiStream() Reader Clob.getCharacterStream() String Clob.getSubString() OutputStream Clob.setAsciiStream() Writer Clob.setCharacterStream() int Clob.setString() InputStream Blob.getBinaryStream() byte[] Blob.getBytes() OutputStream Blob.setBinaryStream() int Blob.setBytes() 제 8 장 LOB 데이터처리 49
다음은 LOB 데이터를읽는예이다. // BLOB 데이터 InputStream is = image.getbinarystream(); byte[] imagedata = new byte[1000]; int readlength = is.read(imagedata); // CLOB 데이터 Reader reader = document.getcharacterstream(); char[] docdata = new char[1000]; int readlength = reader.read(docdata, 0, docdata.length); 다음은 LOB 데이터를쓰는예이다. // BLOB 데이터 byte[] imagedata = {32, 53, 78, 19, 2, 93}; OutputStream os = image.setbinarystream(); os.write(imagedata); // CLOB 데이터 char[] docdata = {'J', 'D', 'B', 'C', ' 안 ', ' 내 ', ' 서 '}; Writer writer = document.setcharacterstream(); writer.write(docdata); writer.flush(); writer.close(); 위의예에서 OutputStream이나 Writer 객체는데이터를쓸때마다데이터베이스에직접전송되므로별도의 UPDATE 문장을실행할필요가없다. 하지만, LOB 자체는트랜잭션범위에포함되므로반드시커밋을수행해야데이터베이스에최종적으로반영된다. 8.4. 임시 LOB tbjdbc에서는대용량데이터를 LOB 형태로저장하기위해임시 LOB을제공한다. 단, 이대용량데이터는테이블에저장되지않는다. 이를위해다음과같은메소드를제공한다. Connection.createBlob() return Blob Connection.createClob() return Clob Connection.createNClob() return NClob Blob.free() Clob.free() 50 Tibero JDBC 개발자안내서
NClob.free() 임시 LOB을사용하여저장한데이터는임시테이블스페이스에저장된다. 이영역에저장된데이터가더는필요하지않게되면, 사용자는반드시이것을해제해야한다. 그렇지않으면이영역의데이터는계속남아있게된다. 임시 LOB는 LOB 컬럼의데이터를바인딩할때주로사용한다. 예를들면다음과같다. PreparedStatement pstmt = conn.preparestatement("insert INTO library VALUES (?,?)"); pstmt.setint(1, 20090811); Clob doc = conn.createclob(); doc.setstring(1, "JDBC Guide<br>writer:Rachael<br>proofreader:Patrick"); pstmt.setclob(2, doc); pstmt.executeupdate(); doc.free(); pstmt.close(); 위에서나열한메소드들은 JDBC 표준 API들로일부메소드는 Java 버전에따라사용할수없는것들이존재한다. 이를위해 tbjdbc에서는별도로다음과같은구현메소드들을제공하고있다. 이메소드들을이용할경우다른 JDBC와의호환성은떨어지지만 tbjdbc에한하여 Java 버전에관계없이사용할수있는장점이있다. TbConnection.createTbBlob() return TbBlob TbConnection.createTbClob() return TbClob TbConnection.createTbNClob() return TbNClob Tibero 4sp1 까지의 tbjdbc 에서는구현메소드를다음과같은형태로제공하였으나, 호환성에문제가있 어폐기 (deprecated) 하고위의메소드들로대체되었다. static TbBlob.createTemporary(Connection conn) return TbBlob static TbClob.createTemporary(Connection conn) return TbClob static TbClob.createTemporaryNClob(Connection conn) return TbClob TbBlob.freeTemporary() static TbBlob.freeTemporary(TbBlob blob) TbClob.freeTemporary() 제 8 장 LOB 데이터처리 51
static TbClob.freeTemporary(TbClob clob) TbNClob.freeTemporary() static TbNClob.freeTemporary(TbNClob nclob) 8.5. API 목록 8.5.1. 표준 API LOB 와관련된표준 API 의정보는 JDBC 표준문서를참고하기바란다. 8.5.2. 확장 API tbjdbc 에서는 LOB 와관련된 API 로 BLOB, CLOB, NCLOB 메소드를추가로제공한다. CONNECTION API TbConnection 클래스에서는다음과같은 API 를추가로제공한다. API TbBlob createtbblob() TbClob createtbclob() TbNClob createtbnclob() 설명데이터베이스에임시 BLOB을생성한후에 TbBlob 객체를반환한다. 데이터베이스에임시 CLOB을생성한후에 TbClob 객체를반환한다. 데이터베이스에임시 NCLOB을생성한후에 TbNClob 객체를반환한다. BLOB API TbBlob 클래스에서는다음과같은 API 를추가로제공한다. API TbBlob createemptyblob() void close() OutputStream getbinaryoutput Stream() OutputStream getbinaryoutput Stream(long) void open(int) 설명 EMPTY_BLOB을생성하여반환한다. BLOB을닫는다. setbinarystream(1l) 과동일하다. setbinarystream(long) 과동일하다. int 모드로 BLOB을연다. 52 Tibero JDBC 개발자안내서
CLOB API TbClob 클래스에서는다음과같은 API 를추가로제공한다. API TbClob createemptyclob() void close() int getbuffersize() long getchars(long offset, char[] buffer) long getchars(long offset, char[] buffer, long numchars) long getchars(long offset, char[] buffer, long bufoffset, long num Chars) void open(int) long putchars(long offset, char[] buffer) long putchars(long offset, char[] buffer, long numchars) long putchars(long offset, char[] buffer, long bufoffset, long num Chars) 설명 EMPTY_CLOB을생성하여반환한다. CLOB을닫는다. 서버와원활하게통신할수있도록 32KB의버퍼크기를반환한다. offset 위치부터 CLOB 데이터를읽어서 buffer에저장한다. offset 위치부터 numchars 만큼의 CLOB 데이터를읽어서 buffer에저장한다. offset 위치부터 numchars 만큼의 CLOB 데이터를읽어서 buffer의 bufoffset 위치에저장한다. int 모드로 CLOB을연다. buffer 데이터를읽어서 offset 위치에저장한다. buffer 데이터를 numchars 만큼읽어서 offset 위치에저장한다. buffer 데이터를 bufoffset 위치부터 numchars 만큼읽어서 offset 위치에저장한다. NCLOB API TbNClob 클래스에서는다음과같은 API 를추가로제공한다. API TbNClob createemptynclob() void close() int getbuffersize() long getchars(long offset, char[] buffer) long getchars(long offset, char[] buffer, long numchars) 설명 EMPTY_NCLOB을생성하여반환한다. NCLOB을닫는다. 서버와원활하게통신할수있도록 32KB의버퍼크기를반환한다. offset 위치부터 NCLOB 데이터를읽어서 buffer에저장한다. offset 위치부터 numchars 만큼의 NCLOB 데이터를읽어서 buffer 에저장한다. 제 8 장 LOB 데이터처리 53
API long getchars(long offset, char[] buffer, long bufoffset, long num Chars) void open(int) long putchars(long offset, char[] buffer) long putchars(long offset, char[] buffer, long numchars) long putchars(long offset, char[] buffer, long bufoffset, long num Chars) 설명 offset 위치부터 numchars 만큼의 NCLOB 데이터를읽어서 buffer 의 bufoffset 위치에저장한다. int 모드로 NCLOB을연다. buffer 데이터를읽어서 offset 위치에저장한다. buffer 데이터를 numchars 만큼읽어서 offset 위치에저장한다. buffer 데이터를 bufoffset 위치부터 numchars 만큼읽어서 offset 위치에저장한다. 54 Tibero JDBC 개발자안내서
제 9 장 Failover 와로드밸런싱 본장에서는 tbjdbc 에서제공하는 Failover 기능과로드밸런싱 (Load balancing) 기능을설명한다. 9.1. Failover tbjdbc 는일반애플리케이션프로그램환경이나 TAC 환경에서최초연결을맺을때혹은임의의작업을 수행하는중에연결이끊어졌을때다시자동으로연결을맺는기능을제공한다. 이를 Failover 라한다. 9.1.1. Failover 기능활성화 Failover 기능을사용하려면 DriverManager.getConnection() 의 URL을 description 형태로작성하고 (FAILOVER=ON) 만추가하면된다. 다음은 Failover 기능을활성화하는예로, svr1로연결이실패하면자동으로 svr2로연결을시도한다. 단, 모든서버에대한연결시도가실패할때는에러가발생한다. Connection conn = DriverManager.getConnection("jdbc:tibero:thin:@(description=(failover=on)" + "(address_list="+ "(address=(host=svr1)(port=8629))"+ "(address=(host=svr2)(port=7629))"+ ")(DATABASE_NAME=TACUAC))", "tibero", "tmax"); 9.1.2. Failover 옵션설정 Failover 기능을활성화하여서버와연결을맺을때옵션을설정할수있다. 이옵션은 java.util.properties 클래스를이용하여저장되고, DriverManager.getConnection() 의파라미터로사용된다. Properties prop = new Properties(); prop.set("user", "tibero"); prop.set("password", "tmax"); prop.set("databasename", "TACUAC");... Connection conn = DriverManager.getConnection("jdbc:tibero:thin:@(description=(failover=on)" + "(address_list="+ "(address=(host=svr1)(port=8629))"+ 제 9 장 Failover 와로드밸런싱 55