XMLDB開発支援
HOME  >  XMLDB開発支援  >  XML DBプログラミング_2 ~スキーマ変更が及ぼすインパクトを徹底検証する[Java編]

XML DBプログラミング_2 ~スキーマ変更が及ぼすインパクトを徹底検証する[Java編]

Xprioriで始めるXML DBプログラミング
~スキーマ変更が及ぼすインパクトを徹底検証する[Java編]~

2004年12月21日 更新

XML DBを採用する利点については、別稿「徹底比較!RDB vs XML DB」で、「スキーマ変更に対する耐性」という観点から検討した。RDB(リレーショナル・データベース)においてスキーマの変更を施す場合には、対応するアプリケーションの変更はもちろん、テーブル、インデックス、リレーションシップなどあらゆる側面から設計を見直す必要がある。極端な話、たった1つのフィールドを追加するにも、設計からアプリケーション・テストまでの多大な工数を割く必要があるのだ。一方で、XML DBの場合はこのような必要はない。必要なデータを必要なノードツリーに自由に追加することができる。この際、テーブル・レイアウトの再設計は一切必要ないし、インデックスも新規のノードツリーがロードされたタイミングで、自動的に追加されるので、開発者はアプリケーション側の改定だけに集中できる。

このような理論は、上述の記事で理解できただろう。しかし、「理屈だけを聞いていても、なかなか具体的なイメージが湧かない」という方も少なくないはずだ。そこで本稿では、Xprioriを採用して、具体的なXML DBプログラミングに挑戦してみよう。スキーマ変更がシステム全体に影響を及ぼさないXML DBの特性を、実際に手を動かしながら体感してほしい。

Xprioriに初期データを投入する

まずは、「徹底比較!RDB vs XML DB」で使用したコード1を個々の<注文>要素の単位に分解し、Xprioriに初期データとして投入しておこう。初期データは以下のリンクからダウンロードすることができる。
初期データ

初期データの投入は、別稿「Xprioriで始めるXML DBプログラミング ~リレーショナルデータベースからXML DBへのデータ移行を進めよう~」で紹介したXmlStoreクラスを利用してもよいが、ここでは、Xpriori標準の管理コンソールから行う方法について紹介する。

管理コンソールの[Database Access]タブから[Store]を選択し、[XML File]欄に格納したいXMLファイルの絶対パスを指定する。[Store XML]ボタンをクリックして、以下のような成功ステータスが表示されれば成功だ。

[Store XML]の実行結果画面
図1 [Store XML]の実行結果

これをダウンロードしたorder1~3.xmlまで繰り返せばよい。格納に成功したかどうか確かめるには、同じく管理コンソールのメニューから[Query]を選択し、XQuery Targetとして、以下の式を指定する。

/ND/注文

このクエリの結果、以下のように注文データが3件表示されれば成功だ。このように、Xprioriでは、すべての結果が要素の子要素として返される点に注目してほしい。

[Query XML]の実行結果画面
図2 [Query XML]の実行結果

上の例では、投入したすべての注文データを取得しているが、特定の注文番号をキーにして注文データを取得したいならば、以下のように指定すればよい。

/ND/注文[注文番号='XXXX-012-X']

今度は、注文番号が「XXXX-012-X」のデータだけが取得できたはずだ。

JavaアプリケーションからXprioriのデータを取得する

次に、管理コンソール上で行った処理をJavaアプリケーションに実装してみよう。以下は、指定された注文番号をキーにXprioriデータベースを検索し、マッチした注文データをコマンドプロンプト上に表示するサンプルだ。

[XmlSearch.java]
package to.msn.wings.samples;

import java.io.StringReader;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.xml.sax.inputSource;

import com.neocore.httpclient.SessionManagedNeoConnection;

public class XmlSearch {
  public static void main(String[] args) {
    try {
       // データベースへのセッションを確立
      SessionManagedNeoConnection session=
        new SessionManagedNeoConnection("localhost",7700); 
      String id=session.login("Administrator","admin");
       // Xprioriデータベースを検索し、注文情報を取得
      StringReader objSr=new StringReader(
        session.queryXML("/ND/注文[注文番号='XXXX-012-X']"));
       // 取得したXML文字列からDOMツリーを生成
      DocumentBuilderFactory objDbf=DocumentBuilderFactory.newInstance();
      DocumentBuilder objDb=objDbf.newDocumentBuilder();
      Document objDoc=objDb.parse(new inputSource(objSr));
       // 生成したDOMツリーから必要な注文情報を出力
      System.out.println("注文番号:"
        + objDoc.getElementsByTagName("注文番号").item(0)
            .getFirstChild().getNodeValue());
      System.out.println("商品名:"
        + objDoc.getElementsByTagName("商品名").item(0)
            .getFirstChild().getNodeValue());
      System.out.println("購入先名:"
        + objDoc.getElementsByTagName("購入先名").item(0)
            .getFirstChild().getNodeValue());
       // データベースからログアウト
      session.logout();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

queryXMLメソッドは、Xprioriデータベースに対して問い合わせを行い、その結果を文字列で返すためのメソッドだ。ここでは、queryXMLメソッドが返した文字列を元にDOMツリーを生成しているが、Xprioriに対して問い合わせを何度も発行して直接に文字列を取得しても構わない。

以上のコードを実行するには、コマンドプロンプトから以下のコマンドを入力すればよい。

> SET CLASSPATH=".;C:\Xpriori\API\Java\lib\xmsclient.jar;"
> javac ./to/msn/wings/samples/XmlSearch.java
> java to.msn.wings.samples.XmlSearch

注文番号:XXXX-012-X
商品名:工作機械
購入先名:新野電子機器

上のように、注文番号に対応する注文情報が表示されれば、まずは成功だ。

Xprioriのスキーマ情報を変更する

次は、いよいよ本題であるスキーマ情報の変更を行ってみよう。もっとも、XprioriはRDBのように厳密なスキーマを持たない(持つ必要がない)ので、開発者は特にスキーマ変更を意識する必要はない。スキーマ変更が必要になったデータから、適宜、データを投入していけばよいのだ。すでに投入済みのデータを「変更」するのでなければ、既存データへの影響も一切ない。例えば、ここでは以下のような注文データを管理コンソールから投入してみよう。order1~3.xmlと異なる点は、新たに仲介情報を追加している点だ。

[order4.xml]
<?xml version="1.0" encoding="UTF-8" ?>
<注文>
  <注文番号>OOOO-111-0</注文番号>

  <発注個数>10</発注個数>
  <商品情報>
    <商品名>電子回路A</商品名>
    <単価>100</単価>

  </商品情報>
  <購入先情報>
    <購入先名>新野電子機器</購入先名>
    <購入先連絡先>142-888-8888</購入先連絡先>
  </購入先情報>

  <仲介情報>
    <仲介業者名>宮下物産</仲介業者名>
    <営業担当者名>宮下</営業担当者名>
    <仲介業者アドレス>miyashita@miyabussan.xx</仲介業者アドレス> 
    <仲介手数料>5</仲介手数料>

  </仲介情報>
</注文>

Xpriori上での作業はこれだけだ。後は、先ほどのデータ検索用クラスであるXmlSearchに仲介情報を取得できるような変更を加えればよい。以下のサンプルコードの太字部分がXmlSearchクラスからの変更部分になる。

[XmlSearch2.java]
package to.msn.wings.samples;

import java.io.StringReader;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.inputSource;

import com.neocore.httpclient.SessionManagedNeoConnection;

public class XmlSearch2 {
  public static void main(String[] args) {
    try {
      SessionManagedNeoConnection session=
        new SessionManagedNeoConnection("localhost",7700); 
      String id=session.login("Administrator","admin");
      StringReader objSr=new StringReader(
        session.queryXML("/ND/注文[注文番号='OOOO-111-0']"));
      DocumentBuilderFactory objDbf=DocumentBuilderFactory.newInstance();
      DocumentBuilder objDb=objDbf.newDocumentBuilder();
      Document objDoc=objDb.parse(new inputSource(objSr));
      System.out.println("注文番号:"
        + objDoc.getElementsByTagName("注文番号").item(0)
           .getFirstChild().getNodeValue());
      System.out.println("商品名:"
        + objDoc.getElementsByTagName("商品名").item(0)
           .getFirstChild().getNodeValue());
      System.out.println("購入先名:"
        + objDoc.getElementsByTagName("購入先名").item(0)
           .getFirstChild().getNodeValue());
      Element objElm=(Element)objDoc.getElementsByTagName("仲介業者名").item(0);
      if(objElm!=null){
        System.out.println("仲介業者名:"
          + objElm.getFirstChild().getNodeValue());
      }
      session.logout();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

<仲介業者名>要素のように必ずしもすべてのデータに含まれない要素が生じても、XmlSearch2.javaに示したとおりアプリケーション側でnull判定のコードを追加するだけで簡単に対応できる。本稿のサンプルでは、XMLデータのスキーマ変更がアプリケーションに与える影響を分かりやすく解説するために、<仲介業者名>要素についてのみチェックを追加したが、実際の開発では各ノードにあらかじめnull判定のコードを実装しておけば、スキーマ変更時のインパクトはさらに小さくなるだろう。

このコードを実行するには、コマンドプロンプトから以下のコマンドを入力すればよい。

> SET CLASSPATH=".;C:\Xpriori\API\Java\lib\xmsclient.jar;"
> javac ./to/msn/wings/samples/Rdb2Xmldb.java
> java to.msn.wings.samples.Rdb2Xmldb

注文番号:OOOO-111-0
商品名:電子回路A
購入先名:新野電子機器
仲介業者名:宮下物産

以上、スキーマ変更時の実例を見てきたが、このように、XML DBではスキーマの変更がデータベースそのものには何ら影響しないことが分っただろう。必要に応じて必要なデータを追加してさえおけば、開発者はアプリケーションの変更だけに集中できる。同様の対応をRDBで行おうとした場合、テーブル設計の変更からインデックスの再設定、実行計画の再検討などの作業が発生し、ここで示したXML DBのようにはいかないことは、RDBでアプリケーションを構築したことがある方ならば容易に想像できるだろう。

前回と今回はJava言語をベースにXML DBの取り扱い方を説明してきたが、当然ながらXML DBはJavaだけのものではない。次回は同様の操作を.NETアプリケーションから行ってみることにしたい。

企画協力:アイティメディア株式会社
アイティメディア株式会社ロゴ

▲このページのTOPへ

  • XMLとは?IT初心者でもすぐわかるXML超入門
  • 無償で使える!XMLDB「NeoCore」
  • サイバーテック求人情報
  • メールマガジン申し込み
  • TEchScore

  • ▲NeoCoreについて記載されています!

  • ▲XMLマスター教則本です。試験対策はこれでばっちり!
Copyright (c) CyberTech corporation ltd. All ights Reserved. | サイバーテックについて | ご利用ガイド