ヘッダーをスキップ
Oracle Database JDBC開発者ガイドおよびリファレンス
11gリリース1(11.1)
E05720-02
  目次
目次
索引
索引

戻る
戻る
次へ
次へ
 

15 Oracleオブジェクト参照の使用

この章では、オブジェクト参照へのアクセスおよび操作を行う、標準Java Database Connectivity(JDBC)に対するOracle拡張機能について説明します。次の項目が含まれます。

オブジェクト参照用Oracle拡張機能

Oracleでは、データベース・オブジェクトへの参照を使用できます。Oracle JDBCでは、次のオブジェクト参照がサポートされます。

SQLでは、オブジェクト参照(REF)は厳密に型指定されています。たとえば、EMPLOYEEオブジェクトへの参照は、REFのみではなく、EMPLOYEE REFとして定義されます。

Oracle JDBCでオブジェクト参照を選択するときには、オブジェクトそのものではなく、オブジェクトへのポインタのみが取り出されることに注意してください。参照は、弱い型指定のoracle.sql.REFインスタンス、または移植性の高いjava.sql.Refインスタンスとしてインスタンス化することも、強い型指定の作成済カスタムJavaクラスのインスタンスとしてインスタンス化することもできます。オブジェクト参照に使用するカスタムJavaクラスを、カスタム参照クラスと呼びます。このクラスは、oracle.sql.ORADataインタフェースを実装する必要があります。oracle.sql.REFクラスは、標準のjava.sql.Refインタフェースを実装します。

REFインスタンスは、結果セットまたはコール可能文オブジェクトから取り出せます。更新されたREFインスタンスは、プリコンパイルされたSQL文またはコール可能文オブジェクトで、データベースに戻せます。REFクラスには、基礎となるオブジェクト属性値を取り出して設定する機能や、基礎となるオブジェクトのSQLベース型名を取り出す機能が含まれています。

カスタム参照クラスには、これと同じ機能が含まれている他に、強い型指定が適用されるという利点があります。この強い型指定により、実行時まで検出できないコーディング・エラーを、コンパイル時に発見できます。


注意:

  • カスタム・オブジェクト・クラスに対してoracle.sql.ORADataインタフェースを使用する場合は、対応するカスタム参照クラスにもORADataを使用します。ただし、カスタム・オブジェクト・クラスに対して標準java.sql.SQLDataインタフェースを使用する場合、参照に使用できるのは、弱いJava型のみです。SQLDataインタフェースは、SQLオブジェクト型のマッピング専用です。

  • JDBCアプリケーションでREFオブジェクトを作成して取り出すことができるのは、SQL文を実行した場合のみです。REFオブジェクトを作成して取り出すためのJDBC固有の機能はありません。

  • 配列はオブジェクトの同様に構造化型ですが、参照できません。


オブジェクト参照機能の概要

オブジェクト参照からオブジェクト・データにアクセスし、更新するには、結果セットまたはコール可能文から参照インスタンスを取出し、プリコンパイルされたSQL文またはコール可能文のバインド変数に渡す必要があります。オブジェクト属性へのアクセスおよび更新を行う機能は、参照インスタンスに含まれています。

この項には、次の項目が含まれます。

オブジェクト参照getterおよびsetterメソッド

結果セット、コール可能文およびプリコンパイルされたSQL文のメソッドを使用して、オブジェクト参照の取出しおよび引渡しができます。

結果セットおよびコール可能文のgetterメソッド

OracleResultSetおよびOracleCallableStatementクラスは、REFオブジェクトを出力パラメータとして取り出すgetREFおよびgetRefメソッドをサポートします。REFオブジェクトは、oracle.sql.REFインスタンスまたはjava.sql.Refインスタンスとして取り出すことができます。getObjectメソッドも使用できます。これらのメソッドは、入力としてString列名またはint列索引を取ります。

プリコンパイルされたSQL文およびコール可能文のsetterメソッド

OraclePreparedStatementおよびOracleCallableStatementクラスは、REFオブジェクトをバインド変数として取り、データベースに渡す、setREFおよびsetRefメソッドをサポートします。setObjectメソッドも使用できます。これらのメソッドは、入力としてStringパラメータ名またはintパラメータ索引を取ります。同時に、oracle.sql.REFインスタンスまたはjava.sql.Refインスタンスも取ります。

主要なREFクラス・メソッド

次のoracle.sql.REFクラス・メソッドを使用して、SQLオブジェクト型名の取出しや、基礎となるオブジェクト・データの取出しおよび引渡しを行います。

  • getBaseTypeName

    参照オブジェクトの完全修飾SQL構造化型名を取り出します。これは、java.sql.Refインタフェースで指定される標準メソッドです。

  • getValue

    参照オブジェクトをデータベースから取り出し、属性値にアクセスできるようにします。オプションで、型マップ・オブジェクトを取ることができます。また、データベース接続オブジェクトのデフォルト型マップを使用できます。このメソッドはOracle拡張機能です。

  • setValue

    参照オブジェクトをデータベースに設定し、属性値を更新できるようにします。入力として、オブジェクト型のインスタンス(STRUCTインスタンスまたはカスタム・オブジェクト・クラスのインスタンス)を取ります。このメソッドはOracle拡張機能です。

オブジェクト参照の取出しと引渡し

この項では、オブジェクト参照の取出しと引渡しを行うJDBC機能を説明します。次の項目が含まれます。

結果セットからのオブジェクト参照の取出し

オブジェクト参照を取り出す方法を示すために、次の例では、最初に、Oracleオブジェクト型ADDRESSを定義し、次にPEOPLE表でこのオブジェクト型を参照します。

create type ADDRESS as object
   (street_name     VARCHAR2(30),
    house_no        NUMBER);

create table PEOPLE
    (col1 VARCHAR2(30),
     col2 NUMBER,
     col3 REF ADDRESS);

ADDRESSオブジェクト型には、street nameとhouse numberという2つの属性があります。PEOPLE表には、文字データ用の列、数値データ用の列、およびADDRESSオブジェクトへの参照を含む列が設定されています。

オブジェクト参照を取り出すには、次の手順に従ってください。

  1. 標準SQL SELECT文を使用して、データベース表のREF列から参照を取り出します。

  2. getREFを使用して、結果セットからAddress参照を取り出し、REFオブジェクトに格納します。

  3. AddressをSQLオブジェクト型のADDRESSに対応するJavaカスタム・クラスに変換します。

  4. JavaクラスAddressとSQL型ADDRESS間の対応を、型マップに追加します。

  5. getValueメソッドを使用して、Address参照の内容を取り出します。出力をAddressにキャストします。

また、PEOPLEデータベース表の定義については、この項の始めの説明を参照してください。前述の手順を実行するコードは、Addressを型マップに追加する手順を除いて、次のようになります。

ResultSet rs = stmt.executeQuery("SELECT col3 FROM PEOPLE");
while (rs.next())
{
   REF ref = ((OracleResultSet)rs).getREF(1);
   Address a = (Address)ref.getValue();
}

注意:

前述のコードで、stmtはあらかじめ定義されている文オブジェクトです。

他のSQL型と同様に、結果セットのgetObjectメソッドを使用して参照を取り出すことができます。この場合、出力をキャストする必要があります。たとえば、次のようになります。

REF ref = (REF)rs.getObject(1);

getREFのかわりにgetObjectを使用しても、パフォーマンスは向上しません。ただし、getREFを使用すると、出力をキャストする必要がありません。

オブジェクト参照のコール可能文からの取出し

オブジェクト参照をPL/SQLブロックのOUTパラメータとして取り出すには、OUTパラメータのバインド型を登録する必要があります。

  1. 次のように、コール可能文をOracleCallableStatementにキャストします。

    OracleCallableStatement ocs =
       (OracleCallableStatement)conn.prepareCall("{? = call func()}");
    
  2. 次の形式のregisterOutParameterメソッドを使用して、OUTパラメータを登録します。

    ocs.registerOutParameter (int param_index, int sql_type, String sql_type_name);
    

    param_indexはパラメータ索引、sql_typeはSQL型コードです。sql_type_nameは、この参照が使用される構造化オブジェクト型の名前です。たとえば、OUTパラメータがADDRESSオブジェクトに対する参照の場合、ADDRESSは渡されるsql_type_nameです。

  3. 次のように、コールを実行します。

    ocs.execute();
    

オブジェクト参照のプリコンパイルされたSQL文への引渡し

オブジェクト参照をプリコンパイルされたSQL文に渡す方法は、他のSQL型を渡す場合と同様です。プリコンパイルされたSQL文のオブジェクトのsetObjectメソッドまたはsetREFメソッドを使用します。

次のプリコンパイルされたSQL文を使用し、ROWIDに基づいてアドレス参照を更新します。

PreparedStatement pstmt =
   conn.prepareStatement ("update PEOPLE set ADDR_REF = ? where ROWID = ?");
((OraclePreparedStatement)pstmt).setREF (1, addr_ref);
((OraclePreparedStatement)pstmt).setROWID (2, rowid);

オブジェクト値に対する、オブジェクト参照を介したアクセスと更新

REFオブジェクトのsetValueメソッドを使用すると、データベースにあるオブジェクトの値をオブジェクト参照から更新できます。このためには、最初に、データベース・オブジェクトに対する参照を取り出し、データベース・オブジェクトに対応するJavaオブジェクトを作成する必要があります。

たとえば、次のように、「オブジェクト参照の取出しと引渡し」のコードを使用して、データベースのADDRESSオブジェクトへの参照を取り出せます。

ResultSet rs = stmt.executeQuery("SELECT col3 FROM PEOPLE");
if (rs.next())
{
   REF ref = rs.getREF(1);
   Address a = (Address)ref.getValue();
}

次に、データベースのADDRESSオブジェクトに対応するJavaのAddressオブジェクトを作成できます。次のように、REFクラスのsetValueメソッドを使用して、データベース・オブジェクトの値を設定します。

Address addr = new Address(...);
ref.setValue(addr);

この例では、setValueメソッドによりデータベースのADDRESSオブジェクトが即時更新されます。

JPublisherで生成するカスタム参照クラス

この章では、oracle.sql.REFクラスの機能を主に説明していますが、カスタムJavaクラス、より厳密にはカスタム参照クラスからも、Oracleオブジェクト参照にアクセスできます。

カスタム参照クラスは、この章で説明した機能をすべて提供します。それに加え、強い型指定が適用されるという利点があります。カスタム参照クラスは、次の3つの要件を満たす必要があります。

カスタム参照クラスは独自に作成できますが、Oracle JPublisherユーティリティで作成すると便利です。JPublisherを使用してOracleオブジェクトにマップするカスタム・オブジェクト・クラスを生成し、ORAData実装を使用するように指定すると、JPublisherはORADataORADataFactoryを実装し、oracle.sql.REF属性を含むカスタム参照クラスも生成します。ORAData実装は、JPublisherの-usertypesマッピング・オプションにoracleが設定されている場合に使用されます。これがデフォルトです。

カスタム参照クラスは、強い型指定です。たとえば、OracleオブジェクトEMPLOYEEを定義すると、JPublisherによりEmployeeカスタム・オブジェクト・クラスおよびEmployeeRefカスタム参照クラスが生成されます。汎用oracle.sql.REFインスタンスのかわりにEmployeeRefインスタンスを使用すると、実行時ではなくコンパイル時にエラーを簡単に捕捉できます。たとえば、EmployeeRef変数に別の種類のオブジェクト参照を間違えて割り当てた場合は、簡単にエラーが検出されます。

標準SQLDataインタフェースはSQLオブジェクト・マッピングのみをサポートすることに注意してください。このため、カスタム・オブジェクト・クラスを作成するとき、JPublisherに標準SQLDataインタフェースを実装するように指示すると、カスタム参照クラスは生成されません。この場合、唯一のオプションは、標準java.sql.Refインスタンスまたはoracle.sql.REFインスタンスを使用して、オブジェクト参照にマップすることです。


関連項目: