Oracle Java Database Connectivity(JDBC)ドライバは、様々なバージョンのJDBC標準機能をサポートしています。Oracle Database 11gリリース2(11.2)では、Oracle JDBCドライバが強化され、JDBC 4.0標準がサポートされました。これらの機能は、oracle.jdbc
パッケージとoracle.sql
パッケージによって提供されます。これらのパッケージでは、Java Development Kit(JDK)リリース1.5と1.6がサポートされています。この章では、Oracle JDBCドライバでのJDBC標準のサポートについて説明します。この章には次の項目があります。
標準のJDBC 2.0の機能は、JDK 1.2以降のバージョンでサポートされています。考慮すべき点が3つあります。
オブジェクト、配列、ラージ・オブジェクト(LOB)などのデータ型に対するサポート。このサポートは、標準java.sql
パッケージを介して処理されます。
結果セット拡張やバッチ更新などの標準機能に対するサポート。このサポートは、JDK 1.2.x以上では、Connection
、ResultSet
およびPreparedStatement
などの標準オブジェクトを介して処理されます。
JDBC 2.0 Optional Packageの機能など、Standard Extension Application Program Interface(API)とも呼ばれる拡張機能に対するサポート。たとえばデータソース、接続プーリングおよび分散トランザクションなどがあげられます。
この項の内容は次のとおりです。
注意: 1.5より前のJDKのバージョンは、もうサポートされていません。oracle.jdbc2 パッケージは削除されました。 |
Oracle JDBCは、標準java.sql
パッケージ内のインタフェースの実装による標準JDBC 2.0機能を含む、JDK 1.5およびJDK 1.6を完全にサポートしています。これらのインタフェースは、oracle.sql
パッケージとoracle.jdbc
パッケージ内のクラスによって、適宜実装されます。
ojdbc5.jar
のJDBCクラスを使用するJDK 1.5環境では、スクロール可能結果セット、更新可能結果セット、バッチ更新などのJDBC 2.0機能は、標準のJDBC 2.0インタフェースによって指定されたメソッドを介してサポートされます。
データソース、接続プーリングおよび分散トランザクションなどのJDBC 2.0 Optional Packageの各機能は、JDK 1.2.x以上の環境でサポートされます。
標準javax.sql
パッケージとそのインタフェースを実装するクラスは、Oracle Databaseでパッケージ化されたJavaアーカイブ(JAR)ファイルに格納されています。
標準のJDBC 3.0の機能は、JDK 1.4以降のバージョンでサポートされています。表3-1では、Oracle Database 11gリリース2(11.2)でサポートしているJDBC 3.0機能と、各機能に関する詳細の参照先を示しています。
表3-1 JDBC 3.0機能の主な領域
機能 | コメントと参照 |
---|---|
トランザクション・セーブポイント |
詳細は、「トランザクション・セーブポイント」を参照してください。 |
文キャッシュ |
接続プーリングによってコンパイルされたSQL文を再使用します。第20章「文キャッシュと結果セット・キャッシュ」を参照してください。 |
ローカル・トランザクションとグローバル・トランザクションの切替え |
「ローカル・トランザクションとグローバル・トランザクションの切替え」を参照してください。 |
LOBの変更 |
「JDBC 3.0のLOBインタフェース・メソッド」を参照してください。 |
名前付きSQLパラメータ |
「インタフェースoracle.jdbc.OracleCallableStatement」および「インタフェースoracle.jdbc.OraclePreparedStatement」を参照してください。 |
RowSet |
第18章「JDBC RowSet」を参照してください。 |
自動生成キーの取出し |
「自動生成キーの取出し」を参照してください。 |
結果セットの保持機能 |
「結果セットの保持機能」を参照してください。 |
この項では、Oracle JDBCドライバによってサポートされている次のJDBC 3.0機能について説明します。
JDBC 3.0の仕様はセーブポイントをサポートしており、トランザクション内でより細かい境界設定をすることができます。アプリケーションはトランザクション内にセーブポイントを設定して、セーブポイントより後に行われたすべての作業をロールバックすることができます。セーブポイントを使用することで、トランザクションの原子性が緩和されます。セーブポイントを持つトランザクションは、トランザクションのコンテキスト外部では1つの単位のように見えるという点で原子的ですが、トランザクション内で動作しているコードは部分的な状態を維持することができます。
注意: セーブポイントがサポートされるのは、ローカル・トランザクションのみです。グローバル・トランザクション内でセーブポイントを指定すると、SQLException 例外が発生します。 |
セーブポイントを作成するには、java.sql.Savepoint
インスタンスを戻すConnection.setSavepoint
を使用します。
セーブポイントには名前がある場合とない場合があります。セーブポイントの名前を指定するには、setSavepoint
メソッドに文字列を指定します。名前が未指定の場合は、整数のIDが割り当てられます。名前の取出しにはgetSavepointName
メソッドを使用します。IDの取出しにはgetSavepointId
メソッドを使用します。
注意: 名前付けされていないセーブポイントから名前を取り出そうとしたり、名前付けされているセーブポイントからIDを取り出そうとしたりすると、SQLException 例外がスローされます。 |
セーブポイントまでロールバックするには、Connection.rollback(Savepoint svpt)
メソッドを使用します。解放されているセーブポイントまでロールバックしようとすると、SQLException
例外がスローされます。
使用中のデータベースでセーブポイントがサポートされているかどうかを調べるには、oracle.jdbc.OracleDatabaseMetaData.supportsSavepoints
メソッドをコールします。セーブポイントが使用可能な場合はtrue
、そうでない場合はfalse
が戻されます。
多くのデータベース・システムでは、行が挿入される際に一意のキー・フィールドが自動的に生成されます。Oracle Databaseでは、順序とトリガーにより、この機能が提供されます。JDBC 3.0には、自動生成キーの取出し機能が導入され、生成された値を取り出せるようになりました。JDBC 3.0では、自動生成キーの取出し機能をサポートするために、次のインタフェースが拡張されました。
java.sql.DatabaseMetaData
java.sql.Connection
java.sql.Statement
これらのインタフェースには、自動生成キーの取出しをサポートするメソッドが用意されています。ただし、この機能はINSERT
文が処理される場合にのみサポートされます。その他のデータ操作言語(DML)文の処理では、自動生成キーの取出しは実施されません。
注意: Oracleのサーバー側内部ドライバでは、自動生成キーの取出し機能をサポートしていません。 |
キー列を明示的に指定しないと、Oracle JDBCドライバでは取り出す列を特定できません。特定できるのは、列名または列索引の配列が使用されている場合です。ただし、int型のStatement.RETURN_GENERATED_KEYS
フラグが使用されている場合、Oracle JDBCドライバではこれらの列を特定できません。int型フラグを使用して自動生成キーが戻るように指定した場合は、ROWID
擬似列がキーとして戻ります。このROWID
は、ResultSet
オブジェクトからフェッチして、他の列を取り出すために使用できます。
次のコードは、自動生成キーの取出しを示しています。
/** SQL statements for creating an ORDERS table and a sequence for generating the * ORDER_ID. * * CREATE TABLE ORDERS (ORDER_ID NUMBER, CUSTOMER_ID NUMBER, ISBN NUMBER, * DESCRIPTION NCHAR(5)) * * CREATE SEQUENCE SEQ01 INCREMENT BY 1 START WITH 1000 */ ... String cols[] = {"ORDER_ID", "DESCRIPTION"}; // Create a PreparedStatement for inserting a row into the ORDERS table. OraclePreparedStatement pstmt = (OraclePreparedStatement) conn.prepareStatement("INSERT INTO ORDERS (ORDER_ID, CUSTOMER_ID, ISBN, DESCRIPTION) VALUES (SEQ01.NEXTVAL, 101, 966431502, ?)", cols); char c[] = {'a', '\u5185', 'b'}; String s = new String(c); pstmt.setNString(1, s); pstmt.executeUpdate(); ResultSet rset = pstmt.getGeneratedKeys(); ...
前の例では、シーケンス( SEQ01
)がORDER_ID
列の値を生成するために作成されます。値は、1000
から始まり、シーケンスが処理されて次の値が生成されるたびに1
ずつ増加します。OraclePreparedStatement
オブジェクトは、ORDERS
表に行を挿入するために作成されています。
表3-2と表3-3では、Oracle独自のメソッドとJDBC 3.0標準メソッドとの間の変換を示しています。
表3-2 等価のBLOBメソッド
Oracle独自のメソッド | JDBC 3.0標準メソッド |
---|---|
|
|
|
|
|
|
|
|
表3-3 等価のCLOBメソッド
Oracle独自のメソッド | JDBC 3.0標準メソッド |
---|---|
|
|
該当なし |
|
|
|
|
|
|
JDBC 4.0標準は、JDK 1.6以降のバージョンでサポートされています。Oracle Database 11gリリース2(11.2)のJDBCドライバでは、JDBC 4.0標準がサポートされています。
注意:
|
Oracle Database 11gリリース2(11.2)のJDBCドライバでは、次のような機能を利用できます。
ラッパー・パターンは、Javaアプリケーションで使用される一般的なコーディング・パターンで、データソース固有の従来のJDBC APIを超える機能を提供します。実際のリソースを表すプロキシ・クラス・インスタンスとしてラップされているリソースにアクセスする場合に、これらの拡張機能を使用する必要があることがあります。JDBC4.0では、リソース代理への直接アクセスを許可するために、プロキシによって表されるこれらのラップされたリソースにアクセスするための標準メカニズムを記述するWrapper
インタフェースが導入されています。
Wrapper
インタフェースでは、次の2つのメソッドが提供されています。
public boolean isWrapperFor(Class<?> iface) throws SQLException;
public <T> T unwrap(Class<T> iface) throws SQLException;
SQLデータを表すものを除く他のJDBC4.0インタフェースはすべてこのインタフェースを実装しています。これには、Connection
、Statement
とそのサブタイプ、ResultSet
およびメタデータ・インタフェースが含まれます。
JDBC 4.0標準で最も重要な更新内容の1つはSQL 2003標準で定義されたXMLデータ型のサポートです。現在、JDBCは、SQL/XMLデータベース・データ型 をサポートするためのマッピング・インタフェースを提供しています(java.sql.SQLXML
)。この新しいJDBCインタフェースは、XMLの、Javaネイティブのバインディングを定義し、それにより、データベースXMLデータの処理をより簡単、より効率的にしています。
注意:
|
java.sql.Connection
インタフェースでcreateSQLXML
メソッドをコールすることによって、XMLのインスタンスを作成することができます。このメソッドは、空のXMLオブジェクトを戻します。
次に示すように、PreparedStatement
、CallableStatement
およびResultSet
インタフェースは拡張され、適切なgetterメソッドとsetterメソッドが用意されました。
PreparedStatement
: メソッドsetSQLXML
が追加されました。
CallableStatement
: メソッドgetSQLXML
およびsetSQLXML
が追加されました。
ResultSet
: メソッドgetSQLXML
が追加されました。
oracle.jdbc.getObjectReturnsXMLTypeプロパティ
Oracle Database 10gと、Oracle Database 11gの初期バージョンでは、Oracle JDBCドライバは、Oracleの独自規格の拡張機能を介してOracle SQL XML型(XMLType)をサポートしていました。XML値はoracle.xdb.XMLType
クラスのインスタンスによって表され、SQL XMLType値はJDBC標準のgetObject
、setObject
およびupdateObject
の各メソッドを介して読取りと、設定が行われていました。
JDBC標準では、SQL XML型の列でコールされた場合、java.sql.SQLXML
型のインスタンスを戻すことを、getObject
メソッドに求めています。しかし、旧バージョンのOracle JDBCドライバでは、oracle.xdb.XMLType
のインスタンスが戻されます。これは、JDBC標準に準拠していません。
Oracle JDBCドライバの現在のリリースでは新しい接続プロパティ( oracle.jdbc.getObjectReturnsXMLType
)が導入され、JDBC標準に準拠しています。このプロパティをfalse
に設定すると、getObject
メソッドはjava.sql.SQLXML
型のインスタンスを戻します。そうするには、javac
でプログラムをコンパイルする際に次のコマンドライン・オプションを使用します。
-Doracle.jdbc.getObjectReturnsXMLType="false"
oracle.xdb.XMLType
を使用する既存のOracle独自規格のSQL XMLTypeサポートに依存している場合、次のコマンドライン・オプションを使用することにより、このプロパティの値をtrue
に戻すことができます。
-Doracle.jdbc.getObjectReturnsXMLType="true"
oracle.jdbc.getObjectReturnsXMLType
プロパティの値は、true
またはfalse
のブール値を表すString
です。このプロパティの値がtrue
の場合、getObject
メソッドは、SQL XMLTypeの列に対してコールされるとoracle.xdb.XMLType
インスタンスを戻します。これが、oracle.jdbc.getObjectReturnsXMLType
プロパティのデフォルト値です。このプロパティの値がfalse
の場合、getObject
メソッドはjava.sql.SQLXML
インスタンスを戻します。これは、標準のJDBC準拠モードです。
注意: oracle.jdbc.getObjectReturnsXMLType プロパティは、getObject メソッドの結果のみに影響を及ぼします。他のメソッドはすべて、プロパティの値に関係なく、標準のJDBC 4.0に準拠します。 |
例
例3-1 SQLXMLデータへのアクセス
次の例は、String
からXMLのインスタンスを作成し、データベースにXMLデータを書き込み、データベースからXMLデータを取得する方法を示しています。
import java.sql.*; import java.util.Properties; import oracle.jdbc.pool.OracleDataSource; public class SQLXMLTest { public static void main(String[] args) { Connection conn = null; Statement stmt = null; ResultSet rs = null; PreparedStatement ps = null; String xml = "<?xml version=\"1.0\"?>\n" + "<oldjoke>\n" + "<burns>Say <quote>goodnight</quote>, Gracie.</burns>\n" + "<allen><quote>Goodnight, Gracie.</quote></allen>\n" + "<applause/>\n" + "</oldjoke>"; try { OracleDataSource ods = new OracleDataSource(); ods.setURL("jdbc:oracle:thin:@//localhost:1521/orcl"); ods.setUser("scott"); ods.setPassword("tiger"); conn = ods.getConnection(); ps = conn.prepareStatement("insert into x values (?, ?)"); ps.setString(1, "string to string"); SQLXML x = conn.createSQLXML(); x.setString(xml); ps.setSQLXML(2, x); ps.execute(); x.free(); stmt = conn.createStatement(); rs = stmt.executeQuery("select * from x"); while (rs.next()) { System.out.println(rs.getString(1) + "\n" + rs.getSQLXML(2).getString()); } rs.close(); ps.close(); } catch (SQLException e){e.printStackTrace ();} } }
注意: 空のXMLを指定してsetterメソッドをコールすると、SQLException がスローされます。getterメソッドが空のXMLを戻すことはありません。 |
JDBC 3.0では、SQLException
という単一の例外しかサポートされていません。ただし、エラーはカテゴリが多いので、区別すると便利です。この機能では、様々なカテゴリのエラーを特定するために、SQLException
クラスのサブクラスがサポートされています。永続エラーと一時エラーの切分けが、主要な切分けになります。永続エラーは、システムの正しい動作の結果であり、常に発生します。一時エラーは、タイムアウトなど、システムの一部で障害が発生した結果であり、再発しない場合もあります。
JDBC 4.0では、一時エラー、永続エラーおよびそれらエラーの様々なカテゴリを表現するために、例外が追加されています。
また、SQLException
クラスとそのサブクラスは、J2SE関連の例外機能をサポートするために機能拡張されています。
JDBC 4.0では、SQLのROWID
値を表現するために、java.sql.RowId
データ型がサポートされています。ResultSet
インタフェースおよびCallableStatement
インタフェースで定義されているgetterメソッドを使用すると、RowId
値を取り出すことができます。開発者は、パラメータ化されたPreparedStatement
の中でRowId
値を使用して、RowId
オブジェクトのパラメータを設定したり、更新可能な結果セットの中で使用して、列を特定のRowId
値に更新したりできます。
RowId
オブジェクトは、指定された行が削除されるまで有効です。RowId
オブジェクトは、次の場合にも有効なことがあります。
作成元トランザクションの期間中。
作成元セッションの期間中。
RowIdオブジェクトが永続的に有効である期間(未定義)。
DatabaseMetaData.getRowIdLifetime
メソッドをコールすると、RowIDオブジェクトの存続期間を確認できます。
JDBC 4.0では、BLOB
、CLOB
およびNCLOB
オブジェクトの作成をサポートするために、Connection
インタフェースが機能拡張されています。このインタフェースでサポートされているcreateBlob
、createClob
およびcreateNClob
メソッドを使用すると、Blob
、Clob
およびNClob
オブジェクトを作成できます。
作成されたLOB(Large OBject)にデータは含まれません。java.sql.Blob
、java.sql.Clob
およびjava.sql.NClob
インタフェースで使用可能なAPIをコールして、これらのオブジェクトにデータを追加または取得できます。これらのオブジェクトからは、内容の全体または一部を取り出すことができます。次のコードでは、BLOB
オブジェクトのオフセット200の位置から100バイトのデータを取り出す方法を示しています。
... Connection con = DriverManager.getConnection(url, props); Blob aBlob = con.createBlob(); // Add data to the BLOB object. aBlob.setBytes(...); ... // Retrieve part of the data from the BLOB object. InputStream is = aBlob.getBinaryStream(200, 100); ...
setBlob
、setClob
およびsetNClob
メソッドを使用して、PreparedStatement
オブジェクトにLOBを入力パラメータとして渡すこともできます。updateBlob
、updateClob
およびupdateNClob
メソッドを使用すると、更新可能結果セット内の列値を更新できます。
これらのLOBは一時LOBで、一時LOBを使用する必要がある場合に使用します。データベース内の記憶域を永続的にするには、これらのLOBを表に書き込む必要があります。
一時LOBは、作成元のトランザクションの期間中は少なくとも有効です。ただし、トランザクションの実行期間が長いと、メモリーの使用が保証されない場合があります。次のようにLOBのfree
メソッドをコールすると、LOBを解放できます。
... Clob aClob = con.createClob(); int numWritten = aClob.setString(1, val); aClob.free(); ...
JDBC 4.0では、各国語キャラクタ・セットの型にアクセスするためのNCHAR
、NVARCHAR
、LONGNVARCHAR
およびNCLOB
というJDBC型が導入されています。これらの型は、各国語キャラクタ・セットを使用して値がエンコードされる点を除き、CHAR
、VARCHAR
、LONGVARCHAR
およびCLOB
型に類似しています。