はじめに
連載の第3回では、CachéとJavaでアプリケーション開発を行う際の、インターシステムズが提供するテクノロジーについて解説します。Cachéは、従来よりJavaアプリケーションとの連携に定評がありましたが、Cachéオブジェクトを意識せずにJavaによる開発手法を提供する新しいテクノロジー「Jalapeño(ハラペーニョ)」が発表されました。第4回・第5回では、このJalapeñoについて詳しく解説する予定ですが、その前に、Jalapeñoにいたるまでの経緯について触れておきましょう。
対象読者
- アプリケーション・システム開発をしている人
- データベース関連の開発およびメンテナンスをしている人
- JavaやC#でプログラミングしている人
JavaによるDBを利用したアプリケーション開発
JavaでRDBを利用するためにはO/Rマッピングが必要
Javaはオブジェクト指向型言語であり、リレーショナルデータベース(RDB)とは構造が大きく異なります。Javaからデータベースを利用するにはJDBCというAPI(Application Program Interface)を利用します(JavaのSDK内に、RDB製品ごとにドライバが用意されていて、利用するRDBに合わせてインストールします)。
しかし、Javaでクラス定義されたデータモデルとRDBのテーブル構造とのギャップを埋める必要がありました。そのギャップのことを「インピーダンスミスマッチ」といい、その解決のために、開発者による「O/Rマッピング」という作業が必要でした。異なる構造をもつデータモデルを合わせるこの作業は単純作業でしかなく、さらに開発全体の労力の60~70%を費やしているという話も聞きます。もちろんO/Rマッピングを自動化するツールも多く提供されていますが、それぞれに検索方法は異なり、Javaによる開発のメリットは多少損なわれます。Data BindingによってJavaのアクセスロジックが自動生成されるようになっても、特定のRDB製品への依存性は変わっていません。
CACHÉが提供するJava Bindingとは
Cachéも、Javaによる業務アプリケーション開発に対応するため、JDBCへの対応が行なわれたのですが、そのインターフェイスを使う場合に、当初はRDBと同様にインピーダンスミスマッチに対処する必要がありました。その後、Cachéでは、Caché Java Bindingにより、インピーダンスミスマッチの問題は解消され開発の手間は軽減されることになりました。
Caché Java Bindingは、JavaアプリケーションとCachéサーバに含まれるオブジェクトとを相互運用するためのものです。Cachéクラス定義にJavaプロジェクションを定義すると、CachéクラスにアクセスするためのJavaプロキシクラスが自動生成されます。Javaプロキシクラスには、サーバ上のCachéメソッドに一致するメソッドと、オブジェクトプロパティにアクセスするためのメソッドが含まれます。Javaアプリケーション側では、このJavaプロキシクラスと通常のJavaクラスを同じものと認識します。このように生成されたJavaプロキシクラスは、CachéのJavaライブラリ(CacheDB.jar)を使ってクライアントとサーバ間の通信を行います。
CACHÉのJava Bindingによるアプリケーション開発
CACHÉのJava環境のセットアップ
Javaクライアントの実行環境として、Java SDKのバージョン1.3以降を使用する必要があります。また、Cachéの接続に必要なJavaライブラリは、前述した「CacheDB.jar」に含まれています(システム環境変数CLASSPATHに「CacheDB.jar」を加えてください)。Eclipseなどを利用している場合は、「CacheDB.jar」を外部JARとして追加する必要があります。Java BindingのためのJavaプロキシファイルを出力するためには、次の2つの方法があります。どちらの場合も、そのオブジェクトと関連があるクラス(参照、継承元など)はすべて出力されます。
スタジオでプロジェクションウィザードを使用してJava Projectionを設定する
[クラス]メニューの[追加]で表示された[新規プロジェクション]を選択してウィザードを起動します。
プロジェクション名を決めて、次ページでプロジェクションタイプ「%Projection.Java」のパラメータを設定します。Javaファイルを出力するディレクトリ(ROOTDIR
パラメータ)は必ず指定してください。それ以外のパラメータについては、ここでは省略します(Caché Class Referenceを参照)。
ターミナルから$SYSTEM.OBJ.ExportJava()関数を使用する
対象クラス、出力ディレクトリは任意に指定できます。
JavaからのCACHÉへの接続
Java Bindingを行うには、「CacheDB.jar」で提供されているcom.intersys.objectsパッケージを次のようにインポートする必要があります。
import com.intersys.objects.*;
続いて、Database
オブジェクトを用意し、CacheDatabase
クラスのgetDatabase
メソッドを実行して、Cachéと接続します。
Database dbconnection = null; String url="jdbc:Cache://localhost:1972/SAMPLES"; dbconnection = CacheDatabase.getDatabase (url, username, password);
ただし、このままではインスタンスは生成されませんので、Java側でCachéオブジェクトをインスタンス化する処理が必要です。新規インスタンスを生成するか、既存のオブジェクトを開く必要があります。
//インスタンス生成 Person person = null; person = new Person( dbconnection );
//既存オブジェクトのオープン(id = 1のオブジェクトのインスタンス化) Person person = null; Id id = null; id = new Id( 1 ); person = (Person) Person._open( dbconnection, id );
JavaからCachéのデータを取得するには、通常のプロパティの場合は、そのままドットシンタックスを使います。ただし、get
メソッド/set
メソッドが必要です。
//データの取得 (CJTest3.java) /* Fetch some properties */ System.out.println( "ID: " + person.getId() ); System.out.println( "Name: " + person.getName() ); System.out.println( "SSN: " + person.getSSN() ); //データの設定 (CJTest2.java) /* Set some properties */ person.setName("Doe, Joe A"); person.setSSN(generateSSN ());
この例ではデータの設定を行っていますので、Save
メソッドを実行してデータベースに反映する必要があります。
//データベースへの反映
person.save();
埋め込みオブジェクトのデータを取得する場合には、まず埋め込みオブジェクトのインスタンスを生成し、通常のプロパティと同様にget
メソッドを使用します。また、ドットシンタックスを使って直接参照することも可能です。
//インスタンス生成後、参照する場合 (CJTest3.java) /* Attempt to bring in an embedded object */ addr = person.getHome(); System.out.println( "Street: " + addr.getStreet() ); System.out.println( "City: " + addr.getCity() ); System.out.println( "State: " + addr.getState() ); System.out.println( "Zip: " + addr.getZip() ); //次のように直接参照も可能 System.out.println( "State: " + person.getHome().getState() ); System.out.println( "Zip: " + person.getHome().getZip() );
CACHÉのクエリの実行
CacheQuery
オブジェクトとjava.sql.ResultSet
オブジェクトを用意して実行します。
CacheQuery cq = null; java.sql.ResultSet rs = null;
下記の例では、サンプルにあるSample.Person
クラスのByNameクエリを実行しています。
//Cache’クエリを作成し、実行結果をResultSet に格納する // (CJTest6.java) /* Create a ResultSet */ System.out.println( "Creating a ResultSet" ); /* Create a CacheQuery */ cq = new CacheQuery( server, "Sample.Person", "ByName" ); /* Execute the query and loop across the returned rows */ rs = cq.execute(query); while (rs.next()) { /* Dump the columns in each row */ String s = ""; for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) { if (s.length() > 0) { s += ": "; } s += rs.getString( i ); } System.out.println( s ); }
ここでは省略しますが、もちろん動的にクエリを生成して実行することもできます。
インターシステムズのウェブサイトで提供されている「Caché Javaバインディングガイド」では、Javaアプリケーションの作成例など、より詳細な解説が載っています。参考にしてください。