この章では、オブジェクト参照へのアクセスおよび操作を行う、標準Java Database Connectivity(JDBC)について説明します。
この項の内容は次のとおりです。
Oracleでは、データベース・オブジェクトへの参照を使用できます。Oracle JDBCでは、次のオブジェクト参照がサポートされます。
SELECT句の列
INまたはOUTバインド変数
Oracleオブジェクトの属性
コレクション型オブジェクトの要素
SQLでは、オブジェクト参照(REF)は厳密に型指定されています。たとえば、EMPLOYEEオブジェクトへの参照は、REFのみではなく、EMPLOYEE REFとして定義されます。
オブジェクト参照を選択する場合は、オブジェクト本体でなく、オブジェクトへのポインタのみを取得することに注意してください。移植性を重視して、参照をjava.sql.Refインスタンスとしてインスタンス化するか、事前に作成したカスタムJavaクラスのインスタンスとしてインスタンス化して強い型指定の利点を取るか、両方の選択肢があります。オブジェクト参照のために使用されるカスタムJavaクラスは、カスタム参照クラスとして参照されるため、oracle.sql.ORADataインタフェースを実装する必要があります。
結果セットまたはコール可能文オブジェクトを介してREFインスタンスを取得し、プリコンパイルされたSQL文またはコール可能文オブジェクトを介して更新されたREFにインスタンスをデータベースに戻すことができます。REFクラスには、基礎となるオブジェクト属性値を取得および設定し、基礎となるオブジェクトのSQLベース型名を取得する機能があります。
カスタム参照クラスには、これと同じ機能が含まれている他に、強い型指定が適用されるという利点があります。この強い型指定により、実行時まで検出できないコーディング・エラーを、コンパイル時に発見できます。
|
注意:
|
この項では、オブジェクト参照の取出しと引渡しを行う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オブジェクトへの参照を含む列が設定されています。
オブジェクト参照を取り出すには、次の手順に従ってください。
AddressをSQLオブジェクト型のADDRESSに対応するJavaカスタム・クラスに変換します。
JavaクラスAddressとSQL型ADDRESS間の対応を、型マップに追加します。
また、PEOPLEデータベース表の定義については、この項の始めの説明を参照してください。前述の手順を実行するコードは、Addressを型マップに追加する手順を除いて、次のようになります。
ResultSet rs = stmt.executeQuery("SELECT col3 FROM PEOPLE");
while (rs.next())
{
REF ref = rs.getRef(1);
Address a = (Address)ref.getObject();
}
|
注意: 前述のコードで、stmtはあらかじめ定義されている文オブジェクトです。 |
オブジェクト参照をPL/SQLブロックのOUTパラメータとして取り出すには、OUTパラメータのバインド型を登録する必要があります。
次のように、コール可能文をOracleCallableStatementにキャストします。
OracleCallableStatement ocs =
(OracleCallableStatement)conn.prepareCall("{? = call func()}");
次の形式の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です。
次のように、コールを実行します。
ocs.execute();
オブジェクト参照をプリコンパイルされたSQL文に渡す方法は、他のSQL型を渡す場合と同様です。プリコンパイルされたSQL文のオブジェクトのsetObjectメソッドまたはsetREFメソッドを使用します。
次のプリコンパイルされたSQL文を使用し、ROWIDに基づいてアドレス参照を更新します。
PreparedStatement pstmt =
conn.prepareStatement ("update PEOPLE set ADDR_REF = ? where ROWID = ?");
pstmt.setRef (1, addr_ref);
pstmt.setRowId (2, rowid);
RefオブジェクトのsetObjectメソッドを使用すると、データベースにあるオブジェクトの値をオブジェクト参照から更新できます。このためには、最初に、データベース・オブジェクトに対する参照を取り出し、データベース・オブジェクトに対応するJavaオブジェクトを作成する必要があります。
たとえば、次のように、「オブジェクト参照の取出しと引渡し」のコードを使用して、データベースのADDRESSオブジェクトへの参照を取り出せます。
ResultSet rs = stmt.executeQuery("SELECT col3 FROM PEOPLE");
if (rs.next())
{
Ref ref = rs.getRef(1);
Address a = (Address)ref.getObject();
}
次に、データベースのADDRESSオブジェクトに対応するJavaのAddressオブジェクトを作成できます。次のように、RefインタフェースのsetObjectメソッドを使用して、データベース・オブジェクトの値を設定します。
Address addr = new Address(...); ref.setObject(addr);
この例では、setValueメソッドによりデータベースのADDRESSオブジェクトが即時更新されます。
この章では、java.sql.Refクラスの機能を主に説明していますが、カスタムJavaクラス、より厳密にはカスタム参照クラスからも、Oracleオブジェクト参照にアクセスできます。
カスタム参照クラスには、この章でここまで説明してきたすべての機能に加え、強い型指定が適用されるという利点があります。カスタム参照クラスは、次の3つの要件を満たす必要があります。
oracle.sql.ORADataインタフェースを実装する必要があります。カスタム・オブジェクト・クラス用の代替である標準JDBC SQLDataインタフェースは、カスタム参照クラスには使用できないので注意してください。
コンパニオン・クラスの場合は、カスタム参照クラスのインスタンスを作成するために、oracle.sql.ORADataFactoryインタフェースを実装する必要があります。
オブジェクト・データを参照する方法を用意する必要があります。JPublisherは、oracle.sql.REF属性を使用することにより、これを実現します。
カスタム参照クラスは独自にも作成できますが、Oracle JPublisherユーティリティを使用して作成すると便利です。JPublisherを使用して、Oracleオブジェクトにマップするためのカスタム・オブジェクト・クラスを生成し、JPublisherがORAData実装を使用するように指定した場合、JPublisherは、ORADataとORADataFactoryを実装して、oracle.sql.REF属性を含むカスタム参照クラスも生成します。JPublisher -usertypesマッピング・オプションがoracleに設定されている場合(デフォルト)、ORAData実装が使用されます。
カスタム参照クラスは、強い型指定です。たとえば、OracleオブジェクトEMPLOYEEを定義すると、JPublisherによりEmployeeカスタム・オブジェクト・クラスおよびEmployeeRefカスタム参照クラスが生成されます。汎用oracle.sql.REFインスタンスのかわりにEmployeeRefインスタンスを使用すると、実行時ではなくコンパイル時にエラーを簡単に捕捉できます。たとえば、EmployeeRef変数に別の種類のオブジェクト参照を間違えて割り当てた場合は、簡単にエラーが検出されます。
標準SQLDataインタフェースはSQLオブジェクト・マッピングのみをサポートすることに注意してください。このため、JPublisherがカスタム・オブジェクト・クラスを作成する際に標準SQLDataインタフェースを実装するように指定した場合、JPublisherはカスタム参照クラスを生成しません。この場合、唯一のオプションは、標準java.sql.Refインスタンスまたはoracle.sql.REFインスタンスを使用して、オブジェクト参照にマップすることです。