日本語PDF

3 JDBC標準のサポート

Oracle Java Database Connectivity(JDBC)ドライバは、様々なバージョンのJDBC標準機能をサポートしています。Oracle Database 12cリリース2 (12.2.0.1)では、Oracle JDBCドライバが強化され、JDBC 4.1標準がサポートされました。これらの機能は、oracle.jdbcパッケージとoracle.sqlパッケージによって提供されます。これらのパッケージでは、Java Development Kit(JDK)リリース8がサポートされています。この章では、Oracle JDBCドライバでのJDBC標準のサポートについて説明します。内容は次のとおりです。

3.1 JDBC 2.0標準のサポート

今回のリリースのOracle JDBCドライバでは、JDK 1.2以降のバージョンを介してJDBC 2.0機能がサポートされています。考慮すべき点が3つあります。

  • オブジェクト、配列およびラージ・オブジェクト(LOB)などのデータ型のサポート。これはjava.sqlパッケージを介して処理されます。

  • 結果セットの拡張およびバッチ更新などの標準機能のサポート。これは、JDK 1.2.x以降でConnectionResultSetおよびPreparedStatementなどの標準オブジェクトを介して処理されます。

  • JDBC 2.0 Optional Packageの機能など、Standard Extension Application Program Interface(API)とも呼ばれる拡張機能に対するサポート。たとえばデータソース、接続プーリングおよび分散トランザクションなどがあげられます。

この項の内容は次のとおりです。

ノート:

5.0より前のJDKのバージョンは、もうサポートされていません。oracle.jdbc2パッケージは削除されました。

3.1.1 データ型のサポート

Oracle JDBCは、標準java.sqlパッケージ内のインタフェースの実装による標準JDBC 2.0機能を含む、JDK 6およびJDK 7を完全にサポートしています。これらのインタフェースは、oracle.sqlパッケージとoracle.jdbcパッケージ内のクラスによって、適宜実装されます。

3.1.2 標準機能のサポート

ojdbc6.jarのJDBCクラスを使用するJDK 6.0環境では、スクロール可能結果セット、更新可能結果セット、バッチ更新などのJDBC 2.0機能は、標準のJDBC 2.0インタフェースによって指定されたメソッドを介してサポートされます。

3.1.3 拡張機能のサポート

データソース、接続プーリングおよび分散トランザクションなどのJDBC 2.0 Optional Packageの各機能は、JDK 1.2.x以上の環境でサポートされます。

標準javax.sqlパッケージとそのインタフェースを実装するクラスは、Oracle Databaseでパッケージ化されたJavaアーカイブ(JAR)ファイルに格納されています。

3.1.4 JDBC2.0 Standard Extension APIとオラクル社独自のパフォーマンス強化API

フェッチ・サイズまたは行のプリフェッチは、以前はOracle拡張機能でしか使用できませんでしたが、現在はJDBC 2.0で使用できます。標準モデルまたはOracleモデルを使用するオプションがあります。可能なかぎりJDBC標準モデルの使用をお薦めします。ただし、この機能のために、1つのアプリケーション内で標準モデルとOracleモデルを同時に使用しないでください。

関連トピック

3.2 JDBC 3.0標準のサポート

Oracle Database 12cリリース1のJDBCドライバでは、JDK 1.4以降のバージョンを介して標準JDBC 3.0機能がサポートされています。次の表では、今回のリリースのOracle JDBCドライバでサポートしているJDBC 3.0機能と、各機能に関する詳細の参照先を示しています。

表3-1 JDBC 3.0機能の主な領域

機能 コメントと参照

トランザクションのセーブポイント

詳細は、トランザクション・セーブポイントの概要を参照してください。

文キャッシュ

接続プールによるプリペアド文の再利用「文キャッシュと結果セット・キャッシュ」を参照してください。

ローカル・トランザクションとグローバル・トランザクションの切替え

ローカル・トランザクションとグローバル・トランザクションの切替えについてを参照してください。

LOBの変更

JDBC 3.0のLOBインタフェース・メソッド JDBC 3.0のLOBインタフェース・メソッドを参照してください。

名前付きSQLパラメータ

Interface oracle.jdbc.OracleCallableStatementおよびInterface oracle.jdbc.OraclePreparedStatement Interface oracle.jdbc.OraclePreparedStatementを参照してください。

RowSet

「JDBC RowSet」を参照してください

自動生成キーの取出し

自動生成キーの取出し 自動生成キーの取出しを参照してください

結果セットの保持機能

結果セットの保持機能 結果セットの保持機能を参照してください

この項では、Oracle JDBCドライバによってサポートされている次のJDBC 3.0機能について説明します。

3.2.1 トランザクション・セーブポイントの概要

JDBC 3.0の仕様はセーブポイントをサポートしており、トランザクション内でより細かい境界設定をすることができます。アプリケーションはトランザクション内にセーブポイントを設定して、セーブポイントより後に行われたすべての作業をロールバックすることができます。セーブポイントを使用することで、トランザクションの原子性が緩和されます。セーブポイントを持つトランザクションは、トランザクションのコンテキスト外部では1つの単位のように見えるという点で原子的ですが、トランザクション内で動作しているコードは部分的な状態を維持することができます。

ノート:

セーブポイントがサポートされるのは、ローカル・トランザクションのみです。グローバル・トランザクション内でセーブポイントを指定すると、SQLException例外が発生します。

3.2.1.1 セーブポイントの作成について

セーブポイントを作成するには、java.sql.Savepointインスタンスを戻すConnection.setSavepointを使用します。

セーブポイントには名前がある場合とない場合があります。セーブポイントの名前を指定するには、setSavepointメソッドに文字列を指定します。名前が未指定の場合は、整数のIDが割り当てられます。名前の取出しにはgetSavepointNameメソッドを使用します。IDの取出しにはgetSavepointIdメソッドを使用します。

ノート:

名前付けされていないセーブポイントから名前を取り出そうとしたり、名前付けされているセーブポイントからIDを取り出そうとしたりすると、SQLException例外がスローされます。

3.2.1.2 セーブポイントまでのロールバックについて

セーブポイントまでロールバックするには、Connection.rollback(Savepoint svpt)メソッドを使用します。解放されているセーブポイントまでロールバックしようとすると、SQLException例外がスローされます。

3.2.1.3 セーブポイントの解放について

セーブポイントを削除するには、Connection.releaseSavepoint(Savepoint svpt)メソッドを使用します。

3.2.1.4 セーブポイント・サポートのチェックについて

使用中のデータベースでセーブポイントがサポートされているかどうかを調べるには、oracle.jdbc.OracleDatabaseMetaData.supportsSavepointsメソッドをコールします。セーブポイントが使用可能な場合はtrue、そうでない場合はfalseが戻されます。

3.2.1.5 セーブポイントに関するノート

セーブポイントを使用する場合は、次の点に注意する必要があります。

  • セーブポイントの解放後、ロールバック操作でそのセーブポイントを参照しようとすると、SQLException例外がスローされます。

  • トランザクションがコミットまたはロールバックされると、そのトランザクション内の作成済セーブポイントはすべて自動的に解放され、無効になります。

  • あるセーブポイントまでトランザクションをロールバックすると、そのセーブポイントより後に作成されたセーブポイントはすべて自動的に解放され、無効になります。

3.2.2 自動生成キーの取出し

多くのデータベース・システムでは、行が挿入される際に一意のキー・フィールドが自動的に生成されます。Oracle Databaseでは、順序とトリガーにより、この機能が提供されます。JDBC 3.0には、自動生成キーの取出し機能が導入され、生成された値を取り出せるようになりました。JDBC 3.0では、自動生成キーの取出し機能をサポートするために、次のインタフェースが拡張されました。

  • java.sql.DatabaseMetaData

  • java.sql.Connection

  • java.sql.Statement

これらのインタフェースには、自動生成キーの取出しをサポートするメソッドが用意されています。ただし、この機能はINSERT文が処理される場合にのみサポートされます。その他のデータ操作言語(DML)文の処理では、自動生成キーの取出しは実施されません。

ノート:

Oracleのサーバー側内部ドライバでは、自動生成キーの取出し機能をサポートしていません。

3.2.2.1 java.sql.Statement

キー列を明示的に指定しないと、Oracle JDBCドライバでは取り出す列を特定できません。Oracle JDBCドライバで自動生成キーを含む列を特定できるのは、列名または列索引の配列が使用されている場合です。ただし、int型のStatement.RETURN_GENERATED_KEYSフラグが使用されている場合、Oracle JDBCドライバではこれらの列を特定できません。int型フラグを使用して自動生成キーが戻るように指定した場合は、ROWID擬似列がキーとして戻ります。このROWIDは、ResultSetオブジェクトからフェッチして、他の列を取り出すために使用できます。

3.2.2.2 サンプル・コード

次のコードは、自動生成キーの取出しを示しています。

/** 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.2.3 自動生成キーの制約

自動生成キーはDML RETURNING句を使用して実装されます。したがって、getGeneratedKeysメソッドから戻されるResultSetオブジェクトには位置によってのみアクセスする必要があります。ResultSetオブジェクトの列としてはバインド変数名を使用しないでください。

3.2.3 JDBC 3.0のLOBインタフェース・メソッド

次の表では、Oracle独自のメソッドとJDBC 3.0標準メソッドとの間の変換を示しています。

表3-2 等価のBLOBメソッド

Oracle独自のメソッド JDBC 3.0標準メソッド

putBytes(long pos, byte [ ] bytes)

setBytes(long pos, byte[] bytes)

putBytes(long pos, byte [ ] bytes, int length)

setBytes(long pos, byte[] bytes, int offset, int len)

getBinaryOutputStream(long pos)

setBinaryStream(long pos)

trim (long len)

truncate(long len)

表3-3 等価のCLOBメソッド

Oracle独自のメソッド JDBC 3.0標準メソッド

putString(long pos, String str)

setString(long pos, String str)

該当なし

setString(long pos, String str, int offset, int len)

getAsciiOutputStream(long pos)

setAsciiStream(long pos)

getCharacterOutputStream(long pos)

setCharacterStream(long pos)

trim (long len)

truncate(long len)

3.2.4 結果セットの保持機能

結果セットの保持機能は、JDBC 3.0から導入されました。この機能は、コミット操作が実行されるとき、ResultSetオブジェクトがオープンされているべきか、クローズされているべきかをアプリケーションが判断できるようにします。コミット操作は暗黙的でも明示的でもかまいません。

Oracle Databaseでサポートしているのは、HOLD_CURSORS_OVER_COMMITのみです。したがって、これが、Oracle JDBCドライバのデフォルト値です。保持機能を変更しようとすると必ず、SQLFeatureNotSupportedException例外がスローされます。

3.3 JDBC 4.0標準のサポート

Oracle Databaseリリース18cのJDBCドライバでは、JDBC 4.0標準がサポートされています。

ノート:

JDBC 4.0仕様では、java.sql.Arrayオブジェクトを作成するjava.sql.Connection.createArrayOfファクトリ・メソッドが定義されています。createArrayOfメソッドは配列要素型の名前を引数の1つに取ります。ここで、配列のタイプは匿名です。Oracle Databaseでは、匿名の配列型でなく、名前付きの配列型のみがサポートされます。したがって、現在のリリースのOracle JDBCドライバはcreateArrayOfメソッドをサポートしていません。配列型を作成するには、Oracle固有のcreateARRAYメソッドを使用する必要があります。

関連項目:

Oracle Databaseリリース18cのJDBCドライバでは、次のような機能を利用できます。

3.3.1 ラッパー・パターンのサポート

ラッパー・パターンは、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インタフェースはすべてこのインタフェースを実装しています。これには、ConnectionStatementとそのサブタイプ、ResultSetおよびメタデータ・インタフェースが含まれます。

3.3.2 SQLXML型

JDBC 4.0標準で最も重要な更新内容の1つはSQL 2003標準で定義されたXMLデータ型のサポートです。現在、JDBCは、SQL/XMLデータベース・データ型をサポートするためのマッピング・インタフェースを提供しています(java.sql.SQLXML)。この新しいJDBCインタフェースは、XMLの、Javaネイティブのバインディングを定義し、それにより、データベースXMLデータの処理をより簡単、より効率的にしています。

ノート:

  • また、SQLXML型のデータを使用するには、classpath環境変数にxdb6.jarファイルとxmlparserv2.jarファイルを指定する必要があります(classpathにすでに指定されている場合を除く)。

  • SQLXMLは、CachedRowsetオブジェクトではサポートされません。

java.sql.ConnectionインタフェースでcreateSQLXMLメソッドをコールすることによって、XMLのインスタンスを作成することができます。このメソッドは、空のXMLオブジェクトを戻します。

次に示すように、PreparedStatementCallableStatementおよびResultSetインタフェースは拡張され、適切なgetterメソッドとsetterメソッドが用意されました。

  • PreparedStatement: メソッドsetSQLXMLが追加されました。

  • CallableStatement: メソッドgetSQLXMLおよびsetSQLXMLが追加されました。

  • ResultSet: メソッドgetSQLXMLが追加されました。

ノート:

Oracle Database 10gと、Oracle Database 11gの初期バージョンでは、Oracle JDBCドライバは、Oracleの独自規格の拡張機能を介してOracle SQL XML型(XMLType)をサポートしていました。これは、JDBC標準に準拠していませんでした。

11.2.0.2のOracle JDBCドライバでは新しい接続プロパティ(oracle.jdbc.getObjectReturnsXMLType)が導入され、JDBC標準に準拠しています。このプロパティにfalseを設定した場合、getObjectメソッドはjava.sql.SQLXMLのデータ型のインスタンスを戻し、oracle.xdb.XMLTypeを使用する既存のOracle独自規格のSQL XMLTypeサポートに依存している場合、このプロパティの値をtrueに戻すことができます。

ただし、getObjectReturnsXMLTypeプロパティの設定は、現在のバージョンのOracle JDBCドライバでは必要ありません。

例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:5221/orcl");
     ods.setUser("HR");
     ods.setPassword("hr");
     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();
     stmt = conn.createStatement();
     rs = stmt.executeQuery("select * from x");
     while (rs.next()) 
     {
       x = rs.getSQLXML(2);
       System.out.println(rs.getString(1) + "\n" + rs.getSQLXML(2).getString());
       x.free();
     }
 
     rs.close();
     ps.close();    
  }
 
  catch (SQLException e){e.printStackTrace ();}
 
  }
}

ノート:

空のXMLを指定してsetterメソッドをコールすると、SQLExceptionがスローされます。getterメソッドが空のXMLを戻すことはありません。

3.3.3 機能拡張された例外階層とSQLException

JDBC 3.0では、SQLExceptionという単一の例外しかサポートされていません。ただし、エラーはカテゴリが多いので、区別すると便利です。この機能では、様々なカテゴリのエラーを特定するために、SQLExceptionクラスのサブクラスがサポートされています。永続エラーと一時エラーの切分けが、主要な切分けになります。永続エラーは、システムの正しい動作の結果であり、常に発生します。一時エラーは、タイムアウトなど、システムの一部で障害が発生した結果であり、再発しない場合もあります。

JDBC 4.0では、一時エラー、永続エラーおよびそれらエラーの様々なカテゴリを表現するために、例外が追加されています。

また、SQLExceptionクラスとそのサブクラスは、J2SE関連の例外機能をサポートするために機能拡張されています。

3.3.4 ROWIDデータ型

JDBC 4.0では、SQLのROWID値を表現するために、java.sql.RowIdデータ型がサポートされています。ResultSetインタフェースおよびCallableStatementインタフェースで定義されているgetterメソッドを使用すると、RowId値を取り出すことができます。開発者は、パラメータ化されたPreparedStatementの中でRowId値を使用して、RowIdオブジェクトのパラメータを設定したり、更新可能な結果セットの中で使用して、列を特定のRowId値に更新したりできます。

RowIdオブジェクトは、指定された行が削除されるまで有効です。RowIdオブジェクトは、次の場合にも有効なことがあります。

  • 作成元トランザクションの期間中。

  • 作成元セッションの期間中。

  • 永続的に有効である期間(未定義)。

DatabaseMetaData.getRowIdLifetimeメソッドをコールすると、RowIDオブジェクトの存続期間を確認できます。

3.3.5 LOBの作成

JDBC 4.0では、BLOBCLOBおよびNCLOBオブジェクトの作成をサポートするために、Connectionインタフェースが機能拡張されています。このインタフェースでサポートされているcreateBlobcreateClobおよびcreateNClobメソッドを使用すると、BlobClobおよびNClobオブジェクトを作成できます。

作成されたLOB(Large OBject)にデータは含まれません。java.sql.Blobjava.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);
...

setBlobsetClobおよびsetNClobメソッドを使用して、PreparedStatementオブジェクトにLOBを入力パラメータとして渡すこともできます。updateBlobupdateClobおよびupdateNClobメソッドを使用すると、更新可能結果セット内の列値を更新できます。

これらのLOBは一時LOBで、一時LOBを使用する必要がある場合に使用します。データベース内の記憶域を永続的にするには、これらのLOBを表に書き込む必要があります。

関連項目:

一時LOBの使用について

一時LOBは、作成元のトランザクションの期間中は少なくとも有効です。ただし、トランザクションの実行期間が長いと、メモリーの使用が保証されない場合があります。次のようにLOBのfreeメソッドをコールすると、LOBを解放できます。

...
Clob aClob = con.createClob();
int numWritten = aClob.setString(1, val);
aClob.free();
...

3.3.6 各国語文字セットのサポート

JDBC 4.0では、各国語文字セットの型にアクセスするためのNCHARNVARCHARLONGNVARCHARおよびNCLOBというJDBC型が導入されています。これらの型は、各国語文字セットを使用して値がエンコードされる点を除き、CHARVARCHARLONGVARCHARおよびCLOB型に類似しています。

3.4 JDBC 4.1標準のサポート

Oracle Database 12cリリース1のJDBCドライバでは、JDK 7を介してJDBC 4.1標準がサポートされています。この項では、JDBC 4.1仕様の次の重要なメソッドについて説明します。

3.4.1 setClientInfoメソッド

データベース・リソースの消費の監視については、setClientInfoメソッドを使用して、指定した時点にデータベースを使用する様々なアプリケーション・タスクを識別できます。setClientInfoメソッドは、様々なアプリケーション情報を提供するプロパティの値を設定します。このメソッドは、<namespace>.<keyname>の形式のキーを受け入れます。たとえば、次のコードに示すようにsetClientInfoメソッドを使用してACTIONキー、MODULEキーおよびCLIENTIDキー(V$SESSIONビューおよび多くのパフォーマンス・ビューにあり、トレース・ファイルでレポート可能)を使用できます。

// "conn" is an instance of java.sql.Connection:
conn.setClientInfo("OCSID.CLIENTID", "Alice_HR_Payroll");
conn.setClientInfo("OCSID.MODULE", "APP_HR_PAYROLL");
conn.setClientInfo("OCSID.ACTION", "PAYROLL_REPORT");

setClientInfoメソッドでは、Java権限oracle.jdbc.clientInfoをチェックします。このセキュリティ・チェックが失敗した場合、SecurityExceptionがスローされます。これは、<namespace>.*の形式の権限の名前パターンをサポートしています。setClientInfoメソッドはすべてのペアの設定またはクリアを行います。したがって、権限の名前にアスタリスク(*)を設定する必要があります。

JDBCドライバでは、<namespace>.<keyname>の組合せをサポートしています。setClientInfoメソッドでは、他のネームスペースではOCSIDネームスペースをサポートしています。ただし、OCSIDネームスペースと他のネームスペースの使用方法には違いがあります。OCSIDネームスペースの場合、setClientInfoメソッドでは次のキーのみをサポートしています。

  • ACTION

  • CLIENTID

  • ECID

  • MODULE

  • SEQUENCE_NUMBER

  • DBOP

また、他のネームスペースに関連付けられた情報は単一のプロトコルを使用してネットワークで通信されますが、OCSIDネームスペースに関連付けられた情報は別のプロトコルを使用して通信されます。OCSIDネームスペースに使用されるプロトコルは、エンドツーエンドのメトリック値を送信するために、OCI Cライブラリと10gのJDBC Thinドライバおよび以降のThinドライバでも使用されます。

ノート:

  • setClientInfoメソッドはsetEndToEndMetricsおよびsetClientIdentifierメソッドとの下位互換性があり、DMSを使用してクライアント・タグを設定できます。

  • setEndToEndMetricsメソッドは、Oracle Database 12cリリース1 (12.1)では非推奨になりました。

データベース操作の監視について

多くのJavaアプリケーションにはデータベース接続機能がありませんが、その機能のかわりにデータベース・アクティビティを追跡する必要があります。このようなアプリケーションのために、Oracle Database 12cリリース1 (12.1)では、DBOPタグが導入されました。これは、アプリケーションがデータベースに明示的にアクセスできない場合に、アプリケーションのスレッドに関連付けることができます。DBOPタグは、DMS APIを起動してスレッドと関連付けられます。データベースへのアクティブな接続は不要です。スレッドが次のデータベース・コールを送信したとき、DMSはデータベース・コールとともに接続を介してこれらのタグを伝播します。追加のラウンドトリップの必要はありません。このように、アプリケーションは、アプリケーション・レイヤーのコードを分析しながら、そのアクティビティをデータベースの動作に関連付けることができます。DBOPタグは次の項目で構成されています。

  • データベースの動作の名前

  • 実行ID

  • 動作属性

setClientInfoメソッドでは、DBOPタグをサポートしています。setClientInfoメソッドは、データベース動作を監視するために、このタグの値を設定します。JDBCアプリケーションがデータベースに接続し、データベース・ラウンドトリップが行われると、データベース・アクティビティを追跡できます。たとえば、次のようにDBOPタグの値にfooを設定できます。

...
Connection conn = DriverManager.getConnection(myUrl, myUsername, myPassword);
conn.setClientInfo("E2E_CONTEXT.DBOP", "foo");
Statement stmt = conn.createStatement();
stmt.execute("select 1 from dual");  // DBOP tag is set after this
...

3.4.2 getObjectメソッド

getObjectメソッドは、渡されたパラメータに基づいて、オブジェクトを取得します。Oracle Database 12cリリース2 (12.2.0.1)では、次の2つの新規getObjectメソッドをサポートしています。

メソッド1

<T> T getObject(int parameterIndex,
                java.lang.Class<T> type)
            throws SQLException

メソッド2

<T> T getObject(java.lang.String parameterName,
                java.lang.Class<T> type)
            throws SQLException

これらのメソッドでは、JDBC仕様に示された変換と表A-1に示された追加の変換をサポートしています。Oracle Database 12cリリース2 (12.2.0.1)のドライバでは、一部の追加クラスへの変換もサポートしています。これは、次の条件のいずれかが満たされている場合、1つ以上の静的なvalueOfメソッドを実装しています。

  • JDBC仕様または表A-1の他の変換が指定されていない。

  • type引数で、valueOfという名前の単一のパブリックで静的な引数メソッドを1つ以上定義している。

  • 1つ以上のvalueOfメソッドがJDBC仕様または表A-1のためにサポートされている型の値である引数を取る。

今回のリリースのJDBCドライバは、JDBC仕様または表A-1で指定された型に値を変換してから、変換した値を引数として、対応するvalueOfメソッドをコールします。適切なvalueOfメソッドが複数ある場合、JDBCドライバはvalueOfメソッドを1つ選択します。この方法は指定されていません。

ResultSet rs = . . . ;
Character c = rs.getObject(1, java.lang.Character.class);

Characterクラスは、次のvalueOfメソッドを定義します。

public static Character valueOf(char c);

表A-1では、NUMBERcharに変換できることが示されています。したがって、ResultSetの最初の列がNUMBERである場合、getObjectメソッドはそのNUMBER値をcharに変換し、そのchar値をvalueOf(char)メソッドに渡し、結果のCharacterオブジェクトを戻します。

3.5 JDBC 4.2標準のサポート

Oracle Database 12cリリース2 (12.2.0.1)のJDBCドライバでは、JDK 8を介してJDBC 4.2標準がサポートされています。この項では、今回のリリースに追加された重要なメソッドの一部について説明します。

%Large%メソッド

今回のリリースのOracle JDBCドライバでは、long値に対応する、JDBC 4.2標準で導入された次のメソッドがサポートされています。

  • executeLargeBatch()

  • executeLargeUpdate(String sql)

  • executeLargeUpdate(String sql, int autoGeneratedKeys)

  • executeLargeUpdate(String sql, int[] columnIndexes)

  • executeLargeUpdate(String sql, String[] columnNames)

  • getLargeMaxRows()

  • getLargeUpdateCount()

  • setLargeMaxRows(long max)

これらの新しいメソッドは、java.sql.Statementインタフェースの一部として使用できます。%Large%メソッドは、int値のかわりにlong値を使用すること以外は、対応するnon-largeメソッドと同様です。たとえば、executeUpdateメソッドはint値として更新された行数を戻しますが、executeLargeUpdateメソッドはlong値として更新された行数を戻します。行数がInteger.MAX_VALUEの値より大きい場合、アプリケーションではexecuteLargeUpdateメソッドを使用する必要があります。

次のコードでは、executeLargeUpdate(String sql)メソッドを使用する方法を示します。

...
Statement stmt = conn.createStatement();
stmt.executeQuery("create table BloggersData (FIRST_NAME varchar(100), ID int)");
long updateCount = stmt.executeLargeUpdate("insert into BloggersData (FIRST_NAME,ID) values('John',1)");
...

SQLTypeメソッド

今回のリリースのOracle JDBCドライバでは、SQLTypeパラメータを使用する、JDBC 4.2標準で導入された次のメソッドがサポートされています。

  • setObject

    setObjectメソッドでは、指定したオブジェクトに指定したパラメータの値を設定します。このメソッドは、setObject(int parameterIndex, Object x, SQLType targetSqlType, int scaleOrLength)に似ていますが、scaleに0を仮定している点が異なります。このメソッドのデフォルト実装はSQLFeatureNotSupportedExceptionをスローします。

    void setObject(int parameterIndex, java.lang.Object x, SQLType targetSqlType) throws SQLException       
               

    ここで、

    parameterIndexは指定されたパラメータの索引で、最初のパラメータは1、2番目のパラメータは2のようになります

    xは、入力パラメータ値を含むオブジェクトです

    targetSqlTypeは、データベースに送られるSQL型です

  • updateObject

    updateObjectメソッドでは、パラメータとして列索引を使用し、指定した列をオブジェクト値で更新します。

  • registerOutParameter

    registerOutParameterメソッドでは、JDBC型をSQLTypeとするように指定したパラメータを登録します。

次のコードでは、setObjectメソッドを使用する方法を示します。

... 
int empId = 100;
connection.prepareStatement("SELECT FIRST_NAME, LAST_NAME FROM EMPLOYEES WHERE EMPNO = ?");
preparedStatement.setObject(1, Integer.valueOf(empId), OracleType.NUMBER);
...