目次


DB2 を XML でプログラムする、第 4 回

Web ベースの DB2 アプリケーションで各種データ・ソースからのデータを統合する

Comments

コンテンツシリーズ

このコンテンツは全#シリーズのパート#です: DB2 を XML でプログラムする、第 4 回

このシリーズの続きに乞うご期待。

このコンテンツはシリーズの一部分です:DB2 を XML でプログラムする、第 4 回

このシリーズの続きに乞うご期待。

はじめに

この記事に記載する DB2 対応のサンプル SOAP ドライバーを使用すれば、明示的マッピングを作成しなくても、SOAP の API を使用して暗黙的に DB2 のストアード・プロシージャーを実行することができます。次世代のデータベース・ドライバーは、データベース接続性を ODBC/JDBC のような下位レベルの API から SOAP や REST などの上位レベルの API に移行させるはずです。その結果、データベースは SOA 世界の表舞台に躍り出ることになるでしょう。

XML データ・モデルに関連するアーキテクチャーの重要な側面だけに焦点を当てるため、この記事での作業の流れはわざと単純にしてあります。GUI に関しても、機能を説明するのに必要最小限なものに抑えています。

サンプルのホテル・データの作成、そしてホテルを検索する SOAP 呼び出しの作成には、Open Travel Alliance XML スキーマを使用しました。アプリケーション・サーバーからクレジット・カードのトランザクションを行うために使用しているのは PayPal API です。

ソース・コードは記事に付属しているので、これをダウンロードしてコンパイルすることができます。ここで前提条件となるのは、DB2 9 がインストール済みで DB2 JCC および XML jar ファイルが Tomcat のクラス・パスに含まれていることです。クレジット・カードのトランザクションをテストする場合には、PayPal Java API をインストールして jar ファイルも同じく Tomcat のクラス・パスに含めてください。さらに、PayPal サンドボックスと取得した API クレデンンシャルの中でアカウントを作成する必要もあります (詳細は PayPal Integration Center を参照)。このクレデンシャル情報は後から article4.java ファイルの setupPaypal () 関数で変更できます。

シナリオ

このシナリオは、ある顧客が Web でホテルの部屋を予約するというものです。まず顧客がログインして自分のプロファイルを取得し、それから都市を指定して選択可能なホテルと宿泊料のリストを取得します。最後にホテルを選択して部屋を予約します。

図 1. 機能レベルのアーキテクチャー
機能レベルのアーキテクチャー
機能レベルのアーキテクチャー

クライアントでの顧客の操作により、Web ブラウザーからアプリケーション・サーバーへの REST 呼び出しが行われることになります。すると、このアプリケーション・サーバーは以下の内容を実行します。

  • JDBC を使用して内部データベースに直接接続し、顧客のプロファイルを取得する。
  • 企業ファイアウォール内側のさらに予約部門の内部ファイアウォールの内側にある別のデータベースに対して SOAP 呼び出しを行う。
  • 外部クレジット・カード・トランザクション・サービス・プロバイダー (PayPal など) に対して REST 呼び出しを行う。
図 2. 設計レベルのアーキテクチャー
設計レベルのアーキテクチャー
設計レベルのアーキテクチャー

具体的な手順

顧客が予約プロセスの各ステップを行うごとに裏で行われていることを理解するため、情報の流れと、その流れを実現するコードを見ていきましょう。

ステップ 1

顧客が旅行代理店の Web サイトで自分の名前を入力し、プロファイルを取得します。説明がややこしくならないように、パスワードは不要で、顧客のプロファイルがあらかじめ代理店のデータベースに入っているという前提にします。

図 3. ログインしてプロファイルを取得する際のコマンドとデータの流れ
ログインしてプロファイルを取得する際のコマンドとデータの流れ
ログインしてプロファイルを取得する際のコマンドとデータの流れ

顧客のプロファイルは XML 文書で、その保管場所はデータベースの XML 列です。クレジット・カード情報も同じく XML 文書ですが、セキュリティーのため、バイナリー・フォーマットに暗号化して保管されています。

リスト 1. customers テーブルの作成とレコードの挿入
CREATE TABLE CUSTOMERS (CUSTID CHARACTER (64) NOT NULL,
CC VARCHAR(1024) for bit data not null, INFO XML NOT NULL )

insert into CUSTOMERS values('hardeep',
encrypt('<CC type="visa" expirydate="12/2009" number="4721930402892796" cvv="808">
<name>hardeep singh</name></CC>' , 'password'),
'<Customer customerid="hardeep" firstname="hardeep" lastname="singh"/>');
図 4. ログイン
ログイン

login ボタンがクリックされると、Javascript 関数の getCustomerInfo() がクライアントから呼び出されます。この関数は、アプリケーション・サーバーの customerinfo サービスを実行するために必要な REST 呼び出しを生成します。

リスト 2. クライアント呼び出しによるユーザー・プロファイルの取得
var cid=document.getElementById("userid").value;
var addr=servletpath+"?cmd=customerinfo&msg="+cid;
var xmlhttpObj= new XMLHttpRequest();
xmlhttpObj.open('GET', addr, true);
xmlhttpObj.onreadystatechange = function() { getCustomerInfoCallback(xmlhttpObj); };
xmlhttpObj.send("");

アプリケーション・サーバーはローカル・データベースに対して SQL クエリーを実行し、customers テーブルの info 列から顧客のプロファイルを選択します。

リスト 3. ユーザー・プロファイルを取得するためのアプリケーション・サーバーによるデータベース・クエリー
Connection conn= DriverManager.getConnection("jdbc:db2:article4");
Statement stmt = conn.createStatement();
stmt.setMaxRows(1);
ResultSet rs= stmt.executeQuery(
"select info from customers where custid='"+msg+"'");
if(rs.next ()) retValue=rs.getString(1);
stmt.close();
conn.close();

データベース・クエリーによって取得された顧客データは、XML データとしてクライアントに送り返されます。

リスト 4. XML に設定されて返されたデータの HTTP ヘッダー
_res.setContentType("text/xml");
 _res.setHeader("Cache-Control", "no-cache");
_res.getWriter().write(retValue);

クライアントはアプリケーション・サーバーから顧客データを受け取ると、getCustomerInfoCallback 関数を呼び出します。これによって、顧客の XML データが XMLParse ラッパー・クラスを使用して DOM ツリーに構文解析され、グローバル変数に保存されます。UI は、ホテルをリストする都市のコードを顧客が入力できるように変更されます。

リスト 5. XML に設定されて返されたデータの HTTP ヘッダー
customerinfo= new xmlparse(xmlhttp.responseXML, false);
var hstr='<table cellSpacing="0" width="100%" cellPadding="2" border="0" align="left">';
hstr+='<tr><td align="right">City Code:</td><td><INPUT type="text" id="citycode"
SIZE=15 MAXLENGTH=50 value="msy" tabindex="1">';
hstr+='<td><INPUT type=button value="submit" onClick="javascript:getRates()" >';
document.getElementById("canvas").innerHTML=hstr;

ステップ 2

このステップでは、顧客が旅行先の都市にあるホテルを検索します。

図 5. ホテルと宿泊料をリストする際のコマンドとデータの流れ
ホテルと宿泊料をリストする際のコマンドとデータの流れ
ホテルと宿泊料をリストする際のコマンドとデータの流れ

ユーザーが都市コードを入力して submit ボタンをクリックすると、クライアント Javascript の getRates () 関数が呼び出されます。

図 6. 都市コードを基準にしたホテルの検索
都市コードを基準にしたホテルの検索

getRates 関数はアプリケーション・サーバーに対してホテル情報を要求するための呼び出しを生成します。呼び出しを生成する際に使用するのは、OTA_HotelAvailRQ XML スキーマです。

リスト 6. OTA_HotelAvailRQ スキーマに従って作成されるホテル検索メッセージ
var citycode=document.getElementById("citycode").value
var req='OTA_HotelSearchRQ xmlns="http://www.opentravel.org/OTA/2003/05"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opentravel.org/OTA/2003/05 OTA_HotelSearchRQ.xsd"
EchoToken="HL" Target="Production" Version="1.003" PrimaryLangID="EN-US"
ResponseType="PropertyList">'+
'<POS><Source AirlineVendorID="FG" PseudoCityCode="MIA" ISOCountry="US"
ISOCurrency="USD" AgentSine="A4444BM" AgentDutyCode="FR"></Source>'+
'<Source><RequestorID Type="5" ID="12345675" ID_Context="IATA"/></Source></POS>'+
'<Criteria><Criterion><RefPoint></RefPoint><CodeRef LocationCode="23"
 CodeContext="OTA-REF code list"/>'+
'<HotelRef HotelCityCode="'+citycode+'"/><Radius Distance="2" DistanceMeasure="MILES"/>'+
'<RoomAmenity RoomAmenity="74"/><RoomAmenity RoomAmenity="123"/></Criterion>
</Criteria></OTA_HotelSearchRQ>';

ホテルをリストするためのこの呼び出しは、AJAX API により、POST リクエストとしてアプリケーション・サーバーに送信されます。

リスト 7. アプリケーション・サーバーに送信されるホテル検索メッセージ
var msg='<request cmd="hotelrates">'+req+'</request>';
var xmlhttpObj= new XMLHttpRequest();
xmlhttpObj.open('POST', servletpath, true);
xmlhttpObj.onreadystatechange = function() { getRatescallback(xmlhttpObj); };
xmlhttpObj.setRequestHeader('content-type', 'text/xml');
xmlhttpObj.send(msg);

アプリケーション・サーバーは article4 データベースの getHotelRates ストアード・プロシージャーに対する SOAP 呼び出しを作成します。このデータベースは http://localhost:8080/article4 に位置し、内部の部門ファイアフォール内で動作しています。ストアード・プロシージャーに引数として渡されるのは、クライアントから受け取った OTA ホテル検索リクエスト (msg) です。

注: SOAP メッセージの SOAPAction プロパティーはデータベース名に設定されます。

リスト 8. アプリケーションによる DB2 getHotelRates ストアード・プロシージャーの SOAP 呼び出し
String body="<db:getHotelRates xmlns:db='http://ibm.com/db2/soap'>"+
"<db:arg>"+msg+"</db:arg></db:getHotelRates>";
return sendURLMessage("http://localhost:8080/article4/db2soapdriver",
body,"http://ibm.com/db2/soap#article4");

SOAP メッセージを作成するために使用できる API はありますが、この記事では基本的な URL 呼び出しコードを使用して、SOAP 呼び出しが HTTP の POST 呼び出しと何ら変わりないことを説明します。つまり、メッセージの本文は標準 XML スキーマに準拠するということです。

注: SOAPAction は、ターゲット・データベースの名前に設定されます。

リスト 9. アプリケーションからの SOAP による DB2 getHotelRates ストアード・プロシージャーの呼び出し
URL u = new URL(url);
URLConnection uc = u.openConnection();
HttpURLConnection connection = (HttpURLConnection) uc;
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("SOAPAction", database_name);
OutputStream out = connection.getOutputStream();
Writer wout = new OutputStreamWriter(out);
 wout.write("<?xml version='1.0'?>\r\n");
>
wout.write("xmlns:SOAP-ENV=");
wout.write("'http://schemas.xmlsoap.org/soap/envelope/' ");
wout.write("xmlns:SOAP-ENC=");
wout.write("'http://schemas.xmlsoap.org/soap/encoding/' " );
wout.write("SOAP-ENV:encodingStyle=");
wout.write("'http://schemas.xmlsoap.org/soap/encoding/' ");
wout.write("xmlns:xsi=");
wout.write("'http://www.w3.org/2001/XMLSchema-instance'> ");
wout.write(" <SOAP-ENV:Body>");
wout.write(msg);
wout.write(" </SOAP-ENV:Body>");
 wout.write("</SOAP-ENV:Envelope>\r\n");

アプリケーション・サーバーはただ単に SOAP ラッパーを作成して URL 呼び出しを実行するだけなので、AJAX のセキュリティー制約で許可されるとしたら、クライアントから直接 SOAP 呼び出しを行うことも同じく可能なはずです。SOAP ドライバーによる Web クライアントからのデータベースの直接呼び出しは確かに可能ですが、このような直接呼び出しはセキュリティー上の理由から望ましくありません。このような事態にならないように SOAP ドライバーを強化する必要があります。

getHotelRates ストアード・プロシージャーは、OTA リクエストで構成された XML 引数を 1 つだけ使用します。XQuery は入力された XML から HotelCityCode を抽出し、これと一致するHotelCityCode 属性を持つすべてのホテルを検索してリストします。

リスト 10. getHotelRates ストアード・プロシージャー
CREATE PROCEDURE getHotelRates( IN request XML )
DYNAMIC RESULT SETS 1
LANGUAGE SQL
BEGIN
DECLARE c_cur CURSOR WITH RETURN FOR
Select XMLQuery('declare namespace ns1 = "http://www.opentravel.org/OTA/2003/05";
$info//ns1:HotelDescriptiveContents' passing info as "info")
from hotel
where xmlexists('declare namespace ns1 = "http://www.opentravel.org/OTA/2003/05";
$info//ns1:HotelDescriptiveContents[@HotelCityCode=$req//ns1:HotelRef/@HotelCityCode]'
passing request as "req", info as "info" );
OPEN c_cur;
END

db2soapdriver からアプリケーション・サーバーに返される SOAP レスポンスは、そのままクライアントに返されます。このことによっても、XML モデルのプログラミングではデータベースが大きな役割を持ち、これによってほとんどの場合、アプリケーション・サーバーの役割はトラフィックの整理という役割にまで軽減されることが浮き彫りになります。

クライアントはアプリケーション・サーバーからのレスポンスを受け取ると、getRatescallback を呼び出します。返された SOAP レスポンスの構文解析に使用されるのは DOM パーサーです。DOM パーサーは、SOAP レスポンスに含まれる名前空間を処理するように構成されます。

リスト 11. クライアントによるアプリケーション・サーバーからの SOAP レスポンスの構文解析
soapxml= new xmlparse(xmlhttp.responseXML, false);
soapxml.xmlRoot.setProperty("SelectionNamespaces",
"xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'
xmlns:db='http://ibm.com/db2/soap'");

var hstr='<table cellSpacing="0" width="100%" cellPadding="2" border="1" align="left">';
hstr+="<tr><td>name<td>rate<td>rooms<td>";

データベースからの結果のそれぞれの行を別の DOM ツリーに抽出し、XPath でナビゲートして関連する情報が抽出されます。そしてクライアントには新しいビューが作成され、そこに、返されたすべてのホテルのリストが表示されます。XPath 呼び出しでは名前空間のエイリアスが使用されることに注意してください。

リスト 12. クライアントによる SOAP 本文からのデータベース結果セットの抽出
soapxml.find("//SOAP-ENV:Body//db:row",null,true);
for(i=0;soapxml.currentFind.length>i;i++)
{
var result=soapxml.getValue("db:col/text()",i);
rateslist=new xmlparse(result,true);
rateslist.xmlRoot.setProperty("SelectionNamespaces",
"xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
xmlns:x='http://www.opentravel.org/OTA/2003/05' ");

 var id=rateslist.getValue("//x:HotelDescriptiveContents/@HotelCode",null);
 var name=rateslist.getValue("//x:HotelName/@HotelShortName",null);
 var rooms=rateslist.getValue("//x:GuestRoomInfo/@Quantity",null);
 var charge=rateslist.getValue("//x:Charge/@Amount",null);

hstr+="<tr><td>"+name+"<td>"+charge+"<td>"+rooms+"<td>
<input type='button' onClick=\"javascript:bookRoom('"+id+"','"+charge+"');
  \" value='select'/>";
}
document.getElementById("canvas").innerHTML=hstr;

ステップ 3

最後のステップでは、顧客がホテルを選択し、そのホテルの部屋を予約します。クレジット・カード情報が顧客のプロファイルから取得され、データベースに保存されます。

図 7. 部屋を予約する際のコマンドとデータの流れ
部屋を予約する際のコマンドとデータの流れ
部屋を予約する際のコマンドとデータの流れ

いよいよ顧客がリストからホテルを選択して部屋を予約する段階にきました。

図 8. ホテルのリストからの部屋の予約
ホテルのリストからの部屋の予約

顧客が select をクリックすると、クライアント Javascript の bookroom 関数が呼び出されます。部屋の予約を要求する XML メッセージは、AJAX API により、POST リクエストとしてアプリケーション・サーバーに送信されます。このリクエストには、ホテル ID、顧客名、予約する部屋の数、そして顧客のクレジット・カードに対する請求金額も含まれます。

リスト 13. クライアントからアプリケーション・サーバーへの REST 呼び出しによる部屋の予約
function bookRoom(hotelid,amount)
{
var cid=document.getElementById("userid").value;
var msg='<request cmd="bookroom"><message><ccinfo units="1" invoice=""
amount="'+amount+'"/><username>'+cid+'</username>
<hotelid>'+hotelid+'</hotelid></message></request>';
var xmlhttpObj= new XMLHttpRequest();
xmlhttpObj.open('POST', servletpath, true);
xmlhttpObj.onreadystatechange = function() { bookRoomcallback(xmlhttpObj); };
xmlhttpObj.setRequestHeader('content-type', 'text/xml');
xmlhttpObj.send(msg);
}

アプリケーション・サーバーは着信メッセージを解析して顧客 ID を抽出します。それからローカル・データベースを呼び出し、customers テーブルからクレジット・カード情報と顧客のプロファイル情報を取得します。

注: クレジット・カード情報は、customers テーブルの暗号化された列に保管されています。サンプル・コードのパスワードはハードコーディングされていますが、実際のシナリオでは、顧客がログインする際に使用したパスワードになるはずです。

リスト 14. アプリケーション・サーバーによる暗号化されたクレジット・カード情報のデータベース・クエリー
XMLParse msgxml=new XMLParse(msg);
String userid=msgxml.getValue("//username/text()");
Connection conn= DriverManager.getConnection("jdbc:db2:article4");
Statement stmt = conn.createStatement();
stmt.setMaxRows(1);
ResultSet rs= stmt.executeQuery("select info,
decrypt_char(CC,'password') from customers where custid='"+userid+"'");
if(rs.next ())
{
String custinfo=rs.getString(1);
String CCInfo=rs.getString(2);

次に、アプリケーション・サーバーは内部の部門ファイアウォールに守られて動作する article4 データベースの bookaroom ストアード・プロシージャーに対する SOAP 呼び出しを作成します。このストアード・プロシージャーに引数として渡されるのは、ホテル ID と顧客のプロファイル情報です。

リスト 15. アプリケーションによる bookaroom ストアード・プロシージャーの SOAP 呼び出し
String hotelid=msgxml.getValue("//hotelid/text()");
String body="<db:bookaroom xmlns:db='http://ibm.com/db2/soap'>"+
"<db:arg>"+hotelid+"</db:arg>"+
"<db:arg>"+custinfo+"</db:arg>"+
"<db:arg></db:arg>"+
"</db:bookaroom>";
String soapstr=sendURLMessage("http://localhost:8080/article4/db2soapdriver",
body,"http://ibm.com/db2/soap#article4");

bookaroom ストアード・プロシージャーは単なるダミー・プロシージャーで、出力引数に常に固定の invoice 値を返します。このストアード・プロシージャーは、db2soapdriver による出力引数の処理と SOAP レスポンスでのその表現を示すことを目的としたものです。

注: これが有効なストアード・プロシージャーで、実際に部屋の予約を行うとしたら、トランザクションを処理するために日付や部屋タイプなどの情報も必要になるはずです。演習としてこのシナリオを拡張するには、日付と部屋の情報を受け入れ、OTA部屋予約メッセージを生成するようにクライアント・コードを強化してください。この場合、予約情報を処理する別のテーブルを追加する必要もあります。

リスト 16. アプリケーション・サーバーによる bookaroom ストアード・プロシージャーの SOAP 呼び出し
create procedure bookaroom (in hotelid varchar(12), in userinfo xml,
  out invoice varchar(64))
language SQL
begin
set invoice = 'INV001';
return 1;
end

SOAP レスポンスのストリングは XML ラッパー・クラスによって DOM オブジェクトとして解析され、請求書番号が XPath 呼び出しによって抽出されます。DB2 のストアード・プロシージャーの呼び出しによる SOAP レスポンスのスキーマを理解するには、db2soapdriver.java を参照してください。

リスト 17. アプリケーション・サーバーによる SOAP レスポンスからの請求書番号の抽出
XMLParse soapXML= new XMLParse(true);
soapXML.createDOM(soapstr,false);
String namespaces= "SOAPENV=http://schemas.xmlsoap.org/soap/envelope/;
db2=http://ibm.com/db2/soap";
soapXML.setNamespaces(namespaces,"=");
String invoice=soapXML.getValue("//db2:out/text()",null);

invoice 値はクライアント・メッセージに設定され、クレジット・カードのトランザクション関数に渡されます。このクレジット・カードのトランザクション結果が、請求情報と併せてクライアントに返されます。

リスト 18. アプリケーション・サーバーによってクライアントに返される CC トランザクションの結果
if(invoice!=null)
{
msgxml.setValue("//ccinfo/@invoice",invoice);
retValue="<invoice='"+invoice+"'>"+makePayment(msgxml,CCInfo)+"</invoice>";

クレジット・カードのトランザクション関数では、クライアント・メッセージからクレジット・カードとショッピング・カートの情報が抽出されます。

リスト 19. アプリケーションによる DOM からのクレジット・カードおよびショッピング・カート情報の抽出
XMLParse ccinfo=new XMLParse(cc);
String units=msg.getValue("//ccinfo/@units");
String invno=msg.getValue("//ccinfo/@invoice");
String amount=msg.getValue("//ccinfo/@amount");
String ctype=ccinfo.getValue("//CC/@type");
String cnumber=ccinfo.getValue("//CC/@number");
String cexpdate=ccinfo.getValue("//CC/@expirydate");
String ccvv=ccinfo.getValue("//CC/@cvv");
String cname=ccinfo.getValue("//CC/name/text()");
String note="Paid by "+cname+" for "+units+" room(s) ";

抽出された情報は、NVP (Name-Value Pair) API によって、PayPal のクレジット・カード・サービスに渡されます。

NVP API は、PayPal のビジネス関数、リスク・マネージメント、そしてビジネス・ロジックとの単純なインターフェースです。NVP API を使用するには基本的に、HTTPS 接続で NVP ストリングを PayPal のサーバーに送信し、同じく NVP ストリングであるレスポンスを処理するだけです。NVP API の呼び出し手順は、以下の基本ステップからなります。

  1. 特定の API メソッドに対する NVP のリクエスト・パラメーター・ストリングを構成します。
  2. 構成したパラメーター・ストリングを HTTPS で PayPal サーバーに送信します。
  3. サーバーからのレスポンスに含まれた NVP を処理します。
リスト 20. PayPal の Web サービスに対する NVP API 呼び出しアプリケーションの抜粋
NVPEncoder encoder = new NVPEncoder();
encoder.add("METHOD","DoDirectPayment");
encoder.add("PAYMENTACTION","Sale");
encoder.add("AMT",amount);
encoder.add("CREDITCARDTYPE",ctype);
encoder.add("ACCT",cnumber);
encoder.add("CVV2",ccvv);
encoder.add("EXPDATE",cexpdate);
encoder.add("FIRSTNAME",cname);
encoder.add("CURRENCYCODE","USD");
 encoder.add("INVNUM",invno);
 encoder.add("CUSTOM",note);
String NVPString = encoder.encode();
String ppresponse = (String) caller.call(NVPString);
NVPDecoder resultValues = new NVPDecoder();
resultValues.decode(ppresponse);
String transactionId = (String)resultValues.get("TRANSACTIONID");
String amt = (String)resultValues.get("AMT");
String avsCode = (String)resultValues.get("AVSCODE");
String cvv2Match = (String)resultValues.get("CVV2MATCH");
String strAck = resultValues.get("ACK");
String strAckSMSG = resultValues.get("L_SHORTMESSAGE0");
String strAckLMSG = resultValues.get("L_LONGMESSAGE0");
String strAckLERR= resultValues.get("L_ERRORCODE0");
if(strAck !=null && !(strAck.equals("Success") || strAck.equals("SuccessWithWarning")))
{
return("PAYPAL Failed "+strAckLERR+" "+strAckSMSG+" "+strAckLMSG );
}

まとめ

Web 指向アーキテクチャーに基づくアプリケーションは、XML データ・モデルを利用することによって設計とコードの複雑さを軽減させます。SOAP や REST などの上位レベルの API を使用してデータベースにアクセスすれば、多種多様なデータベースのデータを統合するのも特別なことではありません。合併とセキュリティー侵害が進化し続ける企業世界では、Web サービスの背後に企業データを隠すというこのブラック・ボックス方式は欠かせない要件となります。このようなアーキテクチャーを確固たるものにするのが XML です。そして、この環境では XML データ・モデルが当然のプログラミング・モデルとなります。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Information Management, XML, SOA and web services
ArticleID=262400
ArticleTitle=DB2 を XML でプログラムする、第 4 回: Web ベースの DB2 アプリケーションで各種データ・ソースからのデータを統合する
publish-date=09202007