pureQuery を使用した Java アプリケーションで pureXML データを操作する

pureQuery アプリケーションで pureXML データを操作するための 3 つの手法

IBM® pureQuery と IBM DB2® pureXML™ はどちらも、それぞれの分野で革新的なデータベース技術となっています。pureQuery はハイパフォーマンスの Java™ データ・アクセス・プラットフォームであり、重点が置かれているのは、データベースのデータを使用するアプリケーションの開発および管理タスクを単純化することです。一方の pureXML は DB2 9 で導入されたネイティブ XML データ管理技術で、階層ストレージ技術、XML 照会言語 (XQuery および SQL/XML)、XML 索引付け技術、その他の XML 関連機能で構成されています。この記事では DB2 アプリケーションのパフォーマンスと管理しやすさを最大限に引き出すために、この 2 つの技術を組み合わせ、pureXML データを操作する pureQuery アプリケーションを開発する方法を説明します。

Vitor Rodrigues, Software Engineer, WSO2 Inc

Vitor RodriguesVitor Rodrigues は、IBM Data Studio Developer チームのソフトウェア開発者で、Silicon Valley Lab に勤務しています。コンピューター・サイエンスとシステム・エンジニアリングの専攻でポルトガルの University of Minho を卒業しています。2005年、DB2 Everyplace と DB2 9 pureXML 担当のインターンとして IBM に参加しました。現在の Data Studio Developer チームに加わる前は、DB2 pureXML および IBM Data Studio の Technical Enablement チームの一員として、IBM Toronto Lab、Silicon Valley Lab を拠点として開発に従事していました。


developerWorks 貢献著者レベル

2009年 1月 08日

はじめに

情報をデータベースに保管する Java アプリケーションの開発は、Java アプリケーション開発の典型的なシナリオです。このようなアプリケーション開発は日常茶飯事のように行われていることから、Java データベース・アクセス用の JDBC (Java Database Connectivity) API といった新しい API や、DAO (Data Access Object) パターンなどのデザイン・パターン、そして JDO (Java Data Objects)、EJB (Enterprise Java Beans)、JPA (Java Persistence API)、Hibernate、EclipseLink をはじめとする多数の Java パーシスタンス技術が生まれています。

IBM pureQuery は、Java アプリケーションが最大限のパフォーマンスを発揮できるよう、基本動作であるデータ・アクセスを (SQL を使用して) 透過的に処理すると同時に、Java 開発を容易にする使いやすい機能を兼ね備えた Java データ・アクセス技術です。pureQuery についての詳細は、「参考文献」を参照してください。

これらの技術はほぼ一律にリレーショナル・データベース・システムに重点を置き、ORM (Object-Relational Mapping) サポートを利用しています。リレーショナル・システムに重点が偏っていることから、XML ストレージをサポートするような非リレーショナル・データベース・システムには、このような Java パーシスタンス技術によってすべてをカバーするサポートがありません。

XML ストレージをサポートするシステムの例には、DB2 9 の pureXML 技術が挙げられます。このネイティブ XML データ管理技術は、XML 文書の (そのままの形での) 階層型ストレージ、XML 照会言語、XML 索引付けなどをはじめとするさまざまな機能を提供し、これらの機能と (DB2 を有名にしている) リレーショナル機能との統合を実現します。

この記事で明らかにするのは、pureQuery のデータ・アクセス API は、DB2 pureXML データベースの XML 列に保管された XML 文書に対するクエリー、そして XML 結果セットと一連の Java 技術オブジェクト間のマッピング、の両方をサポートするように簡単に拡張できることです。この 2 つの新技術を統合することによって、pureQuery の生産性とランタイム・パフォーマンスが向上するという利点が XML データベース管理の領域にもたらされます。

この記事では、pureQuery をデータ・アクセス API として使用する Java アプリケーションで DB2 の XML データを操作する手法として、以下の 3 つを検討します。

  • SQL 層による制御
    この手法では、SQL 層で XML 形式とリレーショナル形式との変換を行い、pureQuery が提供する既存の機能でデータを使用できるようにします。
  • データ・アクセス API による制御
    この手法では、pureQuery の API カスタム・ハンドラーに統合した XML マッピング・フレームワーク (この記事では、J2SE V6 のマッピング・ライブラリーを使用) を利用して、XML 文書と Java オブジェクトとの間のマッピングを行います。
  • アプリケーション層による制御
    Java Bean に統合した独自のマッピング・フレームワークを実装し、これらの Bean が、ビジネス・ロジックでデータを表すようにします。

それぞれの手法ごとに、データベースの pureXML データを Java Bean に取り込む方法、そして Java Bean を pureXML データとしてデータベースに保管する方法を説明していきます。


SQL 層による制御

この手法では、SQL 層を使用して XML データを変換します。SQL/XML ステートメントによって XML データをリレーショナル・データに変換し、XQuery 変換式を使用して XML サブ文書を更新します。

図 1 に示すように、XML データ は SQL 層によってリレーショナル・データにマッピングされるため、データベース、データ・アクセス API、Java Bean の間で受け渡されるのはリレーショナル・データのみとなります。

図 1. SQL 層による制御
SQL 層による制御

データのフェッチ - XMLTABLE を使用して XML データをリレーショナル・データとして公開する場合

この手法では Data Studio Developer の複数の pureQuery ツールを使用して pureXML 文書のデータを Java Bean に取り込むため、データをフェッチするという点では開発作業が最小限となるはずです。

DB2 と pureQuery のそれぞれで使用可能な機能を利用して、両方の利点を結びつけるという選択肢もあります。DB2 は XML 文書を操作してリレーショナル・データとして公開するさまざまな機能を提供していますが、単純な SQL/XML ステートメントでも同じ結果を実現することができます。pureQuery には基本的なオブジェクト・リレーショナル・マッピングが用意されているので、SQL/XML クエリーによる結果セットを使用するのは複雑な作業ではありません。

それでは早速、作業に取り掛かることにしましょう。リスト 1 の 3 つのサンプル XML 文書を見てください。それぞれのサンプル文書が、従業員を表しています。

リスト 1. サンプル XML 文書
<employee id="901">
     <name>
          <first>John</first>
          <last>Doe</last>
     </name>
     <office>344</office>
     <salary currency="USD">55000</salary>
</employee>
<employee id="902">
     <name>
          <first>Peter</first>
          <last>Pan</last>
     </name>
     <office>216</office>
     <phone>905-416-5004</phone>
</employee>
<employee id="903">
     <name>
          <first>Mary</first>
          <last>Jones</last>
     </name>
     <office>415</office>
     <phone>905-403-6112</phone>
     <phone>647-504-4546</phone>
     <salary currency="USD">64000</salary>
</employee>

最終的に目指すのは、データベースに対してクエリーを実行して Employee オブジェクトのリストを返す API を実装することです。このリストの各オブジェクトが、employee 表に保管された XML 文書の従業員それぞれを表すことになります。

この 3 つの文書は、XML 型の列を使用して DB2 に保管することができます。リスト 2 に記載する DDL を使用すると、2 つの列のみで構成された「employee」という名前の新しい表を作成することができます。2 つの列のうち、一方は INTEGER 型の id 列、もう一方は、XML 型の doc 列です。

リスト 2. employee 表を作成する DDL ステートメント
create table employee (id int not null primary key, doc XML);

3 つのサンプル文書を employee 表に挿入するには、以下のリスト 3 に記載する SQL ステートメントを実行します。

リスト 3. employee 表へのサンプル文書の挿入
insert into employee values(901, '<employee id="901"><name><first>John</first>
     <last>Doe</last></name><office>344</office>
     <salary currency="USD">55000</salary></employee>');
insert into employee values(902, '<employee id="902"><name><first>Peter</first>
     <last>Pan</last></name><office>216</office>
     <phone>905-416-5004</phone></employee>');
insert into employee values(903, '<employee id="903"><name><first>Mary</first>
     <last>Jones</last></name><office>415</office>
     <phone>905-403-6112</phone><phone>647-504-4546</phone>
     <salary currency="USD">64000</salary></employee>');

文書を employee 表に挿入したら、今度はリスト 4 に記載する XMLTABLE 関数を使用して、pureQuery で使用できるようにサンプル文書をリレーショナル・フォーマットで公開します。

リスト 4. XML 文書から値を抽出する XMLTABLE 関数
SELECT id, X.* FROM employee,
  XMLTABLE ('$d/employee' passing doc as "d" 
   COLUMNS 
      firstname		VARCHAR(5) 	PATH 'name/first',
      lastname		VARCHAR(5) 	PATH 'name/last',
      office		INTEGER 	PATH 'office') AS X

この関数を直接呼び出すことも、このステートメントに基づくビューを作成し、そのビューに対してクエリーを実行することもできます。追加のフィルタリングが必要な場合は、ビューによる方法を採るか、SQL/XML で XMLEXISTS() 節を調べてください。

リスト 4 のステートメントを実行すると、以下の結果が返されます。

リスト 5. XMLTABLE クエリーによる DB2 コマンド行の出力
ID          FIRSTNAME LASTNAME OFFICE     
----------- --------- -------- -----------
        901 John      Doe              344
        902 Peter     Pan              216
        903 Mary      Jones            415

3 record(s) selected.

これでデータはリレーショナル・フォーマットになったので、今度は pureQuery コードに取り掛かります。pureQuery に馴染みのない方のために説明しておくと、オブジェクト・リレーショナル・マッピングを実装する方法には、トップダウン方式、ボトムアップ方式、そしてミート・イン・ザ・ミドル方式の 3 つがあります。これらの方式については記事「Increase productivity in Java database development with new IBM pureQuery tools, Part 1: Overview of pureQuery tools」(developerWorks、2007年9月) で詳しく説明しているので、そちらを読んでください。

すでに SQL/XML ステートメントを作成してあるので、この記事ではボトムアップ方式を採用し、SQL によって Employee Java Bean を生成することにします。

最初に、IBM Data Studio Developer を使用して EmployeeDAO という DAO (Data Access Object) を作成し、このオブジェクトにデータ・アクセス・メソッドを追加します。まずはリスト 4 のステートメントを使用してすべての従業員を取得するメソッドを実装するところから取り掛かりましょう。それには、リスト 6 の Java コードを使用します。

リスト 6. Employee データ・アクセス・オブジェクトの getEmployees メソッド
public static List getEmployees(Data data){
     return data.queryList("SELECT id, X.* FROM employee, " +
          " XMLTABLE ('$d/employee' passing doc as \"d\" " + 
          " COLUMNS " + 
          " firstname          VARCHAR(20)     PATH 'name/first', " +
          " lastname           VARCHAR(20)     PATH 'name/last', " +
          " office             INTEGER         PATH 'office') AS X");
}

これで作業は完了したように見えますが、これですべてではありません。pureQuery ツールを活用するには、マウスを何回かクリックする作業が残っています。ただし、手作業によるコーディングはすべて終わっています。

この例は pureQuery インライン形式で作成していますが、代わりに pureQuery アノテーション付きメソッド形式を使用することもできます (この記事では後で同じ例をアノテーション付きメソッド形式に変換し、pureQuery で静的 SQL を利用します)。pureQuery インライン形式と pureQuery アノテーション付きメソッド形式については、以下の記事で詳しく説明しています。

Java クラスの SQL ステートメントからのボトムアップ方式を使用すると、Data Studio Developer に対し、SQL の結果セットと構造が一致する Java Bean を生成するように指示することができます。その場合の操作は、ステートメントのテキストを右クリックし、pureQuery > Generate pureQuery code の順に選択するだけです (図 2 を参照)。

図 2. SQL ステートメントの pureQuery コードの生成
SQL ステートメントの pureQuery コードの生成

ウィザードの最初の画面 (図 3. を参照) では、Generate bean for result set (結果セット用 Bean の生成) オプションを選択して、パッケージ名とクラス名を入力します。Generate annotated-method interface for SQL statement (SQL ステートメント用アノテーション付きメソッドの生成) オプションのチェック・マークは外してください。

図 3. Bean プロパティーの指定
Bean プロパティーの指定

Next をクリックし、すべてのチェック・ボックスのチェック・マークが外れていることを確認してから (これらのオプションはテスト・クラスやサンプル・アプリケーションなどの便利な機能を提供しますが、この記事で必要なのは Bean のみだからです)、Finish をクリックします。

新しい Java Bean が作成されて pdq.purexml.approach1 パッケージに追加されます。

図 4. pureQuery によって生成された Java ファイル
pureQuery によって生成された Java ファイル

図 4 の Data Studio Developer によって作成された pureQuery.example パッケージには、開発者が pureQuery をすぐに使えるように、いくつかのユーティリティー・メソッドが用意されています。この記事では、そのうちのいくつかのメソッドをサンプル・メイン・アプリケーションで使用します。

Data Studio Developer pureQuery ツールによって Java Bean が生成されたので、早速この Bean を使い始めることができます。DAO をリファクタリングして、getEmployees() メソッドが汎用の List 型ではなく、Employee オブジェクトのリストを明示的に返すように変更します。

そのために必要な変更はたったの 2 つだけで、1 つはメソッド・シグニチャーに対する変更、そしてもう 1 つは pureQuery API 呼び出しに対する変更です。pureQuery には、ステートメントの結果セットを Employee クラスのオブジェクトに変換するように指示します。この情報を API に渡すには、Employee クラスを追加パラメーターとして渡します。リスト 7 はこの変更による結果です。変更されたテキストは太字で示しています。

リスト 7. Employee 型のオブジェクトのリストを返すようになった getEmployees メソッド
public static List<Employee> getEmployees(Data data){
     return data.queryList("SELECT id, X.* FROM employee, " +
          " XMLTABLE ('$d/employee' passing doc as \"d\" " + 
          " COLUMNS " + 
          " firstname          VARCHAR(20)          PATH 'name/first', " +
          " lastname           VARCHAR(20)          PATH 'name/last', " +
          " office             INTEGER              PATH 'office') AS X",
          Employee.class);
}

この例を締めくくるために、単純なサンプル・メイン・アプリケーションを作成して、DAO による XML 文書から Java オブジェクトへの変換をテストします。

図 5 に、サンプル・メイン・アプリケーションと、このアプリケーションの実行によるコンソール出力を併せて記載します。

図 5. サンプル・メイン・アプリケーションとその出力
サンプル・メイン・アプリケーションとその出力

これで手順は完了です。このように、わずかな基本ステップに従うだけで、データベース表の XML データをビジネス・ロジックに取り込めるようになります。

データの保管 - XQuery 変換式を使用してサブ文書の更新を行う場合

XML データに対してクエリーを実行するための、XQuery および XPath 言語の完全サポートに加え、DB2 では XQuery 変換式による XML 文書の更新もサポートします。XQuery 変換を使用して DB2 の XML 文書を更新する方法については、記事「DB2 9.5 で XML を更新する」(developerWorks、2007年10月) を参照してください。

ここで、前のセクションで説明した XMLTABLE ステートメントを使用した例について考えてみましょう。前の例では既存の XML 文書から 4 つのノードの値しかフェッチしていませんでしたが、XML 文書には、抽出対象としているこれらのノードの他にも多数の XML ノードが含まれる可能性があります。そのため、文書全体の更新は推奨されません。文書全体を更新すると、既存の文書が新しい文書で上書きされるため、情報が失われる恐れがあるためです。このようなシナリオでは、サブ文書を更新することによって、既存の XML 文書を更新するのが最善の方法となります。

以下の例で、XQuery 変換式を使用して既存の XML 文書に含まれる 3 つのノードを更新する方法を説明します。

データベース内の 1 人の従業員だけを更新するため、新規 updateEmployee メソッドがデータ・アクセス・オブジェクトに追加されています。

リスト 8. XQuery 変換式によるサブ文書の更新
public static void updateEmployee(Data data, Employee emp){
String sql = "update employee set doc = xmlquery(" +
     "'copy $new := $DOC " +
     "modify (do replace value of $new/employee/name/first with $firstname," +
     "do replace value of $new/employee/name/last with $lastname," +
     "do replace value of $new/employee/office with $office)" +
     "return $new' " +
     "passing cast(:firstname as varchar(20)) as \"firstname\", " +
     "cast(:lastname as varchar(20)) as \"lastname\"," +
     "cast(:office as INTEGER) as \"office\"" +
     ") where id = :id";
data.update(sql, emp);
}

DB2 の XQuery ステートメントは XQuery に渡されるパラメーター・マーカーをサポートするために、passing as 節を使用します。リスト 8 では、Employee Bean の firstname、lastname、office の値を変換ステートメントに渡していますが、ここでは名前付きパラメーターを使用しているため、Java Bean を pureQuery API 呼び出しに渡すだけで済みます。一般的な JDBC API 呼び出しでのように、パラメーターを 1 つずつ設定する必要はありません。pureQuery が、Bean からパラメーターの値を抽出して DB2 に渡すからです。

ここで使用している XQuery 変換式は XMLTABLE ステートメントから完全に独立していること、そして Employee 表の XML 列に保管されている文書のサブ文書が適切に更新されていることに注目してください。更新中に XLM 文書をシリアライズしたり、構文解析したりする必要はまったくありません。それについては、文書内部で直接行われます。

ここで、最初の従業員の苗字を「Rodrigues」に変更するコードをサンプル・アプリケーションに追加して、変更内容をデータベースに保管してください (図 6 を参照)。

図 6. 更新後のサンプル・アプリケーション
更新後のサンプル・アプリケーション

図 6 の出力を見ると、更新が正常に行われて John の苗字が Rodrigues になっていることがわかります。

XQuery 変換式を使用してデータベース内の XML 文書を更新すると、1 つのフィールドだけを更新することができるため、アプリケーションとデータベース間で受け渡されるデータ量を少なくできるという利点もあります。さらに、DOA オブジェクトに新規メソッド、例えば updateEmployeeOffice() を追加して、前にフェッチしたすべてのノードを更新する代わりに、従業員のオフィス情報だけを更新することもできます。このメソッドを、更新された変数を判別する何らかのロジックと組み合わせれば、アプリケーションとデータベースの間で受け渡される情報の量が最小限になり、最終的にはアプリケーションのパフォーマンス、さらには (サーバーでの作業負荷が軽減されるため) データベース・サーバーのパフォーマンスが改善されることになります。

データベースの XML データを Java Bean に取り込むために使用する手法によらず、XQuery 式は常にデータベース内でサブ文書を更新するために使用することができます。データベースから文書全体を取得した場合でも、サブ文書の更新によってソース文書内で個別のノードの値を更新することができます。


データ・アクセス API による制御

この手法では、データ・アクセス API に制御を任せます。この記事のコンテキストでは、pureQuery API に制御を渡し、XML から Java へのマッピング、あるいは Java から XML へのマッピングを実装します (図 7 を参照)。

図 7. データ・アクセス API による制御
データ・アクセス API による制御

pureQuery にはマッピング・フレームワークが組み込まれていませんが、既存のマッピング・フレームワークを正規 pureQuery API 呼び出しにごく簡単に統合できるプラグイン・メカニズムが用意されています。これらのプラグイン・メカニズムは RowHandler、および ResultHandler という名前で、データ行のカスタム・ハンドラー、結果セットのカスタム・ハンドラーをそれぞれサポートします。カスタム・ハンドラーはほとんどの pureQuery API メソッドに渡すことができるので、開発者にとってデータ処理をカスタマイズする際の強力な手段となります。

データのフェッチ - マッピング・フレームワークを使用する場合

一部の Java フレームワークは、XML と Java のマッピングを提供します。よく使われているフレームワークの例としては、Castor、JAXB、JiBX、XMLBeans などがあります (これらのフレームワークについての詳細は、「参考文献」を参照してください)。J2SE V6 でも同じく、JAXB をベースとした XML と Java のマッピング・ライブラリーを提供しています。これらのライブラリーは J2SE V6 インストールの一部となっていて、追加のセットアップが必要ないことから、この記事では J2SE V6 のマッピング・ライブラリーを使用します。

J2SE V6 のマッピング・ライブラリーでは、XML 文書を Java オブジェクトにアンマーシャリングし、Java オブジェクトを XML 文書にマーシャリングするためのマッピングを定義することができます。このマッピングを実装するには、Java クラスに含まれるそれぞれの変数が属性であるか、XML 文書内の要素であるかを宣言するアノテーションを Java Bean に追加します。

複雑な XML 構造の場合、このような Java Bean を作成するのは厄介な作業です。そこで J2SE V6 には、(XML スキーマを前提として) すべての Java Bean をマッピング・プロセスに必要なアノテーションを設定した上で生成するツールが用意されています。

この記事に付属のダウンロード可能プロジェクトには、フォルダー・データ内の XML ファイルと併せ、これらの文書の検証に必要な XML スキーマが含まれています。スキーマ・ファイルは emp.xsd です。

アノテーション付き Java Bean を生成することのできるツールの名前は「xjc」です。これは J2SE V6 インストールの bin フォルダーに置かれています。以下に、xjc で許容されるパラメーターの一部を記載します。

  • -d source_folder - .java ファイルを作成するフォルダー
  • -p package_name - 新規に作成する Java ファイルを含めるパッケージ
  • my_schema.xsd - Bean の生成元とする XSD スキーマ・ファイル

この例での Java Bean を生成するには、ワークスペースから以下のパラメーターを設定してアプリケーションを実行します。

-d src –p pdq.purexml.approach2 data/emp.xsd

図 8 は、ジェネレーターの実行によるコンソール出力です。

図 8. XSD ファイルからの Java クラスの生成
XSD ファイルからの Java クラスの生成

図 8 を見るとわかるように、pdq.purexml.approach2 パッケージには Employee.java と ObjectFactory.java という 2 つの新しいファイルが作成されています。前者のファイルは従業員情報を表す Java Bean で、後者のファイルは XML 文書から Employee オブジェクトを作成するファクトリー・ヘルパー・オブジェクトです。図 9 に、パッケージ・エクスプローラーに表示された生成済みファイルを示します。

図 9. ツールによって生成された Java ファイル
ツールによって生成された Java ファイル

Employee.java ファイルを調べると、いくつかのアノテーションがあることがわかります。これらのアノテーションは、J2SE V6 が Java と XML のマッピングを実装するためのものです。

リスト 9. ツールによって生成された Employee Bean
...
@XmlAccessorType(AccessType.FIELD)
@XmlType(name = "", propOrder = {
    "name",
    "office",
    "phone",
    "salary"
})
@XmlRootElement(name = "employee")
public class Employee {

    protected Name name;
    protected String office;
    protected List<Phone> phone;
    protected Salary salary;
    @XmlAttribute(required = true)
    protected String id;
...

要素または属性のそれぞれが Java 型に変換されることに注目してください。XML 要素の型が xs:simpleType の場合、その要素はネイティブ Java 型に変換されます。それ以外の場合は、その要素の中身を保管するための内部クラスが作成されます (リスト 9 の name、phone、salary を参照)。

Java Bean の作成はこれで完了しました。次のステップでは、pureXML データベースから XML データをフェッチし、データベースからフェッチした XML 文書ごとに Employee オブジェクトを返す pureQuery コードを実装します。

そのためにはまず、JAXBHandler という名前のカスタム RowHandler を作成します。このハンドラーは、前の例で使用した queryList をはじめ、複数の pureQuery API 呼び出しに渡すことができます。

リスト 10. カスタム行ハンドラー、JAXBHandler
public class JAXBHandler implements RowHandler {

     public Employee handle(ResultSet rs, Object arg1) throws SQLException {
          Employee emp = new Employee();
          JAXBContext jContext;
          try {
               jContext = JAXBContext.newInstance("pdq.purexml.approach2");
               Unmarshaller unmarshaller = jContext.createUnmarshaller();
               emp = (Employee)unmarshaller.unmarshal(rs.getBinaryStream(2));
          } catch (JAXBException e) {
               e.printStackTrace();
          }
          emp.setId(rs.getString(1));
          return emp;
     }
}

リスト 10 で宣言している JAXBHandler は、SQL クエリーの結果セットの各行に適用され、行のそれぞれに対して handle メソッドを実行します。JAXBHandler 内では、このメソッドが Unmarshaller オブジェクトを使用して、データベースからフェッチした XML 文書を Employee 型の Java オブジェクトに変換します。リスト 2 の表の宣言で、XML 文書の列が表の 2 番目の列にあったことを覚えているでしょうか。そこで、ResultSet メソッド getBinaryStream(2) を呼び出し、Unmarshaller に渡すバイナリー・ストリームとして結果セットの 2 番目の列をフェッチするように指定します。Unmarshaller はバイナリー・ストリームを受け取ると、これを構文解析して対応する Employee オブジェクトを作成します。

JAXBHandler 行ハンドラーを作成したら、後はこのハンドラーを pureQuery API 呼び出しで使用するだけです。リスト 11 にその一例を記載します。

リスト 11. Employee データ・アクセス・オブジェクトの getEmployees メソッド
public static List<Employee> getEmployees(Data data){
     return data.queryList("select * from employee",new JAXBHandler());
}

リスト 11 の例では、以下のパラメーターを指定して pureQuery メソッド queryList() を呼び出しています。

  • SQL の select ステートメント。データベースの複数の行を取得するために実行されます。
  • RowHandler。返された行のそれぞれを Java オブジェクトに変換するために使用されます。

行ハンドラーを使用して XML を Java Bean にマッピングする上での利点は、データベースからデータをフェッチするための pureQuery API 呼び出しが、リレーショナル表を操作するときに使用する呼び出しと非常によく似ていることです。表に対して「全選択」の SQL クエリーを実行するだけで、表に含まれる従業員すべてのリストを手に入れらることができます。XML データはデータ・アクセス API、つまり pureQuery にシームレスに統合されるため、ソース・データが XML 形式であったという事実は、アプリケーション・レベルではほとんど気付かれません。

極めて単純化したサンプル・アプリケーションを実行してみると、JAXBHandler が実際に pureXML 列のデータを Employee Bean にマッピングする様子がわかります。このアプリケーション・コードとその出力は、図 10 のとおりです。

図 10. マッピングに JAXBHandler を使用するサンプル・アプリケーション
マッピングに JAXBHandler を使用するサンプル・アプリケーション

データの保管 - マッピング・フレームワークを使用する場合

前のセクションでは既存の Java と XML とのマッピング・フレームワークを利用して XML 文書を Java Bean にマッピングしましたが、同じフレームワークを使用して逆のマッピング、つまり Java Bean から XML 文書へのマッピングを行うことができます。

J2SE V6 には XML 文書を Java Bean に変換するためのアンマーシャリング・メソッドだけでなく、Java Bean から XML 文書への変換に使用できるマーシャリング機能も用意されています。

こうした機能は、XML データを含む文書をまるごと更新する際に、大いに役立つはずです。データベースからデータをフェッチした後に、Java オブジェクトのほとんどのフィールド、あるいはすべてのフィールドが変更されている場合には、いくつかの更新ステートメントを個別に実行するよりも、文書全体を置き換えるだけのほうが簡単です。そのような場合、マーシャラーを使用することで、タスクを大幅に単純化することができます。

リスト 12 に、データベース内の特定の従業員のレコードを更新する updateEmployee メソッドを記載します。

リスト 12. Java オブジェクトを XML として保管するための J2SE V6 のマーシャリング機能の使用
public static void updateEmployee(Data data, Employee emp){
     try {
          JAXBContext jContext = JAXBContext.newInstance("pdq.purexml.approach2");
          Marshaller marshaller = jContext.createMarshaller();
          StringWriter sw = new StringWriter();
          marshaller.marshal(emp, sw);	
          data.update("update employee set doc = ? where id = ?", 
                         sw.toString(), emp.getId());
     } catch (JAXBException e) {
          e.printStackTrace();
     }
}

Java オブジェクトをテキスト形式の XML 表現に変換するためのステップは、以下のように、元の XML 文書を Java オブジェクトに変換するステップと同様です。

  1. アプリケーションの JAXB コンテキストを取得します。
  2. マーシャラーを作成します。
  3. Java オブジェクトをマーシャリングし、同じオブジェクトの XML 表現を生成します。

オブジェクトが XML 形式になった後は、通常の SQL の update ステートメントを実行して EMPLOYEE 表内のレコードを更新することができます。

この例のコードは、図 11 に示すような単純なサンプル・アプリケーションを使って簡単にテストすることができます。

図 11. JAXBHandler を使用してデータの保管およびフェッチを実演するサンプル・アプリケーション
JAXBHandler を使用してデータの保管およびフェッチを実演するサンプル・アプリケーション

マッピング・フレームワークを使用して XML と Java との間の変換を行うと、確かに開発タスクは楽になりますが、DB2 からデータをフェッチする際にはシリアライズと構文解析が必要になることに注意してください。J2SE V6 マッピング・ライブラリーは、Employee オブジェクトを作成するために DB2 のデータを構文解析するためです。


アプリケーション層による制御

この手法では、pureXML データと Java Bean との間のマッピングをアプリケーション層で行います。

図 12. アプリケーション層による制御
アプリケーション層による制御

この場合のマッピングは、Java Bean が XML 文書によってクラス変数を設定し、これらのクラス変数から XML文書を作成し直すという方法で実装されます。

図 12 に示しているように、XML データは pureXML データベースからアプリケーション層に送られ、アプリケーション層で Java Bean によって処理されます。

データのフェッチ - Java Bean 内にマッピングを実装する場合

この例では、マッピングは Bean 内部で行われます。pureQuery API は引き続きデータ・アクセス層を提供するために使用されますが、この例ではデータ行を「現状のまま」アプリケーションに返します。つまり、id と doc の 2 つの変数を持つ Employee オブジェクトの形式で返すということです。

Employee Bean には、XML から Java Bean への独自のマッピングを追加機能として実装することができます。これは、複雑なマッピング・フレームワークを作成する代わりに、独自のマッピングを Java Bean の拡張機能として追加するという単純な方法となります。実際のシナリオでは、このマッピングをユーティリティー・ライブラリーで行うと理想的です。こうすれば、アプリケーションの複数のコンポーネントでマッピングを再利用できるからです。

マッピングを実装するには、独自のゲッター・メソッドおよびセッター・メソッドを作成します。データ行を Java Bean として表すために、pureQuery はデータベースからデータをフェッチするときに、Bean の設定メソッドを呼び出して Bean の変数を設定します。通常、これらのセッター・メソッドは pureQuery によって自動的に生成されますが、この手法では XML から Java Bean の他のフィールドへのマッピングを実装するために、開発者自身がメソッドを作成することができます。

この手法でサンプルとして使用する Employee Bean には、データベース表の列を保管するための id フィールドと doc フィールドの他、マッピング・コードによって設定される追加フィールドがいくつかあります。これらの追加フィールドとは、リスト 13 に記載されている firstname、lastname、および office です。

リスト 13. Bean 内でマッピングを行う Employee Bean
public class Employee {

     // Class variables generated by pureQuery code generator
     @Id
     protected int id;
     protected String doc;

     // Additional class variables
     protected String firstname;
     protected String lastname;
     protected int office;

     ...

これらの追加フィールドには、pureQuery が doc 変数を設定するために setDoc() メソッドを呼び出すと、データが設定されます。リスト 14 に示されているように、setDoc メソッドが呼び出されると、Employee Bean はパラメーターの値を doc 変数に割り当てるだけでなく、populateVariables() メソッドを呼び出して他のクラス変数にもデータを設定します。

リスト 14. Employee Bean の setDoc メソッド
public void setDoc(String doc) {
     this.doc = doc;
     populateVariables();
}

XML 文書とクラス変数との間のマッピングを実装するのは、リスト 15 のコードです。この記事では JAXP (Java API for XML Processing) ライブラリーによって XML 文書を構文解析し、一部の XPath 式を評価します (詳細は、「参考文献」を参照)。残念ながら、DB2 の XML バイナリー文書を Java Document オブジェクトに渡すためのメソッドはまだないので、XML 文書は DB2 によってシリアライズされた後に Java ライブラリーで再び構文解析する必要があります。

この点を念頭に置いて、データベースからデータをフェッチするのに最適な手法を決めてください。

データベースから取得した XML 文書のコンテンツを使用して Document のインスタンスを作成する方法、そして XPath 式を適用して firstname、lastname、および office クラス変数を設定するために使用するノードの値を抽出する方法を理解するには、リスト 15 のコードを見てください。

このリストでの XPath 式が、最初の例での XMLTABLE によるビューで使用した式と非常に似ていることにお気付きでしょうか。実際、このステップは同様のステップで、データベース・エンジンではなくクライアント・サイドで実行しているという点が異なるだけです。そのため使用している API はそれぞれに異なりますが、マッピング・ロジックは同じです。つまり、ノードの値を抽出し、これらの値をクラス変数として設定しています。

リスト 15. doc のコンテンツを使用したその他のクラス変数の設定
private void populateVariables(){
try {
     DocumentBuilder builder=DocumentBuilderFactory.newInstance().newDocumentBuilder();
     Document document = builder.parse(new InputSource(new StringReader(this.doc)));
     XPath xpath = XPathFactory.newInstance().newXPath();
     String firstname_expression = "/employee/name/first";
     String lastname_expression = "/employee/name/last";
     String office_expression = "/employee/office";
     String fname = (String)xpath.evaluate(
               firstname_expression, document, XPathConstants.STRING);
     String lname = (String)xpath.evaluate(
               lastname_expression, document, XPathConstants.STRING);
     int office = (new Integer((String)xpath.evaluate(
               office_expression, document, XPathConstants.STRING))).intValue();
     setFirstname(fname);
     setLastname(lname);
     setOffice(office);
} catch (Exception e) {
	//handle exception
}
}

この手法の EmployeeDAO では、すべての従業員レコードを Employee オブジェクトとして取得するために、単に全選択を行い、それによって返されたデータで Employee オブジェクトを作成するように pureQuery に指示します (リスト 16 を参照)。

リスト 16. Employee Bean を返す getEmployees メソッド
public static List<Employee> getEmployees(Data data){
     return data.queryList("select * from employee", Employee.class);
}

pureQuery がリスト 16 の API 呼び出しに従って Employee オブジェクトを作成し、このオブジェクトにデータを設定するときには、doc 変数を設定するために Employee クラスの setDoc メソッドが実行され、そのイベントによって、その他のクラス変数のデータ設定がトリガーされます。

このコードを実行するデモ用のサンプル・アプリケーションは、図 13 を見るとわかるように前の例でのサンプル・アプリケーションと同様です。

図 13. Bean 内マッピングを使用するサンプル・アプリケーション
Bean 内マッピングを使用するサンプル・アプリケーション

図 13 の「Console」ウィンドウの出力を見ると、名前とオフィスのフィールドが Bean 内マッピング・コードによって正しく設定されていることがわかります。

データの保管 - Java Bean 内にマッピングを実装する場合

DB2 pureXML によって保管された XML 文書の中に Java オブジェクトを保管するには、Bean 内マッピングと同じ手法を使用することができます。前の例では set メソッドを作成して使用しましたが、このステップでは、Java Bean のコンテンツを使用して XML 文書を生成する独自の get メソッドを作成する必要があります。これにより、この get メソッドによって生成した XML 文書を、リスト 19 に記載する pureQuery API の update ステートメントに渡すことができます。

この例が複雑にならないよう、Employee Bean のテキスト形式の XML 表現を作成する基本コードを作成しておきました。リスト 17 に、Java Bean を XML 文書に変換するためのコードの一部を記載します。

リスト 17. Employee Bean から XML 文書への単純なマッピング
private void recreateXMLDocument(){
     //create XML textual representation
     StringBuffer sb = new StringBuffer();
     sb.append("<employee>");
     sb.append("<name>");
     sb.append("<first>").append(this.getFirstname()).append("</first>");
     sb.append("<last>").append(this.getLastname()).append("</last>");
     sb.append("</name>");
     sb.append("<office>").append(this.getOffice()).append("</office>");
     sb.append("</employee>");
     this.setDoc(sb.toString());
}

リスト 17recreateXMLDocument メソッドは、Employee Bean の getDoc メソッドが呼び出されるたびに実行されます (リスト 18getDoc メソッド本体を参照)。

リスト 18. getDoc でトリガーされる最新 XML 文書の生成
public String getDoc() {
     //reconstruct doc from contents of other class variables
     recreateXMLDocument();
     return doc;
}

getDoc が実際に doc 変数の中身を返す前に、recreateXMLDocument が実行され、doc には他のクラス変数の値から作成された新規 XML 文書が設定されます。

リスト 19. Bean 内マッピング Employee データ・アクセス・オブジェクトの更新メソッドおよびステートメント
public static void updateEmployee(Data data, Employee emp) {
     data.update("update employee set doc = :doc where id = :id", emp);
}

pureQuery はリスト 19 に記載した update ステートメントのパラメーター値を設定する際に、:docパラメーターの値を渡すためにリスト 18getDoc メソッドを呼び出します。このメソッドにより、Employee データベース表内の doc 列は、updateEmployee() メソッドに引数として渡された emp 変数の XML 表現で更新されます。

ここでも同じく、Java オブジェクトを XML として保管する機能と、XML を Java オブジェクトに取り込む機能の両方を実演するために、サンプル・アプリケーションに多少の変更を加えます。

図 14. Bean 内マッピング用に変更したサンプル・アプリケーション
Bean 内マッピング用に変更したサンプル・アプリケーション

図 14 の「Console」ウィンドウを見ると、従業員の苗字に対する変更が正しくデータベースに維持されていることから、このマッピング・コードが正常に機能することは明らかです。


一にパフォーマンス、二にも三にもパフォーマンス!

あらゆるアプリケーション開発者が最終的な目標とするのは、できるだけ優れたパフォーマンスのアプリケーションを作成することです。この記事では 2 つの技術、pureXML と pureQuery について説明しているので、このセクションではそれぞれの技術でのパフォーマンスに関するアドバイスを提供します。

pureXML でデータベース・パフォーマンスを向上させるには

データベースに関して言えば、優れたパフォーマンスを実現するための鍵を握るのは索引です。このことはおそらく既にご存知だと思いますが、DB2 pureXML には XQuery と SQL/XML 両方のタイプのクエリーを高速化する XML 索引付けの拡張メカニズムがあることをご存知でしょうか。XML 索引はリレーショナル索引と同じ索引ページに保管されるため、リレーショナル索引と比べてアクセス時間はほとんど変わりません。この記事で作成したアプリケーションで使える索引の中で、使用するとよい索引の例を検討する前に、pureXML のパフォーマンスと索引付けについて以下の記事を参照してください。

例えば、ID が 250 よりも大きい番号で、苗字が「Doe」のすべての従業員を選択するとします。従業員 ID は id 列に保管されているため、SQL ステートメントの where 節に範囲の比較を追加することで、このフィルターは簡単に実装することができます。一方、従業員の苗字は doc 列に保管された XML 文書の要素ノードのいずれかに保管されていますが、DB2 pureXML で従業員の苗字をフィルタリングするのは、たいした作業ではありません。DB2 には、SQL/XML 標準に含まれる XMLEXISTS() 関数が用意されています。XML 列をフィルタリングするには、この関数を使用することができます。しかも、XMLEXISTS() を使用すると、XML 列で索引を利用することもできます。一例として、条件を満たす場合に表で全選択を実行する SQL ステートメントは、以下のようになります。

リスト 20. リレーショナル列と XML 列の両方で索引を利用できる SQL ステートメント
SELECT * FROM EMPLOYEE WHERE ID > 250 AND
     XMLEXISTS('$DOC/employee[name/last = "Doe"]')

id 列は表の列の中でも主要な列なので、この列にはすでにリレーショナル索引が作成されています。XML 列にも索引を作成すれば、クエリーのパフォーマンスをさらに改善することができます。こうすれば、従業員の苗字の検索をはるかに短時間で評価できるようになります。XML 索引は、通常の SQL の create index ステートメントに XML 固有の節を追加することで作成することができます (リスト 21 を参照)。

リスト 21. XML 文書の苗字のノード値に索引を作成する CREATE INDEX ステートメント
CREATE INDEX FNAME_IDX ON DB2ADMIN.EMPLOYEE(DOC)
     GENERATE KEY USING XMLPATTERN '/employee/name/last'
     AS SQL VARCHAR(25)

嬉しいことに、この記事で説明した手法ではいずれも、上記で作成した索引を使ってデータベースのデータをビジネス・ロジックに取り込むことができます。そのための準備は、索引を作成して where 節を SQL の select ステートメントに追加するだけです。

pureXML ストレージのパフォーマンスを改善するためのその他のアドバイスについては、記事「DB2 9 での pureXML パフォーマンスのための 15 のベスト・プラクティス」(2008年1月) を読んでください。

pureQuery で Java アプリケーションのパフォーマンスを向上させるには

データベースでの pureXML データ・アクセスのパフォーマンスを改善する方法についてのアドバイスをいくつか説明したところで、次はアプリケーションのパフォーマンスに目を向けます。

pureQuery で重点を置いているのは、Java アプリケーションのデータ・アクセス・メカニズムを改善することです。そのために pureQuery では、静的 SQL の使用に基づく予測可能な卓越したパフォーマンス、問題判別、既存の Java データ・アクセス・アプリケーションの最適化、開発ツールをはじめとする、数多くの重要な機能を提供しています。

pureQuery の一部のツールと API に関するアドバイス、それによって開発者の生産性が大幅に向上する仕組みについては、すでに説明したとおりです。

このセクションでは、Java アプリケーションでのデータ・アクセスのパフォーマンスを向上させる方法を探るために、サンプル・アプリケーションを静的 SQL としてデプロイして実行します。pureQuery では、実行時に動的 SQL と静的 SQL を切り替えられるようになっています。このため、開発者は開発段階では作業を迅速かつ簡単に行うために動的 SQL を利用し、開発後は予測可能な高いパフォーマンスをもたらす静的 SQL に切り替えることができます。

DB2 での静的 SQL についての知識が十分にない場合には、先に進む前に、以下の 2 つの記事を読んでください。

pureQuery 使用したアプリケーションで静的 SQL を使用可能にするには、以下の 2 つの方法があります。

  • Java アノテーションまたは XML マッピング・ファイル (JPA XML マッピング・ファイルと同じフォーマットを使用) のいずれかを使用して、pureQuery アノテーション付きインターフェースにデータ・アクセス層を定義します。
  • pureQuery クライアント最適化機能を使用します。クライアントを最適化することによってアプリケーション・コードを変更せずに、既存の JDBC 動的アプリケーションが pureQuery を介して静的 SQL を使用できるようにします。

ここでは、pureQuery アノテーション付きインターフェースを使用して既存のデータ・アクセスをデータベース内で静的 SQL としてバインドします。まず始めに、手法 1 で使用した既存の EmployeeDAO を変換する必要がありますが、他の 2 つの手法の場合は同様のアノテーション付きインターフェースを作成するので構いません。

pureQuery クライアント最適化機能を使用してみたいという方は、チュートリアル「Optimize your existing JDBC applications using pureQuery」(developerWorks、2008年8月) を参照してください。

pureQuery API では、Java インターフェースのメソッド宣言のところで使用できるアノテーションを導入しており、そのメソッドに SQL ステートメントを関連付けることができます。この表現により、pureQuery ツールはこのデータ・アクセス層をデータベース内の静的 SQL としてバインドすることができたり、実行時に静的 SQL または動的 SQL のいずれかとして実行可能なインターフェースの実装を生成することができたりします。これらのアノテーションは、@Call@Select@Update です。それぞれの名前は、実行対象の SQL ステートメントのタイプを反映しています。

手法 1 の既存の EmployeeDAO を pureQuery アノテーション付きメソッド・インターフェースにマイグレーションするのは簡単です。EmployeeDAO クラスのメソッド・シグニチャーをコピーし、SQL ステートメントをメソッド内部から Java メソッド宣言の前にある pureQuery アノテーションの本体に移動すればよいだけです。

リスト 22. EmployeeDAO からアノテーション付きメソッド・インターフェースへの変換
public interface EmployeeData extends Data {

@Select(sql = "SELECT id, X.* FROM employee, "
     + " XMLTABLE ('$d/employee' passing doc as \"d\" " + " COLUMNS "
     + " firstname     VARCHAR(20)     PATH 'name/first', "
     + " lastname      VARCHAR(20)     PATH 'name/last', "
     + " office        INTEGER         PATH 'office') AS X")
public List<Employee> getEmployees();

@Update(sql = "update employee set doc = xmlquery("
     + "'copy $new := $DOC "
     + "modify (     do replace value of $new/employee/name/first with $firstname,"
     + "             do replace value of $new/employee/name/last with $lastname,"
     + "             do replace value of $new/employee/office with $office)"
     + "return $new' "
     + "passing      cast(:firstname as varchar(20)) as \"firstname\", "
     + "             cast(:lastname as varchar(20)) as \"lastname\","
     + "             cast(:office as INTEGER) as \"office\"" + ") where id = :id")
public void updateEmployee(Employee emp);
}

リスト 22 に示されているように、メソッドの本体は除去され、SQL ステートメントは @Select および @Update アノテーションの sql パラメーターに移動されています。Data Studio Developer に組み込まれた pureQuery ツールは、Java プロジェクトが作成されるたびに起動され、アノテーション付きメソッド・インターフェースの有無をチェックします。アノテーション付きメソッド・インターフェースが見つかると、pureQuery コード・ジェネレーターが実行されて、該当するインターフェースごとに実装クラスが生成されます (図 15 を参照)。

図 15. アノテーション付きインターフェースと自動的に生成された実装クラス
アノテーション付きインターフェースと自動的に生成された実装クラス

生成されたインターフェースは、インターフェースに定義されたデータ・アクセスを実装するために、宣言済み SQL ステートメントの呼び出しを作成し、SQL 結果セットとメソッドの戻り型とのマッピング、あるいはメソッド・パラメーターと SQL ステートメントのパラメーター・マーカー (存在する場合) とのマッピングを実装します。

このデータ・アクセス層を静的 SQL としてデータベースにバインドするには、パッケージ・エクスプローラーで EmployeeData.java ファイルを右クリックし、pureQuery > Bind… の順に選択します (図 16 を参照)。

図 16. アノテーション付きメソッド・インターフェースのバインド
アノテーション付きメソッド・インターフェースのバインド

バインド・プロセスが実行されると、コンソール・ウィンドウに Data Studio Developer からのメッセージが表示され、インターフェースを正常にバインドできたか、またはインターフェースのバインドに失敗したかが示されます (図 17 を参照)。

図 17. バインド操作による結果
バインド操作による結果

プロジェクトに複数のアノテーション付きメソッド・インターフェースが含まれる場合、1 つずつバインドすることも、すべて同時にバインドすることもできます。すべてのインターフェースを同時にバインドするには、インターフェースではなくプロジェクトを選択して右クリックし、pureQuery > Bind pureQuery Application の順に選択します。

アプリケーションを動的モードではなく静的モードで実行するには、pureQuery に静的モードでの実行を指示するランタイム・フラグを設定する必要があります。このフラグの名前は「pdq.executionMode」で、EmployeeData インターフェースの実装を要求する際に SampleUtil クラスに渡すことができます。

図 18. 静的 SQL を使用したサンプル・アプリケーションの実行
静的 SQL を使用したサンプル・アプリケーションの実行

図 18 のコードは、ランタイム・プロパティー pdq.executionMode の値を STATIC に設定した上で、このプロパティーを SampleUtil.getData メソッドに渡しています。このメソッドが、リスト 22 で宣言したメソッド形式インターフェースのインスタンス・クラスを作成します。このアプリケーションは、すべてのデータベース呼び出しで実行される SQL ステートメントに対して事前にコンパイルされたアクセス・パスを実行するという点を除き、前の例で使用したサンプル・アプリケーションと同じです。

pureQuery の中で静的 SQL を利用するだけでなく、その他の pureQuery のベスト・プラクティスについても認識しておくために、pureQuery アプリケーションの開発を始める前には記事「pureQuery Best Practices」(developerWorks、2008年8月) を読んでください。簡単に適用できるこれらのべスト・プラクティスによって、アプリケーションのパフォーマンスとメモリー使用量に大きなメリットがもたらされるはずです。


まとめ

この記事では、同じソリューションのなかで pureQuery と pureXML を組み合わせるための 3 通りのパラダイムを説明しました。他にもこれと同じ目標を達成する方法はあるかもしれませんが、この 2 つの技術をマージするには、この記事で提案したパラダイムが最も一般的です。

どの手法を使用するかは、複数の要因によって決まります。以下の表に、それぞれの手法の利点と欠点を記載するので、決定する際の参考にしてください。

表 1. データベースからのデータのフェッチ
手法利点欠点
SQL 層による制御 (XMLTABLE 関数を使用)
  • オブジェクトと表の間のマッピングを実装する既存の pureQuery マッピング機能を利用できるため、開発作業が減ることになります。
  • 必要なフィールドのみがフェッチされるため、受け渡されるデータ量が少なくなります。
  • 必要なフィールドの数が増えると、SQL/XML ステートメントが長くなり、複雑になります。
  • 要件が変更された場合、SQL/XML ステートメントと Bean の両方を更新しなければならなくなります。
データ・アクセス API による制御 (J2SE V6 マッピング・ライブラリーを使用)
  • アプリケーション層と SQL 層はマッピングに気付かないため、要件が変更されてもこの 2 つの層には影響がありません。
  • Bean とマッピング・コードを新規に生成することによって要件の変更を効率的に取り入れるツールを提供します。
  • SQL ステートメントは簡潔で、マッピングはフレームワークによって行われるため、開発者にとっての作業負荷が他の 2 つの方法よりも軽くなります。
  • サイズの大きな XSD ファイルの場合、Java オブジェクト階層がかなり複雑になります。
  • 文書全体をフェッチするため、受け渡されるデータ量が最大限になります。これによって、ランタイム・パフォーマンスが問題になる可能性があります。
アプリケーション層による制御 (カスタム Bean 内マッピングを使用)
  • フェッチするフィールドの数を増減するとしても、Bean 内マッピングを変更するだけで済みます。データ・アクセス API と SQL 層はこの変更に気付きません。
  • 複数の Bean に、同じ SQL ステートメントに対する異なる内部マッピングを簡単に接続できるため、1 つの要件、あるいは一連の要件を満たす Bean を作成することができます。
  • マッピングを実装するための追加作業が必要になります。
  • 文書全体をフェッチするため、受け渡されるデータ量が最大限になります。これによって、ランタイム・パフォーマンスが問題になる可能性があります。
表 2. データベース内へのデータの保管
手法利点欠点
SQL 層による制御 (XQuery 変換式を使用)
  • 必要なフィールドだけを更新して、受け渡されるデータ量を最小限にします。
  • 1 つのステートメントで複数のノードの値を更新することができます。
  • 多数のノードを更新するには、複雑な XQuery ステートメントが必要になってきます。
  • 順番に更新するノードを識別するために、複雑なロジックが必要になる場合があります。
データ・アクセス API による制御 (J2SE V6 マッピング・ライブラリーを使用)
  • XML に自動的にマーシャリングされます。
  • 新規の Bean とマッピング・コードを生成するツールを実行することで、要件の変更に対応できます。
  • 文書全体を更新するため、受け渡されるデータ量が最大限になります。
アプリケーション層による制御 (カスタム Bean 内マッピングを使用)
  • データ・アクセス層は、マッピングに気付きません。
  • 何も変更されていない場合には XML 文書を再作成しないようにするロジックを追加することができます。
  • シリアライズを実装するために、開発者が追加の作業を行う必要があります。
  • 元の XML からすべてのフィールドが抽出されなかった場合、データベースからフェッチしたデータが更新時に失われないことを確実にするには、マッピングを慎重に設計する必要があります。
  • 文書全体を更新するため、受け渡されるデータ量が最大限になります。

市場に登場してからわずか数年のうちに、DB2 pureXML サポートは半構造化データを管理する代表的な技術となり、多種多様なカスタマーがミッション・クリティカルなシステムでその威力を活用するようになりました。DB2 pureXML のサクセス・ストーリーについて詳しく調べるには、DB2 pureXML の Web サイト (「参考文献」を参照) にアクセスしてください。

pureQuery は登場してから 1 年も経たないうちに、分散 DB2 サーバーおよびメインフレーム DB2 サーバーの両方にとって Java データ・アクセスを最適化する上で欠かせない技術であることが証明されました。その理由は主に、そのシームレスな静的 SQL のサポートと JDBC ベスト・プラクティスの実施によるものです。

この記事は、読者の皆さんがこの 2 つの技術を組み合わせて自分たちの環境で使用し、ソリューションのパフォーマンス、セキュリティー、管理性、そして問題判別能力をさらに高め、投資収益率の増大を実現できるようにすることを目標に書かれました。

カスタマーからよく聞かれる代表的な 2 つの質問は、pureXML と pureQuery の相性、そして pureQuery によって pureXML を使用する方法についての質問です。この記事では両方の質問に対する答えとなるように、それぞれの技術の違いを説明するとともに、この 2 つの技術を統合する方法を説明しました。


サンプル・コードについて

ダウンロード」セクションに、Data Studio Developer プロジェクト (Java プロジェクト) を用意してあります。記事で使用したすべてのサンプル・コードは、このプロジェクトを使用して開発しました。

この .zip ファイルには、記事で使用したサンプル XML 文書と XML スキーマ・ファイルも含まれています。また、Employee 表を作成するための SQL スクリプトもあります。

DB2 JDBC ドライバーおよび pureQuery .jar ファイルは、この .zip ファイルには含まれていません。Data studio Developer で pureQuery がサポートされる場合には、pureQuery サポートをプロジェクトに追加すると (追加するには、プロジェクトを右クリックし、pureQuery > Add pureQuery support の順に選択)、このドライバーとファイルが自動的に追加されます。

サンプルを「データ・アクセス API による制御」と「アプリケーション層による制御」の手法で実行するには、お使いのシステムに J2SE V6 をインストールして、このプロジェクトの Java ランタイム環境として使用する必要があります。


謝辞

この記事をレビューしてくれた、DB2 pureXML Enablement チームの Bryan Patterson 氏と Cindy Saracco 氏、Data Studio Enablement チームの Kathy Zeidenstein 氏、そして InferData のVladimir Blackvanski 氏に感謝いたします。


ダウンロード

内容ファイル名サイズ
Data Studio project with sample codepdq_xml_dsd_project.zip62KB

参考文献

学ぶために

製品や技術を入手するために

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Information Management, XML, Java technology
ArticleID=369269
ArticleTitle=pureQuery を使用した Java アプリケーションで pureXML データを操作する
publish-date=01082009