ヘッダーをスキップ
Oracle® Database JPublisherユーザーズ・ガイド
11gリリース2 (11.2)
B56279-03
  目次へ
目次
索引へ
索引

前へ
前へ
 
次へ
次へ
 

3 データ型およびJava間の型マッピング

この章では、Java間の型マッピングに関するJPublisherのスタイルおよびスタイル・ファイルなど、JPublisherのデータ型マッピング・サポートを説明します。これらのスタイル・ファイルは、主にWebサービスのサポート用に使用されます。この章の内容は、次のとおりです。

JPublisherのデータ型マッピング

この項では、SQLおよびPL/SQLからJavaへのマッピングに関するJPublisherの機能について説明します。この項の内容は、次のとおりです。

JPublisherのデータ型マッピングの概要

-builtintypes-lobtypes-numbertypesおよび-usertypesの型マッピング・オプションを使用する場合、次のデータ型マッピングの設定からいずれか1つを指定できます。

  • oracle

  • jdbc

  • objectjdbc

  • bigdecimal


注意:

objectjdbcおよびbigdecimalは、-numbertypesオプション専用の設定です。

これらのマッピングは、JPublisherで生成されるメソッドで使用される引数および結果の型に影響を与えます。

JPublisherでオブジェクト型に対して生成されるクラスには、オブジェクト属性用のgetXXX()およびsetXXX()アクセッサ・メソッドがあります。VARRAY型またはネストした表型に対してJPublisherで生成されるクラスには、配列またはネストした表の要素にアクセスするgetXXX()メソッドおよびsetXXX()メソッドがあります。ラッパー・メソッドの生成が有効化されている場合、オブジェクト型またはPL/SQLパッケージ用にJPublisherで生成されるクラスにはラッパー・メソッドがあります。これらのラッパー・メソッドが、オブジェクト型またはパッケージのサーバー・メソッド(ストアド・プロシージャ)をコールします。マッピング・オプションは、これらのメソッドで使用する引数および結果の型を制御します。

Java Database Connectivity(JDBC)マッピングおよびObject JDBCマッピングでは、標準のJava操作で処理可能な通常のJava型が使用されます。Oracleマッピングは最も効率のよいマッピングです。oracle.sql型はOracle内部データ型とほぼ一致しているため、JavaとSQLフォーマット間のデータ変換はほとんど、あるいはまったく必要ありません。情報を失うことはなく、データの処理およびデータの取出しにおいてより柔軟性があります。データベース内でデータを操作している場合やデータを移動している場合、標準のSQL型に対するOracleマッピングが最も便利な表現です。たとえば、ある既存の表から別の表へのSELECTおよびINSERT操作を実行している場合がこれに該当します。データ・フォーマット変換が必要な場合は、oracle.sql.*クラスのメソッドを使用してネイティブなJava型に変換できます。

OracleおよびJDBC型へのSQLとPL/SQLのマッピング

表3-1に、SQLデータ型およびPL/SQLデータ型からJava型へのマッピングを示します。PL/SQLメソッドの引数または結果の型として、この表でサポート対象となっているすべてのデータ型を使用できます。データ型のサブセットをオブジェクト属性の型として使用することもできます。

SQLおよびPL/SQLデータ型列にはすべての使用可能なデータ型が含まれます。

Oracleマッピング列は、すべての型マッピング・オプションをoracleに設定した場合にJPublisherで使用される対応Java型を示します。これらの型はOracleが提供するoracle.sqlパッケージ内にあり、Oracleデータ型をJava型に変換したときに発生するオーバーヘッドが最小となるように設計されています。


関連項目:

oracle.sqlパッケージの詳細は、『Oracle Database JDBC開発者ガイド』を参照してください。

JDBCマッピング列は、すべての型マッピング・オプションをjdbcに設定した場合にJPublisherで使用される対応Java型を示します。標準SQLデータ型の場合、JPublisherによりJDBC仕様で指定されたJava型が使用されます。Oracle拡張要素であるSQLデータ型の場合、JPublisherによりoracle.sql.*型が使用されます。-numbertypesオプションをobjectjdbcに設定すると、対応する型はJDBCマッピング列の場合と同じになります。ただし、intなどのJavaプリミティブ型は、java.lang.Integerなどの対応するオブジェクト型に置き換えられます。


注意:

PL/SQLのBOOLEANからSQLのNUMBER、さらにJavaのbooleanへのマッピングなど、JPublisherの型マップに明示的に定義されている型の対応付けは、マッピング・オプションの設定の影響を受けません。

PL/SQLにのみ関係する型など、JPublisherで直接サポートされないデータ型がいくつかあります。これらの制限事項は、等価のSQL型とJava型、およびPL/SQL表現とSQL表現の間のPL/SQL変換ファンクションを提供することで回避できます。これらの変換については、後述します。

表3-1 OracleおよびJDBCマッピング・クラスに対するSQLおよびPL/SQLデータ型

SQLおよびPL/SQLデータ型 Oracleマッピング JDBCマッピング

CHARCHARACTERLONGSTRINGVARCHARVARCHAR2

oracle.sql.CHAR

java.lang.String

NCHARNVARCHAR2

oracle.sql.NCHAR(注意1)

oracle.sql.NString(注意1)

NCLOB

oracle.sql.NCLOB(注意1)

oracle.sql.NCLOB(注意1)

RAWLONG RAW

oracle.sql.RAW

byte[]

BINARY_INTEGERNATURALNATURALNPLS_INTEGERPOSITIVEPOSITIVENSIGNTYPEINTINTEGER

oracle.sql.NUMBER

int

DECDECIMALNUMBERNUMERIC

oracle.sql.NUMBER

java.math.BigDecimal

DOUBLE PRECISIONFLOAT

oracle.sql.NUMBER

double

SMALLINT

oracle.sql.NUMBER

int

REAL

oracle.sql.NUMBER

float

DATE

oracle.sql.DATE

java.sql.Timestamp

TIMESTAMP

TIMESTAMP WITH TZ

TIMESTAMP WITH LOCAL TZ

oracle.sql.TIMESTAMP

oracle.sql.TIMESTAMPTZ

oracle.sql.TIMESTAMPLTZ

java.sql.Timestamp

INTERVALYEARTOMONTH

INTERVALDAYTOSECOND

String(注意2)

String(注意2)

ROWIDUROWID

oracle.sql.ROWID

oracle.sql.ROWID

BOOLEAN

boolean(注意3)

boolean(注意3)

CLOB

oracle.sql.CLOB

java.sql.Clob

BLOB

oracle.sql.BLOB

java.sql.Blob

BFILE

oracle.sql.BFILE

oracle.sql.BFILE

オブジェクト型

生成されたクラス

生成されたクラス

SQLJオブジェクト型

型の作成時に定義されたJavaクラス

型の作成時に定義されたJavaクラス

OPAQUE

生成されるクラスまたは事前定義済のクラス(注意4)

生成されるクラスまたは事前定義済のクラス(注意4)

RECORD

SQLオブジェクト型へのマッピングを使用(注意5)

SQLオブジェクト型へのマッピングを使用(注意5)

ネストした表、VARRAY

oracle.sql.ARRAYを使用して実装された生成クラス

java.sql.Array

オブジェクト型の参照

oracle.sql.REFを使用して実装された生成クラス

java.sql.Ref

REF CURSOR

java.sql.ResultSet

java.sql.ResultSet

索引付き表

SQLコレクションへのマッピングを使用(注意6)

SQLコレクションへのマッピングを使用(注意6)

スカラー(数値または文字)

索引付き表

Java配列へのマッピングを使用(注意7)

Java配列へのマッピングを使用(注意7)

ユーザー定義サブタイプ

ベース型と同じ

ベース型と同じ


データ型マッピングの注意 次の注意事項は、前述の表の項目に対応しています。

  1. Javaクラスoracle.sql.NCHARoracle.sql.NCLOBおよびoracle.sql.NStringは、JDBCの一部ではなく、JPublisherランタイムとともに配布されます。JPublisherでは、これらのクラスを使用して、対応するクラスoracle.sql.CHARoracle.sql.CLOBおよびjava.lang.Stringの使用がNCHAR形式で表現されます。

  2. SQLのINTERVAL型からJavaのString型へのマッピングは、デフォルトのJPublisher型マップに定義されています。変換にはSYS.SQLJUTLパッケージのファンクションが使用されます。

  3. PL/SQLのBOOLEANからSQLのNUMBERおよびJavaのbooleanへのマッピングは、デフォルトのJPublisher型マップに定義されています。このプロセスには、SYS.SQLJUTLパッケージからの変換ファンクションが使用されます。

  4. SQLのOPAQUE型であるSYS.XMLTYPEからJavaクラスoracle.xdb.XMLTypeへのマッピングは、デフォルトのJPublisher型マップに定義されています。他のOPAQUE型の場合は、通常、対応するJavaクラスがベンダーから提供されます。この場合は、SQLのOPAQUE型および対応するJavaラッパー・クラス間の対応付けを定義するJPublisher型マップ・エントリを指定する必要があります。型マップ・エントリのないOPAQUE型が検出されると、JPublisherはそのOPAQUE型用のJavaラッパー・クラスを生成します。

  5. PL/SQLのRECORD型をサポートするために、JPublisherはRECORD型をSQLオブジェクト型にマップした後、SQLオブジェクト型に対応したJava型にマップします。JPublisherでは2つのSQLスクリプトが生成されます。一方のスクリプトは、SQLオブジェクト型を作成し、SQL型とRECORD型の間の変換ファンクションを含むPL/SQLパッケージを作成するためのものです。もう一方のスクリプトは、最初のスクリプトにより作成されたSQL型とPL/SQLパッケージを削除するために使用されます。

  6. PL/SQLの索引付き表の型をサポートするために、JPublisherは最初に索引付き表の型をSQLコレクション型にマップした後、そのSQLコレクション型に対応したJavaクラスにマップします。JPublisherでは2つのSQLスクリプトが生成されます。一方のスクリプトは、SQLコレクション型を作成し、SQLコレクション型と索引付き表の型の間の変換ファンクションを含むPL/SQLパッケージを作成するためのものです。もう一方は、最初のスクリプトにより作成されたコレクション型とPL/SQLパッケージを削除するためのものです。

  7. JDBCドライバを使用してPL/SQLストアド・プロシージャまたはオブジェクト・メソッドをコールする場合は、PL/SQLのTABLE型とも呼ばれるスカラーの索引付き表が直接サポートされます。この場合は、型マップ・エントリを使用し、JPublisherに対して、PL/SQLのスカラーの索引付き表の型および対応するJava配列型を指定する必要があります。この後、JPublisherでは、このスカラーの索引付き表を使用するPL/SQLまたはオブジェクト・メソッドのシグネチャを自動的に公開することができます。

JPublisherのユーザー型マップとデフォルトの型マップ

JPublisherには、-typemapおよび-addtypemapオプションによって制御され、最初は空で始まるユーザー型マップがあります。また、-defaulttypemapおよび-adddefaulttypemapオプションによって制御され、次に示すエントリで始まるデフォルトの型マップもあります。

jpub.defaulttypemap=SYS.XMLTYPE:oracle.xdb.XMLType
jpub.adddefaulttypemap=BOOLEAN:boolean:INTEGER:
SYS.SQLJUTL.INT2BOOL:SYS.SQLJUTL.BOOL2INT
jpub.adddefaulttypemap=INTERVAL DAY TO SECOND:String:CHAR:
SYS.SQLJUTL.CHAR2IDS:SYS.SQLJUTL.IDS2CHAR
jpub.adddefaulttypemap=INTERVAL YEAR TO MONTH:String:CHAR:
SYS.SQLJUTL.CHAR2IYM:SYS.SQLJUTL.IYM2CHAR

これらのコマンド(一部の行は折り返されています)は、PL/SQL型、Java型およびSQL型の間のマッピングを示します。該当する場合は、PL/SQL型とSQL型の間で変換に使用する変換ファンクションも指定されます。

JPublisherでは、最初にデフォルトの型マップがチェックされます。デフォルトの型マップに含まれているマッピングをユーザー型マップで再定義しようとすると、JPublisherでは警告メッセージが生成され、再定義は無視されます。同様に、以前のマッピングと競合する-adddefaulttypemapまたは-addtypemap設定を介してマッピングを追加しようとすると、無視されて警告が生成されます。

通常、型マップには次の2つの使用例があります。

  • JDBCでサポートされないPL/SQLデータ型の型マッピングを指定します。

  • ユーザー定義型にマップするためのJavaクラスの再生成を回避します。たとえば、ユーザー定義のSQLオブジェクト型STUDENTがあり、この型をマップするためのStudentクラスがすでに生成されているとします。ユーザー型マップでSTUDENT:Studentマッピングを指定すると、JPublisherではStudentクラスが検索され、再生成なしでマッピングに使用されます。

カスタム・マッピングを使用するには、次のようにデフォルトの型マップを消去することをお薦めします。

-defaulttypemap=

その後、-addtypemapオプションを使用して、必要なマッピングをユーザー型マップに追加します。

事前定義済のデフォルトの型マップでは、SQLのOPAQUESYS.XMLTYPEとJavaラッパー・クラスoracle.xdb.XMLTypeの間の対応付けが定義されます。また、PL/SQLのBOOLEAN型は、SYS.SQLJUTLパッケージに定義されている2つの変換ファンクションを使用して、JavaのbooleanおよびSQLのINTEGERにマップされます。デフォルトの型マップには、SQLのINTERVAL型とJavaのString型のマッピングも提供されています。

ただし、true値とfalse値の他にSQLのNULL値を取得するために、PL/SQLのBOOLEAN型からJavaのオブジェクト型Booleanへのマッピングが必要な場合があります。そのためには、次のようにデフォルトの型マップをリセットします。

-defaulttypemap=BOOLEAN:Boolean:INTEGER:SYS.SQLJUTL.INT2BOOL:SYS.SQLJUTL.BOOL2INT

これにより、指定したJava型がbooleanからBooleanに変更され、他の既存のデフォルトの型マップ・エントリは排除されます。変換の残りの部分は引き続き有効です。

例: 型マップを使用した再生成の回避 次の例では、再生成されたJavaクラスのマッピングを回避するためのJPublisherの型マップを使用します。次の型宣言があるとします。CITY型がTRIP型の属性であることに注意してください。

SQL> CREATE TYPE city AS OBJECT (name VARCHAR2(20), state VARCHAR2(10));
/
SQL> CREATE OR REPLACE TYPE trip AS OBJECT (leave DATE, place city);
/

次のようにJPublisherを起動するとします。

% jpub -u scott -s TRIP:Trip
Enter scott password: password

JPublisherの出力は次のとおりです。

SCOTT.TRIP
SCOTT.CITY

処理対象にはTRIPのみが指定されています。ただし、このコマンドではソース・ファイルCity.javaCityRef.javaTrip.javaおよびTripRef.javaが生成されます。これは、CITYが属性であるためです。

CITYのクラスを再生成せずにTRIPのクラスを再生成する必要がある場合は、次のようにJPublisherを再実行できます。

% jpub -u scott -addtypemap=CITY:City -s TRIP:Trip SCOTT.TRIP
Enter scott password: password

この出力行でわかるように、CITY型は再処理されないため、City.javaおよびCityRef.javaファイルは再生成されません。これは、型マップにCITY:Cityの関係が追加され、マッピングに既存のCityクラスを使用することがJPublisherに伝えられるためです。

データ型マッピングに関するJPublisherの論理進行

JPublisherでは、指定された特定のSQL型またはPL/SQL型をJavaにマップするために、次の論理進行が使用されます。

  1. 型マップがチェックされ、マッピングが指定済かどうかが確認されます。

  2. SQL型とPL/SQL型に対する事前定義済のJavaマッピングがチェックされます。

  3. マップされるデータ型がPL/SQLのRECORD型であるか索引付き表の型であるかがチェックされます。PL/SQLのRECORD型の場合、JPublisherではJavaにマップできるように、対応するSQLオブジェクト型が生成されます。索引付き表の型の場合は、Javaにマップできるように、対応するSQLコレクション型が生成されます。

  4. 手順1から3のいずれにも該当しない場合は、そのデータ型をユーザー定義型にする必要があります。JPublisherでは、JPublisherのオプション設定に従って、マップするORADataまたはSQLDataクラスが生成されます。

オブジェクト属性の型

オブジェクト属性の型として表3-1にリストされているSQLデータ型のサブセットを使用できます。使用できる型は次のとおりです。

  • CHARVARCHARVARCHAR2CHARACTER

  • NCHARNVARCHAR2

  • DATE

  • DECIMALDECNUMBERNUMERIC

  • DOUBLE PRECISIONFLOAT

  • INTEGERSMALLINTINT

  • REAL

  • RAWLONG RAW

  • CLOB

  • BLOB

  • BFILE

  • NCLOB

  • オブジェクト型、OPAQUE型、SQLJオブジェクト型

  • ネストした表、VARRAY

  • オブジェクト参照型

JPublisherでは、次のTIMESTAMP型がオブジェクト属性としてサポートされます。

  • TIMESTAMP

  • TIMESTAMP WITH TIMEZONE

  • TIMESTAMP WITH LOCAL TIMEZONE


注意:

Oracle JDBC実装ではTIMESTAMP型はサポートされません。

REF CURSOR型と結果セットのマッピング

PL/SQLストアド・プロシージャ、PL/SQLファンクションまたはSQL問合せがREF CURSORを戻した場合、JPublisherはREF CURSORjava.sql.ResultSetにマップするためのメソッドをデフォルトで生成します。

また、ストアド・プロシージャやファンクションによってREF CURSORではなくSQL問合せが戻された場合、JPublisherはREF CURSORを行の配列にマップするためのメソッドを生成します。この配列では、各行がJavaBeansインスタンスで表されます。

また、-style=webservices-commonに設定され、CLASSPATHで次のクラスが使用可能になっている場合、JPublisherはREF CURSORを次の型にマップするためのメソッドを生成します。

  • javax.xml.transform.Source

  • oracle.jdbc.rowset.OracleWebRowSet

  • org.w3c.dom.Document


注意:

  • マッピングを生成するためにはCLASSPATHにクラスが指定されている必要があるという依存性は、スタイル・ファイル内のCONDITION文で指定します。CONDITION文には、必須クラスをリストします。

  • webservices9およびwebservices10スタイル・ファイルにはwebservices-commonが含まれていますが、これらのマッピングはオーバーライドされます。したがって、-style=webservices9または-style=webservices10に設定すると、JPublisherでこれらのマッピングは生成されません


必要な場合、JPublisherでクラスを確実に検出できるように次の手順を実行する必要があります。

  1. translator.jarruntime12.jarおよびojdbc5.jarの各ライブラリがCLASSPATHに指定されていることを確認します。これらのファイルには、それぞれJPublisherとSQLJ Translatorのクラス、SQLJランタイムのクラス、JDBCのクラスが含まれています。

  2. Sourceにマップするには、Java Development Kit(JDK)1.4を使用します。このクラスは、以前のバージョンのJDKでは定義されていません。

  3. OracleWebRowSetにマップするには、CLASSPATHにORACLE_HOME/jdbc/lib/rowset-jsr114.jarを追加します。

  4. Documentにマップするには、CLASSPATHにORACLE_HOME/lib/xmlparsev2.jarを追加します。

次のPL/SQLストアド・プロシージャを考えてみます。

TYPE curtype1 IS REF CURSOR RETURN emp%rowtype;
FUNCTION get1 RETURN curtype1;

公開時にCLASSPATH内でOracleWebRowSetクラスが検出されても、DocumentおよびSourceが検出されなければ、JPublisherではget1ファンクション用に次のメソッドが生成されます。

public oracle.jdbc.rowset.OracleWebRowSet get1WebRowSet()
                                 throws java.sql.SQLException;
public java.sql.ResultSet get1() throws java.sql.SQLException;

DocumentおよびSourceを戻すメソッドの名前は、それぞれget1XMLDocument()およびget1XMLSource()となります。

Source、OracleWebRowSetまたはDocumentへのマッピングの無効化

現在、SourceOracleWebRowSetまたはDocumentへのマッピングを明示的に有効化または無効化するためのJPublisherオプションはありません。webservices-commonスタイル・ファイルでの条件は、CLASSPATHにクラスが存在するかどうかのみです。ただし、JPublisherによるREF CURSORのマッピング方法を厳密に制御する必要がある場合は、スタイル・ファイルをコピーして独自に編集できます。次のコードに、例としてコピーおよび編集したwebservices-commonファイルの抜粋を示します。編集内容についてはコードの後に説明します。

BEGIN_TRANSFORMATION
MAPPING
SOURCETYPE java.sql.ResultSet
TARGETTYPE java.sql.ResultSet
RETURN
%2 = %1;
END_RETURN;
END_MAPPING

MAPPING
#CONDITION oracle.jdbc.rowset.OracleWebRowSet
SOURCETYPE java.sql.ResultSet
TARGETTYPE oracle.jdbc.rowset.OracleWebRowSet
TARGETSUFFIX WebRowSet
RETURN
%2 = null;
if (%1!=null)
{
  %2 = new oracle.jdbc.rowset.OracleWebRowSet();
  %2.populate(%1);
}
END_RETURN
END_MAPPING
 
#MAPPING
#CONDITION org.w3c.dom.Document oracle.xml.sql.query.OracleXMLQuery
#SOURCETYPE java.sql.ResultSet
#TARGETTYPE org.w3c.dom.Document
#TARGETSUFFIX XMLDocument
#RETURN
#%2 = null;
#if (%1!=null)
#  %2= (new oracle.xml.sql.query.OracleXMLQuery
#                                 (_getConnection(), %1)).getXMLDOM();
#END_RETURN
#END_MAPPING

MAPPING
CONDITION org.w3c.dom.Document oracle.xml.sql.query.OracleXMLQuery
          javax.xml.transform.Source javax.xml.transform.dom.DOMSource
SOURCETYPE java.sql.ResultSet
TARGETTYPE javax.xml.transform.Source
TARGETSUFFIX XMLSource
RETURN
%2 = null;
if (%1!=null)
  %2= new javax.xml.transform.dom.DOMSource
      ((new oracle.xml.sql.query.OracleXMLQuery
       (new oracle.xml.sql.dataset.OracleXMLDataSetExtJdbc(_getConnection(),
       (oracle.jdbc.OracleResultSet) %1))).getXMLDOM());
END_RETURN
END_MAPPING
END_TRANSFORMATION

このファイルをmyrefcursormaps.propertiesにコピーするとします。SOURCETYPEおよびTARGETTYPEエントリに従ってREF CURSORResultSetOracleWebRowSetDocumentおよびSourceにマップすることを意図した4つのMAPPINGセクションがあります。この例では、次の目的で各行が"#"文字を使用してコメント化されています。

  • OracleWebRowSetマッピングに対するCONDITION文はコメント化されています。このため、JPublisherでは、OracleWebRowSetがCLASSPATHに含まれているかどうかに関係なく、このマッピング用のメソッドが生成されます。

  • Documentマッピングの場合は、MAPPINGセクション全体がコメント化されています。このマッピング用のメソッドは生成されません。

カスタム・マッピングを使用するために、次のオプションでJPublisherを実行します。

% jpub -u scott -style=myrefcursormaps -s MYTYPE:MyType
Enter scott password: password

JDBCマッピングにおける接続

-usertypes=jdbc設定を使用すると、JPublisherではSQLオブジェクト型用のSQLDataが生成されます。SQLDataインスタンス用の基礎となるJDBC接続は、JDBCドライバによって自動設定はされません。したがって、SQLDataインスタンス内の属性にアクセスする前に、setConnectionContext()メソッドを使用してJDBC接続を設定する必要があります。

Addressは、JPublisherによって-usertypes=jdbcを使用して生成されたSQLDataクラスであることを考慮してください。次のコード・セグメントでは、Addressインスタンスの属性がアクセスされています。setConnectionContextコールが、基礎となるJDBC接続を明示的に初期化していることに注意してください。

...
ResultSet rset = stmt.executeQuery();
Address address = (Address) rset.getObject(1);
address.setConnectionContext(new sqlj.runtime.ref.DefaultContext(connection));
String addr = address.getAddress();
...

注意:

他の-usertypes設定の場合、前のコード例で説明したように接続の設定は必要ありません。

一方、JPublisherが-usertypes=oracle設定を使用して、またはデフォルトで生成するORAData型の場合は、接続の初期化は必要ありません。ORADataの場合、基礎となるJDBC接続はResultSetから読み取られた時点ですでに割り当てられています。

PL/SQLデータ型のサポート

JPublisherにより検出されたPL/SQLストアド・プロシージャまたはファンクション(SQLオブジェクト型のメソッドを含む)に、JDBCでサポートされていないPL/SQL型が使用されている場合については、次の3つの使用例があります。

次の項では、JDBCでサポートされていないPL/SQL型に対するJPublisherの型マッピング機能の詳細を説明します。

OPAQUE型の型マッピング・サポート

この項では、SQLのOPAQUE型のJPublisher型マッピング・サポート全般について説明します。


注意:

JPublisherを使用してSQLのOPAQUE型のラッパー・クラスを生成する場合は、Oracle9iリリース2(9.2)以上のインストールとJDBCドライバを使用する必要があります。

Oracle JDBC実装とSQLJ実装では、oracle.sql.ORADataインタフェースを実装するJavaクラスとして公開されるSQLのOPAQUE型がサポートされます。この種のクラスには、次のパブリック・フィールド、静的フィールドおよびメソッドを含める必要があります。

public static String _SQL_NAME = "SQL_name_of_OPAQUE_type";
public static int _SQL_TYPECODE = OracleTypes.OPAQUE;
public static ORADataFactory getORADataFactory() { ... }

SQLのOPAQUE型にマップするJavaラッパー・クラスがあり、クラスがこの要件を満たしている場合は、JPublisherのユーザー型マップを介してマッピングを指定できます。次の構文で-addtypemapオプションを使用し、マッピングをユーザー型マップに追加します。

-addtypemap=sql_opaque_type:java_wrapper_class

Oracle Database 11gでは、SQLのOPAQUESYS.XMLTYPEは、JPublisherのデフォルトの型マップを介してJavaのoracle.xdb.XMLTypeクラスにマップされます。これと同じマッピングは、次のようにユーザー型マップを介して明示的に指定できます。

-addtypemap=SYS.XMLTYPE:oracle.xdb.XMLType

JPublisherでは、型の対応付けが指定されていないSQLのOPAQUE型が検出されるたびに、Javaラッパー・クラスが公開されます。SCOTTスキーマに定義されている次のSQL型を考えます。

CREATE TYPE X_TYP AS OBJECT (xml SYS.XMLTYPE);

次のコマンドでは、X_TYPがJavaクラスXTypとして公開されます。

% jpub -u scott -s X_TYP:XTyp
Enter scott password: password

デフォルトでは、xml属性は、SYS.XMLTYPEに対する事前定義済の型マッピングであるoracle.xdb.XMLTypeを使用して公開されます。JPublisherのデフォルト型マップを消去すると、SYS.XMLTYPE属性用のラッパー・クラスXmltypeが自動的に生成されます。この動作は、JPublisherを次のように起動することで確認できます。

% jpub -u scott -s X_TYP:XTyp -defaulttypemap=
Enter scott password: password

-defaulttypemapオプションは、JPublisherのデフォルトの型マップを設定します。前述の例のように、値を指定しない場合は消去されます。

スカラーの索引付き表の型マッピング・サポート

スカラーのPL/SQL索引付き表という用語は、VARCHAR型および数値型の要素を持つPL/SQL索引付き表を指します。10gリリース2(10.2)から、JPublisherでは、PL/SQL索引付き表をカスタムJDBC型へマップする方法にかわって、単純なPL/SQL索引付き表をJava配列にマップできます。オプションplsqlindextableは、単純なPL/SQL索引付き表のマッピング方法を指定します。

-plsqlindextable=custom|array|int

-plsqlindextable=customが設定されている場合、すべての索引付き表がSQLDataCustomDatumまたはORADataなどのカスタムJDBC型にマップされます。-plsqlindextable=arrayまたは-plsqlindextable=intが設定されている場合、単純な索引付き表がJava配列にマップされます。-plsqlindextableintの場合、int値は配列の容量(デフォルトで32768)を指定します。このオプションのデフォルト設定はcustomです。

次のPL/SQLパッケージを考えてみます。

CREATE OR REPLACE PACKAGE indexbytable_package AS
  TYPE index_tbl1 IS TABLE OF VARCHAR2(111) INDEX BY binary_integer;
  TYPE index_tbl2 IS TABLE OF NUMBER INDEX BY binary_integer;
  TYPE varray_tbl3 IS VARRAY(100) OF VARCHAR2(20);
  TYPE nested_tbl4 IS TABLE OF VARCHAR2(20);
  FUNCTION echo_index_tbl1(a index_tbl1) RETURN index_tbl1;
  FUNCTION echo_index_tbl2(a index_tbl2) RETURN index_tbl2;
  FUNCTION echo_varray_tbl3(a varray_tbl3) RETURN varray_tbl3;
  FUNCTION echo_nested_tbl4(a nested_tbl4) RETURN nested_tbl4;
END;
/

次のコマンドを実行します。

% jpub -u scott -sql=indexbytable_package:IndexbyTablePackage#IndexbyTableIntf -plsqlindextable=32
Enter scott password: password

-plsqlindextable=32の設定は、単純な索引付き表が容量が32のJava配列にマップされることを指定します。次のインタフェースが、IndexbyTableIntf.javaに生成されます。

public interface IndexbyTableIntf
{
 public String[] echoIndexTbl1(String[] a);
 public java.math.BigDecimal[] echoIndexTbl2(java.math.BigDecimal[] a);
 public IndexbytableintfVarrayTbl3 echoVarrayTbl4(IndexbytableintfVarrayTbl3 a);
 public IndexbytableintfNestedTbl4 echoVarrayTbl4(IndexbytableintfNestedTbl4 a);
}

生成されたコードでは、単純な索引付き表の型であるindex_tbl1およびindex_tb2が、String[]およびBigDecimal[]にそれぞれマップされます。ただし、ネストした表とVARRAY表はカスタムJDBC型にマップされます。これらの表は索引付きの表ではなく、そのマッピングが-plsqlindextable設定の影響を受けないためです。

PL/SQLの索引付き表から配列へのマッピングには、表が整数で索引付けされている必要があるという制限があります。PL/SQLパッケージに整数で索引付けされた表とVARCHARで索引付けされた表の両方が含まれている場合、-plsqlindexbytable=array-plsqlindexbytable=intの設定は使用できません。使用すると、VARCHARで索引付けされた表のマッピングでランタイム・エラーが発生します。-plsqlindexbytable=customをかわりに使用する必要があります。

索引付き表の要素のマッピングは、JDBC型マッピングに従います。たとえばJDBCマッピングの場合、SMALLINTはJavaのint型にマップされます。したがって、SMALLINTの索引付き表はint[]にマップされます。-plsqlindexbytable=arrayまたは-plsqlindexbytable=int設定は、数値に対してOracleマッピングが有効になっている場合、つまり-numbertypes=oracleの場合は無視されます。理由は、索引付き表にマップされるJava配列の要素は文字列または数値のJava型であることが必要なのに対して、OracleマッピングではSQLの数値がoracle.sql型にマップされるためです。

Oracle JDBCドライバでは、数値または文字の要素を持つPL/SQLのスカラーの索引付き表が直接サポートされます。数値要素を持つ索引付き表は、次のJava配列型にマップできます。

  • int[]

  • double[]

  • float[]

  • java.math.BigDecimal[]

  • oracle.sql.NUMBER[]

文字要素を持つ索引付き表は、次のJava配列型にマップできます。

  • String[]

  • oracle.sql.CHAR[]

次の場合は、索引付き表の型について特定の情報を説明にそって指定する必要があります。

  • OUTまたはIN OUTパラメータの位置に索引付き表の型を使用するときは常に、最大要素数を指定する必要があります。その他の場合はオプションです。最大要素数は、Java配列割当て用の通常の構文を使用して指定できます。たとえば、最大100個の要素に対応できる型を示すint[100]、または最大20個の要素に対応できる型を示すoracle.sql.CHAR[20]を指定できます。

  • 文字要素を持つ索引付き表の場合は、必要に応じて個々の要素の最大サイズをバイト数で指定できます。この設定を定義するには、SQLと同様のサイズ構文を使用します。たとえば、IN引数に使用する索引付き表の場合は、String[](30)を指定できます。また、最大長が20で各要素が255バイトを超えない索引付き表の場合は、oracle.sql.CHAR[20](255)を指定できます。

ユーザーの型マップに、スカラーの索引付き表であるPL/SQL型および対応するJava配列型の間の対応付けを指定する指示を追加するには、JPublisherの-addtypemapオプションを使用します。前述の構文を使用して指定したサイズ・ヒントは生成されるSQLJクラスに埋め込まれるため、実行時にJDBCに与えられます。

一例として、SCOTTスキーマ内のINDEXBY PL/SQLパッケージの定義から抜粋した次のコード部分を考えてみます。このコードがindexby.sqlというファイルで使用可能であるとします。

CREATE OR REPLACE PACKAGE indexby AS

--  jpub.addtypemap=SCOTT.INDEXBY.VARCHAR_ARY:String[1000](4000)
--  jpub.addtypemap=SCOTT.INDEXBY.INTEGER_ARY:int[1000]
--  jpub.addtypemap=SCOTT.INDEXBY.FLOAT_ARY:double[1000]

 TYPE varchar_ary IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
 TYPE integer_ary IS TABLE OF INTEGER        INDEX BY BINARY_INTEGER;
 TYPE float_ary   IS TABLE OF NUMBER         INDEX BY BINARY_INTEGER;

 FUNCTION get_float_ary RETURN float_ary;
 PROCEDURE pow_integer_ary(x integer_ary, y OUT integer_ary);
 PROCEDURE xform_varchar_ary(x IN OUT varchar_ary);

END indexby;
/
CREATE OR REPLACE PACKAGE BODY indexby IS ...
/

3つの索引付き表の型のマッピングに必要な-addtypemapディレクティブを次に示します。

-addtypemap=SCOTT.INDEXBY.VARCHAR_ARY:String[1000](4000)
-addtypemap=SCOTT.INDEXBY.INTEGER_ARY:int[1000]
-addtypemap=SCOTT.INDEXBY.FLOAT_ARY:double[1000]

使用中のオペレーティング・システム・シェルによっては、大カッコ[...]や丸カッコ(...)を含むオプションを引用符で囲む必要があるため注意してください。この種のオプションを次のようにJPublisherのプロパティ・ファイルに挿入すると、引用符で囲まずにすみます。

jpub.addtypemap=SCOTT.INDEXBY.VARCHAR_ARY:String[1000](4000)
jpub.addtypemap=SCOTT.INDEXBY.INTEGER_ARY:int[1000]
jpub.addtypemap=SCOTT.INDEXBY.FLOAT_ARY:double[1000]

また、便利な機能として、プロパティ・ファイル内のJPublisherディレクティブは、接頭辞--(2つのハイフン)を付けると認識されますが、jpub.または-- jpub.で始まらないエントリは無視されます。そのため、JPublisherディレクティブをSQLスクリプトに挿入し、同じSQLスクリプトをJPublisherのプロパティ・ファイルとして再利用できます。したがって、次のように、INDEXBYパッケージを定義するためにindexby.sqlスクリプトを起動した後、JPublisherを実行して、このパッケージをJavaクラスIndexByとして公開できます。

% jpub -u scott -s INDEXBY:IndexBy -props=indexby.sql
Enter scott password: password

前述のように、スカラーの索引付き表のマッピングは、Oracle JDBCドライバでのみ使用できます。他のドライバを使用している場合や、ドライバに依存しないコードを作成する場合は、索引付き表の型に対応するSQL型と、2つの型の間でマップする変換ファンクションを定義する必要があります。

PL/SQL変換ファンクションを介した型マッピングのサポート

この項では、JPublisherでJavaコード内のPL/SQL型をサポートするために使用されるメカニズムについて説明します。このメカニズムでは、JDBCからアクセスできるように各PL/SQL型および対応するSQL型の間で変換を行うPL/SQL変換ファンクションが使用されます。

通常、Javaプログラムでは、PL/SQL固有の型のバインドをサポートしていません。この種の型をJavaから使用するには、PL/SQLコードを使用してSQL型にマップし、これらのSQL型にJavaからアクセスする必要があります。ただし、1つの例外はスカラーの索引付き表の型です。

JPublisherでは、型マップの使用により、このタスクが簡単になります。特定のPL/SQL型の場合、JPublisherの型マップ・エントリに次の情報を指定します。

  • PL/SQLの型の名前(通常は次の書式を使用)

    SCHEMA.PACKAGE.TYPE
    
  • 対応するJavaラッパー・クラスの名前

  • PL/SQLの型に対応するSQL型の名前

    この型をJavaラッパー型に直接マップできるようにする必要があります。たとえば、SQL型がNUMBERの場合、対応するJava型はintdoubleIntegerDoublejava.math.BigDecimalまたはoracle.sql.NUMBERとなります。SQL型がオブジェクト型の場合、対応するJava型はoracle.sql.ORADataまたはjava.sql.SQLDataインタフェースを実装するオブジェクト・ラッパー・クラスとなります。通常、このオブジェクト・ラッパー・クラスはJPublisherにより生成されます。

  • SQL型をPL/SQL型にマップするPL/SQL変換ファンクションの名前

  • PL/SQL型をSQL型にマップするPL/SQL変換ファンクションの名前

この-addtypemapは、次の書式で指定します。

-addtypemap=plsql_type:java_type:sql_type:sql_to_plsql_fun:plsql_to_sql_fun

たとえば、PL/SQLのBOOLEAN型をサポートするための型マップ・エントリを考えてみます。これは次の指定で構成されます。

  • PL/SQL型の名前(BOOLEAN)

  • Javaのbooleanにマップするための指定

  • 対応するSQL型(INTEGER)

    JDBCでは、boolean値は特殊な数値とみなされます。

  • SQLからPL/SQLにマップするPL/SQLファンクションの名前(INT2BOOL)

    ファンクションのコードは次のとおりです。

    FUNCTION int2bool(i INTEGER) RETURN BOOLEAN IS
    BEGIN IF i IS NULL THEN RETURN NULL;
          ELSE RETURN i<>0;
          END IF;
    END int2bool;
    
  • PL/SQLからSQLにマップするPL/SQLファンクションの名前(BOOL2INT)

    ファンクションのコードは次のとおりです。

    FUNCTION bool2int(b BOOLEAN) RETURN INTEGER IS
    BEGIN IF b IS NULL THEN RETURN NULL;
          ELSIF b THEN RETURN 1;
          ELSE RETURN 0; 
          END IF;
    END bool2int;
    

前述の指定をすべて次の型マップ・エントリに使用できます。

-addtypemap=BOOLEAN:boolean:INTEGER:INT2BOOL:BOOL2INT

この型マップ・エントリでは、SQL型、Java型、2つの変換ファンクションが、それぞれSQL、JavaおよびPL/SQLで定義されているものとみなされます。PL/SQLのBOOLEANに関するエントリは、すでにJPublisherのデフォルトの型マップに存在することに注意してください。前述の型マップ・エントリをテストする場合は、デフォルトの型マップをオーバーライドする必要があります。この操作には、JPublisherの-defaulttypemapオプションを次のようにして使用できます。

% jpub -u scott -s SYS.SQLJUTL:SQLJUtl -defaulttypemap=BOOLEAN:boolean:INTEGER:INT2BOOL:BOOL2INT
Enter scott password: password

注意:

  • 前述の例のINT2BOOLBOOL2INTの場合など、JPublisherで変換ファンクションが(通常はSYS.SQLJUTLパッケージ内で)事前定義されている場合があります。その他、RECORD型および索引付き表の型などの場合は、JPublisherが実行中に変換ファンクションを生成します。

  • このマニュアルでは、SQL型とPL/SQL型の間のマッピングとしての変換について説明していますが、このアプローチにPL/SQL限定という制限事項はありません。様々なSQL型の間でもマップできます。事実、JPublisherのデフォルトの型マップでは、VARCHAR2値との間でマップされるSQLのINTERVAL型をサポートするために、このマッピングが行われています。


PL/SQLのラッパー・ファンクションもJPublisherにより作成される場合があることに注意してください。各ラッパー・ファンクションが、PL/SQL型を使用するストアド・プロシージャをラップします。これが元のストアド・プロシージャをコールして、適切な変換ファンクションを使用して対応するSQL型のみがJavaに公開されるようにそのPL/SQLの出入力を処理します。次のJPublisherオプションでは、PL/SQL型を使用するPL/SQLストアド・プロシージャをコールするコードのJPublisherによる作成方法が制御されます。これには、変換ファンクションの使用方法やラッパー・ファンクションの使用方法なども含まれます。

  • -plsqlpackage=plsql_package

    このオプションでは、JPublisherでPL/SQL変換ファンクションが生成されるPL/SQLパッケージの名前を指定します。これは、サポートされない各PL/SQL型を対応するSQL型に変換するファンクションと、対応する各SQL型をPL/SQL型に変換するファンクションです。オプションで、-plsqlmapオプションの設定によっては、パッケージに元のストアド・プロシージャのラッパー・ファンクションも含まれます。各ラッパー・ファンクションにより、該当する変換ファンクションがコールされます。

    パッケージ名を指定しないと、JPublisherはJPUB_PLSQL_WRAPPERを使用します。

  • -plsqlfile=plsql_wrapper_script,plsql_dropper_script

    このオプションでは、JPublisherにより作成されるラッパー・スクリプトおよび削除スクリプトの名前を指定します。ラッパー・スクリプトにより、サポートされないPL/SQL型にマップするために必要なSQL型と、PL/SQLパッケージも作成されます。削除スクリプトでは、これらのSQL型およびPL/SQLパッケージが削除されます。

    このファイルが存在している場合は、上書きされます。ファイル名を指定しないと、JPublisherはplsql_wrapper.sqlおよびplsql_dropper.sqlという名前のファイルに書き込みます。

  • -plsqlmap=flag

    このオプションでは、JPublisherでPL/SQL型を使用するストアド・プロシージャのラッパー・ファンクションを生成するかどうかを指定します。各ラッパー・ファンクションは、対応するストアド・プロシージャと、ストアド・プロシージャのPL/SQLの出入力用の適切なPL/SQL変換ファンクションをコールします。対応するSQL型のみがJavaに公開されます。flagには、次のいずれかを設定できます。

    • true

      これはデフォルト設定です。必要な場合にのみPL/SQLラッパー・ファンクションが生成されます。指定のストアド・プロシージャをコールしてPL/SQL型を直接変換するJavaコードが単純で、かつ、PL/SQL型がINパラメータまたはファンクションの戻り値にのみ使用される場合、生成されるコードはかわりにストアド・プロシージャを直接コールします。その後、該当する変換ファンクションを介してPL/SQLの出入力を処理します。

      PL/SQL型がOUTまたはIN OUTパラメータとして使用される場合は、元のストアド・プロシージャをコールする前または後にPL/SQL表現とSQL表現の間で変換する必要があるため、ラッパー・ファンクションが必要です。

    • false

      PL/SQLラッパー・ファンクションは生成されません。シグネチャ内にダイレクト・コールと変換でサポートできないPL/SQL型が検出された場合、その特定のストアド・プロシージャに対するJavaコードの生成は省略されます。

    • always

      PL/SQL型を使用するストアド・プロシージャごとに、PL/SQLラッパー・ファンクションが生成されます。この設定は、オリジナルのPL/SQLパッケージを補完するプロキシPL/SQLパッケージを生成する場合に役立ちます。オリジナル・パッケージ内でJDBCを介してアクセスできないファンクションまたはプロシージャについては、JDBCでアクセス可能なシグネチャが提供されます。

PL/SQLのRECORD型と索引付き表の型の型マッピング・サポート

JPublisherでは、PL/SQLのRECORD型を引数または戻り型として使用するPL/SQLストアド・プロシージャまたはファンクションを公開するたびに、この型を自動的に公開します。これは、PL/SQLの索引付き表の型の場合も同じです。RECORD型または索引付き表を公開する唯一の方法となります。この種の型の公開をJPublisherのオプション設定を使用して明示的に要求する方法はありません。


注意:

JPublisherにおけるPL/SQLのRECORD型および索引付き表の型のサポートには、次の制限があります。
  • RECORDまたは索引付き表の引数からJDBCでサポート可能なSQL型へのマッピングには、中間的なラッパー・レイヤーが必要です。また、JPublisherでは、索引付き表のセマンティクスは完全にはサポートされません。索引付き表の構造はJavaのハッシュテーブルに似ていますが、JPublisherによりSQLのTABLE型にマップされると情報が失われます。

  • JDBC OCIドライバを使用し、スカラーの索引付き表の公開のみが必要な場合は、Javaとこれらの型の間で直接のマッピングを使用できます。


次の項では、JPublisherでのPL/SQLのRECORD型と索引付き表の型のサポートについて説明します。

RECORD型と索引付き表の型のサポートを示すサンプル・パッケージ

次のPL/SQLパッケージを使用して、PL/SQLのRECORD型と索引付き表の型に対するJPublisherのサポート例を示します。

CREATE OR REPLACE PACKAGE company IS
  TYPE emp_rec IS RECORD (empno NUMBER, ename VARCHAR2(10));
  TYPE emp_tbl IS TABLE OF emp_rec INDEX BY binary_integer;
  PROCEDURE set_emp_rec(er emp_rec);
  FUNCTION get_emp_rec(empno number) RETURN emp_rec;
  FUNCTION get_emp_tbl RETURN emp_tbl;
END;

このパッケージでは、PL/SQLのRECORDEMP_RECおよびPL/SQLの索引付き表の型EMP_TBLが定義されています。次のコマンドを使用してCOMPANYパッケージを公開します。

% jpub -u scott -s COMPANY:Company -plsqlpackage=WRAPPER1
  -plsqlfile=wrapper1.sql,dropper1.sql
Enter scott password: password

JPublisherの出力は次のとおりです。

SCOTT.COMPANY
SCOTT."COMPANY.EMP_REC"
SCOTT."COMPANY.EMP_TBL"
J2T-138, NOTE: Wrote PL/SQL package WRAPPER1 to file wrapper1.sql.
Wrote the dropping script to file dropper1.sql

この例では、JPublisherによりCOMPANYパッケージのJavaラッパー・クラス用のCompany.javaと次のSQLおよびJavaエンティティが生成されます。

  • wrapper1.sqlスクリプト。このスクリプトにより、PL/SQLのRECORD型と索引付き表の型に対応するSQL型が作成され、SQL型とPL/SQL型の間の変換ファンクションも作成されます。

  • dropper1.sqlスクリプト。このスクリプトでは、wrapper1.sqlにより作成されたSQL型と変換ファンクションが削除されます。

  • CompanyEmpRec.javaソース・ファイル。PL/SQLのRECORD型用に生成されるSQLオブジェクト型のJavaラッパー・クラスが含まれます。

  • CompanyEmpTbl.javaソース・ファイル。PL/SQLの索引付き表の型用に生成されるSQLコレクション型のJavaラッパー・クラスが含まれます。

RECORD型のサポート

この項では、「RECORD型と索引付き表の型のサポートを示すサンプル・パッケージ」の例を引き続き説明します。PL/SQLのRECORDEMP_RECの場合、JPublisherでは対応するSQLオブジェクト型 COMPANY_EMP_RECが生成されます。また、両者間の変換ファンクションも生成されます。この例では、wrapper1.sql内でEMP_REC用に次のように生成されます。

CREATE OR REPLACE TYPE COMPANY_EMP_REC AS OBJECT (
                       EMPNO NUMBER(22),
                       ENAME VARCHAR2(10)
);
/
-- Declare package containing conversion functions between SQL and PL/SQL types
CREATE OR REPLACE PACKAGE WRAPPER1 AS
   -- Declare the conversion functions the PL/SQL type COMPANY.EMP_REC
        FUNCTION PL2COMPANY_EMP_REC(aPlsqlItem COMPANY.EMP_REC)
        RETURN COMPANY_EMP_REC;
        FUNCTION COMPANY_EMP_REC2PL(aSqlItem COMPANY_EMP_REC)
        RETURN COMPANY.EMP_REC;
END WRAPPER1;
/

また、SQLオブジェクト型COMPANY_EMP_RECがJavaソース・ファイルCompanyEmpRec.javaに公開されます。

PL/SQLのRECORD型が公開された後、マッピングを型マップに追加できます。JPublisherのサンプル・プロパティ・ファイルdone.propertiesのエントリを次に示します。

jpub.addtypemap=SCOTT.COMPANY.EMP_REC:CompanyEmpRec:COMPANY_EMP_REC:
WRAPPER1.COMPANY_EMP_REC2PL:WRAPPER1.PL2COMPANY_EMP_REC

RECORDEMP_RECを参照するパッケージまたは型を公開するときには、この型マップ・エントリを使用します。たとえば次のJPublisherコールでは、この型マップ・エントリとともにdone.propertiesが使用されています。

% jpub -u scott -p done.properties -s COMPANY -plsqlpackage=WRAPPER2
       -plsqlfile=wrapper2.sql,dropper2.sql
Enter scott password: password

JPublisherの出力は次のとおりです。

SCOTT.COMPANY
SCOTT."COMPANY.EMP_TBL"
J2T-138, NOTE: Wrote PL/SQL package WRAPPER2 to file wrapper2.sql. 
Wrote the dropping script to file dropper2.sql

索引付き表の型のサポート

この項では、「RECORD型と索引付き表の型のサポートを示すサンプル・パッケージ」の例を引き続き説明します。

索引付き表の型をサポートするには、PL/SQLの索引付き表の型との間の変換が可能なSQLコレクション型を定義する必要があります。JPublisherでは、PL/SQLのネストした表とVARRAYも同じ方法でサポートされます。そのため、次に示すEMP_TBLの3つの定義の場合、実際には同じコードが生成されます。

TYPE emp_tbl IS TABLE OF emp_rec INDEX BY binary_integer;
TYPE emp_tbl IS TABLE OF emp_rec;
TYPE emp_tbl IS VARRAY OF emp_rec;

PL/SQLの索引付き表の型EMP_TBLの場合、JPublisherではSQLコレクション型、および索引付き表の型とSQLコレクション型の間の変換ファンクションが生成されます。

前述のRECORD型の説明で示したファンクションに加えて、JPublisherでは次のファンクションが生成されます。

-- Declare the SQL type for the PL/SQL type COMPANY.EMP_TBL
CREATE OR REPLACE TYPE COMPANY_EMP_TBL AS TABLE OF COMPANY_EMP_REC; 
/
-- Declare package containing conversion functions between SQL and PL/SQL types
CREATE OR REPLACE PACKAGE WRAPPER1 AS
   -- Declare the conversion functions for the PL/SQL type COMPANY.EMP_TBL
        FUNCTION PL2COMPANY_EMP_TBL(aPlsqlItem COMPANY.EMP_TBL)
        RETURN COMPANY_EMP_TBL;
        FUNCTION COMPANY_EMP_TBL2PL(aSqlItem COMPANY_EMP_TBL)
        RETURN COMPANY.EMP_TBL;
...
END WRAPPER1;

さらに、SQLコレクション型がCompanyEmpTbl.javaに公開されます。

PL/SQLのRECORD型の場合と同様に、PL/SQLの索引付き表の型が公開されると、公開結果(Javaラッパー・クラス、SQLコレクション型および変換ファンクションなど)を使用して、そのPL/SQLの索引付き表の型が関係するPL/SQLパッケージを公開できます。たとえば、JPublisherの起動に使用するプロパティ・ファイル(たとえばdone.properties)に次のエントリを追加すると、JPublisherでは指定した型マップが使用され、その索引付き表の型は再公開されません。

jpub.addtypemap=SCOTT.COMPANY.EMP_TBL:CompanyEmpTbl:COMPANY_EMP_TBL:
WRAPPER1.COMPANY_EMP_TBL2PL:WRAPPER1.PL2COMPANY_EMP_TBL

PL/SQL変換ファンクションを直接使用する場合とラッパー・ファンクションを使用する場合

PL/SQL型を使用するストアド・プロシージャの起動コードをJavaで生成する場合、JPublisherでは次のいずれかの操作モードを使用できます。

  • ストアド・プロシージャを直接コールし、これが該当する変換ファンクションを介してPL/SQLの出入力を処理します。

  • PL/SQLラッパー・ファンクションをコールし、ラッパー・ファンクションはストアド・プロシージャをコールし、該当する変換ファンクションを介してPL/SQLの出入力を処理します。JPublisherにより生成されるラッパー・ファンクションは、対応するSQL型を出入力に使用します。

JPublisherで最初のモードを使用するか、第2のモードを使用するか、あるいはどちらのモードも使用しないかは、-plsqlmapオプションで状況に応じて指定します。

一例として、PL/SQLの索引付き表の型EMP_TBLを戻すPL/SQLストアド・プロシージャSCOTT.COMPANY.GET_EMP_TBLを考えてみます。「RECORD型と索引付き表の型のサポートを示すサンプル・パッケージ」で紹介したCOMPANYパッケージが、JPublisherで次のコマンドを使用して処理されるとします。

% jpub -u scott -s COMPANY:Company -plsqlpackage=WRAPPER1
       -plsqlfile=wrapper1.sql,dropper1.sql -plsqlmap=false
Enter scott password: password

JPublisherの出力は次のとおりです。

SCOTT.COMPANY
SCOTT."COMPANY.EMP_REC"
SCOTT."COMPANY.EMP_TBL"
J2T-138, NOTE: Wrote PL/SQL package WRAPPER1 to file wrapper1.sql.
Wrote the dropping script to file dropper1.sql

このコマンドにより、JPublisherでは次の要素が作成されます。

  • PL/SQLのRECORDEMP_RECにマップするSQLオブジェクト型COMPANY_EMP_REC

  • PL/SQLの索引付き表の型EMP_TBLにマップするSQLコレクション型COMPANY_EMP_TBL

  • COMPANYCOMPANY_EMP_RECおよび COMPANY_EMP_TBLにマップするJavaクラス

  • PL/SQLの索引付き表の型とSQLコレクション型の間で変換を行うPL/SQL変換ファンクションを含むPL/SQLパッケージWRAPPER1

この例では、変換ファンクションPL2COMPANY_EMP_TBLがPL/SQLのEMP_TBL型をSQLのCOMPANY_EMP_TBL型に変換します。-plsqlmap=falseに設定されているため、ラッパー・ファンクションは作成されません。生成されたJavaコードでは、次のJDBC文を使用してストアド・プロシージャがコールされます。

conn.prepareOracleCall = 
("BEGIN :1 := WRAPPER1.PL2COMPANY_EMP_TBL(SCOTT.COMPANY.GET_EMP_TBL()) \n; END;");

SCOTT.COMPANY.GET_EMP_TBLが直接にコールされ、そのEMP_TBL出力がPL2COMPANY_EMP_TBL変換ファンクションで処理されて必要なSQL型COMPANY_EMP_TBLが戻されます。

これに対して、-plsqlmap=alwaysに設定してJPublisherを実行すると、WRAPPER1にもPL/SQL型を使用するPL/SQLストアド・プロシージャごとにPL/SQLラッパー・ファンクションが含まれます。この場合、指定のストアド・プロシージャについて生成されたJavaコードは、ストアド・プロシージャではなくラッパー・ファンクションをコールします。この例のラッパー・ファンクションWRAPPER1.GET_EMP_TBLは、元のストアド・プロシージャをコールし、その出力を変換ファンクションを介して処理します。

FUNCTION  GET_EMP_TBL()
   BEGIN 
      RETURN WRAPPER1.PL2COMPANY_EMP_TBL(SCOTT.COMPANY.GET_EMP_TBL()) 
   END;

生成されたJavaコードでは、ラッパー・ファンクションをコールするJDBC文は次のようになります。

conn.prepareOracleCall("BEGIN :1=SCOTT.WRAPPER1.GET_EMP_TBL() \n; END;");

-plsqlmap=trueの場合、JPublisherでは、可能な場合は元のストアド・プロシージャへのダイレクト・コールが使用されます。ただし、直接コールして変換するためのJavaコードが複雑すぎるストアド・プロシージャや、PL/SQL型をOUTまたはIN OUTパラメータとして使用するストアド・プロシージャの場合、JPublisherではラッパー・ファンクションが生成され、そのファンクションが生成されたコード内でコールされます。

JDBCでサポートされないデータ型に対するその他の代替方法

JDBCでサポートされないPL/SQL型にアクセスするためにJPublisherで使用されるメカニズムについては前述しました。この方法でJPublisherを使用するかわりに、次のいずれかの方法を使用できます。

  • その型を使用しないようにPL/SQLメソッドを書きなおします。

  • 次のような無名ブロックを記述します。

    • JDBCでサポートされる入力タイプを、PL/SQLストアド・プロシージャで使用される入力タイプに変換します。

    • PL/SQLストアド・プロシージャで使用される出力タイプを、JDBCでサポートされる出力タイプに変換します。

JPublisherのスタイルとスタイル・ファイル

JPublisherのスタイル・ファイルを使用すると、Java間の型マッピングを指定できます。これにより、生成されるクラスをWebサービスで確実に使用できます。一例として、java.sql.Cloboracle.sql.CLOBなどのCLOB型はWebサービスで使用できませんが、java.lang.StringなどのWebサービスでサポートされている型に変換すると、データを使用できます。JPublisherでは、スタイル・ファイルとJava間の型変換の使用を実装するユーザー・サブクラスを生成する必要があります。

通常、スタイル・ファイルはOracleに用意されていますが、編集や独自作成が必要になる場合があります。

次の項では、スタイルとスタイル・ファイルの機能および使用方法について説明します。

スタイル・ファイルの指定と位置

JPublisherの-styleオプションを使用してスタイル・ファイル名を指定します。

-style=stylename

JPublisherでは、指定したstylenameに基づいて次のようにスタイル・ファイルが検索され、最初に検出されたファイルが使用されます。

  1. CLASSPATH内で次のリソースが検索されます。

    /oracle/jpub/mesg/stylename.properties
    
  2. リソース名または修飾リソース名としてstylenameを使用し、CLASSPATH内で次のリソースが検索されます。

    /stylename-dir/stylename-base.properties
    
  3. ファイル名または修飾ファイル名としてstylenameを使用し、カレント・ディレクトリ内で次のファイルが検索されます。

    stylename.properties
    

    この場合、stylenameには必要に応じてディレクトリ・パスを含めることができます。たとえば-style=mydir/foo設定を使用すると、カレント・ディレクトリに相対のmydir/foo.propertiesが検索されます。

一致するファイルが見つからない場合は、例外が生成されます。

最初の使用例で、リソース/oracle/jpub/mesg/webservices.propertiesORACLE_HOME/sqlj/lib/translator.jarに存在し、CLASSPATH内でtranslator.jarが検出されると、-style=webservices設定では、カレント・ディレクトリにwebservices.propertiesファイルが存在する場合でもtranslator.jar/oracle/jpub/mesg/webservices.propertiesが使用されます。

ただし、-style=mystyleを指定すると、/oracle/jpub/mesg内でリソースmystyle.propertiesが検出されない場合にも、mystyle.propertiesファイルがカレント・ディレクトリにあれば、それが使用されます。


注意:

現在、Oracleには次の3つのスタイル・ファイルが用意されています。
/oracle/jpub/mesg/webservices-common.properties
/oracle/jpub/mesg/webservices10.properties
/oracle/jpub/mesg/webservices9.properties

これらはtranslator.jarファイル内にあり、このファイルをCLASSPATHに含める必要があります。各ファイルが、Oracle JDBC型をWebサービスでサポートされるJava型にマップします。webservices-common.propertiesファイルは汎用であり、webservices10.propertiesおよびwebservices9.propertiesの両方に含まれていることに注意してください。

Oracle Database 11gでWebサービスを使用するには、次のスタイル・ファイルを指定します。

-style=webservices10

Oracle9iのWebサービスを使用するには、-style=webservices9を指定します。


スタイル・ファイルの形式

スタイル・ファイルの主要部分はTRANSFORMATIONセクションです。このセクションは、TRANSFORMATIONタグとEND_TRANSFORMATIONタグの間のすべてです。ここには、オブジェクト属性またはメソッドのシグネチャに使用される型に適用される型変換、つまりJava間のマッピングが記述されています。

利便性を考慮してOPTIONSセクションが用意されており、ここにその他のJPublisherオプション設定を指定できます。このセクションにより、スタイル・ファイルでは、マッピングの指定に加えて他のJPublisherプロパティ・ファイルの機能を置き換えることができます。

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


注意:

以下の説明はスタイル・ファイルに関する一般的な情報です。この情報は変更される可能性があります。

スタイル・ファイルのTRANSFORMATIONセクション

この項では、スタイル・ファイルのTRANSFORMATIONセクションのテンプレートをコメント付きで提供します。TRANSFORMATIONセクションには、指定する各マッピング用のMAPPINGセクションがあります。MAPPINGセクションはMAPPINGタグで始まり、END_MAPPINGタグで終わります。各MAPPINGセクションには、多数のサブタグおよび追加情報が含まれています。MAPPINGセクションでは、SOURCETYPEタグおよびTARGETTYPEタグが必須のサブタグです。通常は、各TARGETTYPEセクションで、少なくともRETURNINおよびOUTのケース情報をそれぞれ対応するタグを使用して指定します。次のコードでは、一般的なTRANSFORMATIONセクションの構造を示します。

TRANSFORMATION

 IMPORT
 # Packages to be imported by the generated classes
 END_IMPORT

 # THE FOLLOWING OPTION ONLY APPLIES TO PL/SQL PACKAGES
 # This interface should be implemented/extended by
 # the methods in the user subclasses and interfaces
 # This option takes no effect when subclass is not generated.
 SUBCLASS_INTERFACE java_interface

 # THE FOLLOWING OPTION ONLY APPLIES TO PL/SQL PACKAGES
 # Each method in the interface and the user subclass should
 # throw this exception (the default SQLException will be caught
 # and re-thrown as an exception specified here)
 # This option takes no effect when subclass is not generated.
 SUBCLASS_EXCEPTION Java_exception_type

 STATIC
 # Any code provided here is inserted at the
 # top level of the generated subclass regardless
 # of the actual types used.
 END_STATIC

 # Enumerate as many MAPPING sections as needed.

 MAPPING
 SOURCETYPE Java_source_type
 # Can be mapped to several target types.
 TARGETTYPE Java_target_type

 # With CONDITION specified, the source-to-target
 # mapping is carried out only when the listed Java
 # classes are present during publishing. 
 # The CONDITION section is optional.
 CONDITION list_of_java_classes

 IN
 # Java code for performing the transformation
 # from source type argument %1 to the target
 # type, assigning it to %2.
 END_IN
 IN_AFTER_CALL
 # Java code for processing IN parameters
 # after procedure call.
 END_IN_AFTER_CALL
 OUT
 # Java code for performaing the transformation
 # from a target type instance %2 to the source
 # type, assigning it to %1.
 END_OUT
 RETURN
 # Java code for performing the transformation
 # from source type argument %1 to the target
 # type and returning the target type.
 END_RETURN

 # Include the code given by a DEFINE...END_DEFINE block
 # at the end of this template file.
 USE defined_name

 # Holder for OUT/INOUT of the type defined by SOURCETYPE.
 HOLDER Java_holder_type
 END_TARGETTYPE

 # More TARGETTYPE sections, as needed

 END_MAPPING

 DEFAULT_HOLDER
 # JPublisher will generate holders for types that do
 # not have HOLDER entries defined in this template.
 # This section includes a template for class definitions
 # from which JPublisher will generate .java files for
 # holder classes.
 END_DEFAULT_HOLDER

 # More MAPPING sections, as needed

 DEFINE defined_name
 # Any code provided here is inserted at the
 # top level of the generated class if the
 # source type is used.
 END_DEFINE
 # More DEFINE sections, as needed

END_TRANSFORMATION

注意:

  • スタイル・ファイルには、ISO8859_1エンコーディングを使用します。このエンコーディングで直接表すことのできない文字は、Unicodeエスケープ・シーケンスで表す必要があります。

  • 複数のMAPPINGセクションで同じSOURCETYPEを指定できます。引数の型の場合、JPublisherでは最後に検出されたMAPPINGセクションが使用されます。



関連項目:

ホルダーの詳細は、「JAX-RPCホルダーを使用した出力パラメータ渡し」を参照してください。

スタイル・ファイルのOPTIONSセクション

スタイル・ファイルのOPTIONSセクションでは、必要なJPublisherオプション設定をJPublisherプロパティ・ファイルの標準形式で指定できます。同様の構文は次のとおりです。

OPTIONS
 # Comments
 jpub.option1=value1
 jpub.option2=value2
 ...
END_OPTIONS

Oracleスタイル・ファイルでの主要なJava間の型マッピングのサマリー

Oracleスタイル・ファイルwebservices-common.propertieswebservices9.propertiesおよびwebservices10.propertiesには、それぞれのSOURCETYPEおよびTARGETTYPE指定を介して、Webサービス・サポート用の多数の重要なJava間の型マッピングおよびREF CURSORのマッピングが指定されています。これらのマッピングを表3-2にまとめてあります。

表3-2 Oracleスタイル・ファイルでのJava間の型マッピングのサマリー

ソースの型 ターゲットの型

oracle.sql.NString

java.lang.String

oracle.sql.CLOB

java.lang.String

oracle.sql.BLOB

byte[]

oracle.sql.BFILE

byte[]

java.sql.Timestamp

java.util.Date

java.sql.ResultSet

oracle.jdbc.rowset.OracleWebRowSet

org.w3c.dom.Document

javax.xml.transform.Source


複数のスタイル・ファイルの使用

JPublisherでは、コマンドラインで複数の-styleオプションを使用して次の動作を指定できます。

  • OPTIONSセクションの連結。

  • TRANSFORMATIONセクションの連結。ただし、MAPPINGセクションのエントリは規定に従ってオーバーライドされます。後からコマンドラインで指定したスタイル・ファイルのMAPPINGエントリが、先にコマンドラインで指定したスタイル・ファイルの、同じSOURCETYPE指定を持つMAPPINGエントリをオーバーライドします。

この機能は、前に定義した型マッピングを上書きする場合や、新しい型マッピングを追加する場合に役立ちます。たとえば、SYS.XMLTYPEjava.lang.Stringにマップする場合、-style=xml2stringの設定をJPublisherのコマンドラインに追加できます。この例では、./xml2string.propertiesスタイル・ファイルがアクセスされるものとします。このスタイル・ファイルの定義は次のとおりです。

      OPTIONS
       jpub.defaulttypemap=SYS.XMLTYPE:oracle.xdb.XMLType
      END_OPTIONS
      TRANSFORM
      MAPPING
      SOURCETYPE oracle.xdb.XMLType
      TARGETTYPE java.lang.String
      # XMLType => String
      OUT
      %2 = null;
      if (%1!=null) %2=%1.getStringVal();
      END_OUT
      # String => XMLType
      IN
      %1 = null;
      if (%2!=null)
      {
        %1 = new %p.%c(_getConnection());
        %1 = %1.createXML(%2);
      }
      END_IN
      END_TARGETTYPE
      END_MAPPING
      END_TRANSFORM

引き続き同じ例で、次のPL/SQLストアド・プロシージャが定義されているとします。

PROCEDURE foo (arg XMLTYPE);

このストアド・プロシージャはベース・クラスで次のようにマップされます。

void foo (arg oracle.xdb.XMLType);

また、ユーザー・サブクラスでは次のようにマップされます。

void foo (arg String);

注意:

JPublisherでは、デフォルトでSYS.XMLTYPEoracle.xdb.XMLTypeにマップされます。