Java バインディングの使用法
この章では、Java アプリケーション内での Caché Java バインディングの使用例について詳しく説明します。
Java プロキシ・クラスの生成
Caché クラスの Java プロジェクションを生成するには、Caché クラスのコンパイル時に、必ず Java クラスが自動的に生成されるように指定します。そのためには、Caché クラスにプロジェクション定義を追加します。このプロジェクション定義により、クラスをコンパイルすると、そのクラスのJava コードもクラス・コンパイラによって必ず生成されます。
そのプロセスは、以下のとおりです。
-
スタジオで、クラスのネームスペースに接続し、そのクラスを開きます。
-
スタジオの新規プロジェクション・ウィザードを使用して、クラスに Java プロジェクション定義を追加します ([クラス] メニューの [追加] サブメニューで [新規プロジェクション] を選択します)。
-
プロジェクションの名前を選択後、%Projection.JavaOpens in a new tab タイプを指定します。
-
生成された Java クラスが書き込まれるディレクトリを指定する ROOTDIR パラメータを入力します。
-
Caché クラスをコンパイルします。コンパイルをスタジオから実行したか、ターミナルのコマンド行から実行したかにかかわらず、クラスの Java プロジェクションが生成されます。
この時点で、以下のようなコード行がクラス定義に追加されます。
Projection PrjName As %Projection.Java;
PrjName はプロジェクションの名前です。
これで、javac コマンドなどのツールを使用して、Java クラスをコンパイルできます。Caché を変更、コンパイルするたびに、プロジェクションは、投影された Java クラスを自動的に更新します。
生成された Java プロジェクション・コードを直接変更したり、カスタムの Java 接続コードを追加したりしないでください。これらを行うと、予期しない深刻な結果が生じる場合があります。生成されるコードは、予告なく変更される可能性がある InterSystems 内部コードに依存します。
Caché クラスからの Java クラスの生成
Caché クラスを Java クライアントから使用するには、Java クラスを生成してクライアント側で実行します。
Caché クラスにプロジェクション定義を追加すると、Caché クラスのコンパイル時に、必ず Java クラスが自動的に生成されるようになります。このプロジェクション定義により、クラスをコンパイルすると、そのクラスのJava コードもクラス・コンパイラによって必ず生成されます。詳細は、"スタジオの使用法" にある "プロジェクション" の章を参照してください。
以下のように、Java クラスを生成します。
-
スタジオで、クラスのネームスペースに接続して、そのクラスを開きます。例えば Person サンプル・クラスを使用する場合は、SAMPLES ネームスペースに接続し、Sample パッケージの Person クラスを開きます。
-
スタジオの新規プロジェクション・ウィザードを使用して、クラスに Java プロジェクション定義を追加します ([クラス] メニューの [追加] サブメニューで [新規プロジェクション] を選択します)。
-
プロジェクションの名前を選択後、%Projection.JavaOpens in a new tab タイプを指定します。
-
ROOTDIR パラメータに、生成された Java クラスを格納するディレクトリを入力します。
-
[新規プロジェクション・ウィザード] の最後の画面で、[完了] をクリックします。この時点で、ウィザードは、以下のようなコード行をクラス定義に追加します。
Projection MyProjection As %Projection.Java(ROOTDIR="C:\temp\");
-
Caché クラスをコンパイルします。コンパイルをスタジオから実行したか、ターミナルのコマンド行から実行したかにかかわらず、クラスの Java プロジェクションが生成されます。
-
Java クラスをコンパイルします。javac コマンド、または Java クラスのコンパイルに使用する他のツールのいずれかでコンパイルできます。
オブジェクトの使用法
Caché Java バインディング・アプリケーションは非常にシンプルです。以下は、完全なサンプル・プログラムです。
import com.intersys.objects.*;
public class TinyBind {
public static void main( String[] args ) {
try {
// Connect to the Cache' database
String url="jdbc:Cache://localhost:1972/SAMPLES";
String username="_SYSTEM";
String password="SYS";
Database dbconnection =
CacheDatabase.getDatabase (url, username, password);
// Create and use a Cache' object
Sample.Person person = new Sample.Person( dbconnection );
person.setName("Doe, Joe A");
System.out.println( "Name: " + person.getName() );
}
// Handle exceptions
catch (CacheException ex) {
System.out.println( "Caught exception: " +
ex.getClass().getName() + ": " + ex.getMessage() );
}
}
}
このコードは以下の動作を実行します。
-
com.intersys.objects.* パッケージをインポートします。
-
Caché データベースに接続します。
-
Caché データベースへの接続に必要な情報を定義します。
-
Database オブジェクト (dbconnection) を作成します。
-
Caché オブジェクトを作成し、使用します。
-
-
Database オブジェクトを使用して、Caché Sample.PersonOpens in a new tab クラスのインスタンスを作成します。
-
Sample.PersonOpens in a new tab オブジェクトの Name プロパティを設定します。
-
Name プロパティを取得し、出力します。
-
標準の例外処理を実行します。
-
以下のセクションでは、これらの基本処理について詳しく説明します。
Connection オブジェクトの生成
CacheDatabase クラスは、特定の Caché サーバとネームスペースへの接続を管理する Java クラスです。このクラスには、接続を確立するためのスタティック・メソッド getDatabase() があります。このメソッドは、Database インタフェースから取得される Caché データベースへの接続を返します。
接続を確立するには、以下の手順を実行します。
-
適切なパッケージをインポートします。これには、CacheDatabase を収めた com.intersys.objects.* パッケージが必ず含まれている必要があります。
import com.intersys.objects.*;
-
次に、接続に使用する変数を宣言し、インスタンスを生成します。
Database dbconnection = null; String url="jdbc:Cache://localhost:1972/NAMESPACE_NAME"; String username="_SYSTEM"; String password="sys";
getDatabase() メソッドにより、Java クライアントから Caché サーバへの TCP/IP 接続が確立されます。このメソッドは 3 つの引数を取ります。最初の引数には、IP アドレス (ここでは、ローカル・ホスト 127.0.0.1)、ポート番号 (ここでは 1972)、およびネームスペース (ここでは SAMPLES) を指定します。2 番目と 3 番目の引数には、サーバにログインするためのユーザ名とパスワードをそれぞれ指定します。
このメソッドを実行すると、dbconnection と呼ばれる Database オブジェクトが返されます。その後、getDatabase() を使用して接続を確立します。
dbconnection = CacheDatabase.getDatabase(url, username, password);
Java 標準の JDBC接続インタフェースを使用して接続を確立し、クエリを実行することもできます。詳細は、"JDBC での Caché の使用法" の "接続のための DriverManager の使用法" を参照してください。
プロキシ・オブジェクトの作成とオープン
以下のコードは、ローカル Caché サーバへの接続を試行します。
String url="jdbc:Cache://localhost:1972/SAMPLES";
String username="_SYSTEM";
String password="sys";
//...
dbconnection = CacheDatabase.getDatabase (url, username, password);
次に、標準の Java 機能を使用し、オブジェクトを開いて値を取得するための ID を入力するようユーザに要求します。ID が存在する場合、指定されたオブジェクトを以下の手順で開きます。
person = (Sample.Person)Sample.Person._open(dbconnection, new Id(strID));
このコードは、Sample パッケージにある Person オブジェクトの _open() メソッドを呼び出します。このメソッドは 2 つの引数を取ります。その 1 つには開くオブジェクトが格納されているデータベースを指定し、もう 1 つには開くオブジェクトの ID を指定します。_open() は Persistent クラスから継承されているので、このクラスのインスタンスを返します。したがって、ここでは、Sample.PersonOpens in a new tab のインスタンスに限定 (キャスト) された値が返されます。
メソッドとプロパティの使用法
オブジェクトを開くと、プログラムによって、そのオブジェクトの Name プロパティの値が表示されます。
System.out.println("Name: " + person.getName());
オブジェクト・プロパティへの参照は、Caché サーバと異なり、プロパティ自体を直接参照するのではなく、get() メソッドと set() メソッドを介して行うことに注意してください。
次に、City プロパティの値を表示し、その後このプロパティに新しい値を割り当てます。
System.out.println("City: " + person.getHome().getCity());
person.getHome().setCity("Ulan Bator");
City プロパティを処理するコード行は、埋め込みオブジェクトのプロパティの状態と変更を示します。(Home プロパティのように) プロパティがオブジェクトの場合、そのオブジェクトには、アクセサ・メソッドを持つ独自のプロパティ (City プロパティなど) があります。これらのメソッドは、カスケード・ドット構文を使用して実行できます。
保存とクローズ
City プロパティに新しい値を割り当てると、アプリケーションはそのオブジェクトを保存して値を表示し、オブジェクトを閉じた後でその割り当てを解放し、アプリケーション自身を閉じます。
person._save();
// Report the new residence of this person */
System.out.println( "New City: " + person.getHome().getCity());
// * de-assign the person object */
dbconnection.closeObject(person.getOref());
person = null;
// Close the connection
dbconnection.close();
接続を閉じる前に、その接続を使用するすべてのオブジェクトで closeObject() を呼び出すことが重要です。これを行わないと、サーバ上のデータの整合性が損なわれる可能性があります。オブジェクトは既定の並列処理値 1 で開きます。つまり、クラスが複数のデータ・ノードを使用する場合、読み込みロックが取得されます ("Caché オブジェクトの使用法" の “オブジェクト同時処理” を参照してください)。
また、接続インスタンスが範囲外になる前に、すべての接続インスタンスで close() を呼び出すことも必要です。これを行わないと、メモリ・リークなどの問題が発生する可能性があります。
Java バインディング・アプリケーションのサンプル
SampleApplication.java は単純な Java プログラムです。Caché SAMPLES データベースに接続し、このデータベースに保存されている Sample.PersonOpens in a new tab オブジェクトのインスタンスを開いて変更します。さらに、このデータベースに対して、事前に定義されたクエリを実行します。このアプリケーションは、オペレーティング・コマンド行から呼び出され、コマンド行からオブジェクト ID 値を読み取り、Java system.out オブジェクトを使用して出力を書き込みます。この例では、Caché と Java が Windows マシンで動作していることを前提としています。
SampleApplication.java は <cachesys>/dev/Java/Samples ディレクトリにあります (ご使用のシステムの <cachesys> の場所については、"Caché インストール・ガイド" の "Caché の既定のインストール・ディレクトリ" を参照してください)。Samples ディレクトリで、このプログラムを以下のようにコンパイルします。
javac SampleApplication.java
その後、以下を実行します。
java SampleApplication
このプログラムは、以下の結果を出力します。
C:\java> java SampleApplication
Enter ID of Sample.Person object to be opened: 1
Name: Isaacs,Sophia R.
City: Tampa
New City: Ulan Bator
C:\java>
以下は、サンプル・アプリケーションの完全な Java ソースです。
/*
* SampleApplication.java
*/
import java.io.*;
import java.util.*;
import com.intersys.objects.*;
public class SampleApplication {
public static void main(String[] args){
Database dbconnection = null;
String url="jdbc:Cache://localhost:1972/SAMPLES";
String username="_SYSTEM";
String password="sys";
ObjectServerInfo info = null;
Sample.Person person = null;
try {
// Connect to Cache on the local machine, in the SAMPLES namespace
dbconnection = CacheDatabase.getDatabase (url, username, password);
// Open an instance of Sample.Person,
// whose ID is read in from the console
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
System.out.print("Enter ID of Person object to be opened:");
String strID = br.readLine();
// Use the entered strID as an Id and use that Id to
// to open a Person object with the _open() method inherited
// from the Persistent class. Since the _open() method returns
// an instance of Persistent, narrow it to a Person by casting.
person = (Sample.Person)Sample.Person._open(dbconnection, new Id(strID));
// Fetch some properties of this object
System.out.println("Name: " + person.getName());
System.out.println("City: " + person.getHome().getCity());
// Modify some properties
person.getHome().setCity("Ulan Bator");
// Save the object to the database
person._save();
// Report the new residence of this person */
System.out.println( "New City: " + person.getHome().getCity());
/* de-assign the person object */
dbconnection.closeObject(person.getOref());
person = null;
// Close the connection
dbconnection.close();
} catch (Exception ex) {
System.out.println("Caught exception: "
+ ex.getClass().getName()
+ ": " + ex.getMessage());
}
}
}
ストリームの使用法
Caché を使用すると、ストリームと呼ばれるプロパティを生成できます。ストリームには、文字形式またはバイナリ形式の文字列が格納されます。文字ストリームは長いテキスト文字列です。例えば、データ入力画面の自由形式テキスト・フィールドに入力された内容などがあります。バイナリ・ストリームは通常はイメージ・ファイルまたはサウンド・ファイルです。他のデータベース・システムの BLOB (binary large object) に類似しています。
以下は、Java でストリームを使用するプロセスです。
-
Java クライアントを生成する際、適切なタイプ (GlobalBinaryStream または GlobalCharacterStream) の変数を定義し、初期化します。例えば、文字ストリームを使用する場合、変数を以下のように定義します。
com.intersys.classes.GlobalCharacterStream localnotes = null;
その後、インスタンス化されたクラスのストリームからコンテンツを読み取ります。
localnotes = myTest.getNotes();
-
ストリームをローカルにコピーすると、そこから読み取ることができます。
IntegerHolder len = new IntegerHolder( new Integer(8)) ; while (len.value.intValue() != 0 ) { System.out.println( localnotes._read( len) ); } ;
_read() メソッドの引数には、読み取る文字数を表す整数を指定します。その返り値は、実際に読み取られた文字数です。さらに、正常に読み取られた文字数 (指定した数以下の文字数) が、引数として使用した整数の変数に設定されます。
ストリームにデータを書き込んだり、ストリームからデータを読み取ったりする場合、Caché によってストリーム内での位置が監視されるので、前方や後方へ移動することができます。
Caché ストリーム・クラスは、com.intersys.classes パッケージの GlobalBinaryStream および GlobalCharacterStream です。以下は、ストリームに関する基本メソッドです。
コンテンツの追加
コンテンツの追加 (文字ストリームのみ)
コンテンツの読み取り
コンテンツの読み取り (文字ストリームのみ)
ストリームの終了位置への移動
ストリームの開始位置への移動
現在の位置がストリームの最後かどうかの確認
ストリームのサイズの取得
ストリームがコンテンツを持つかどうかの確認
ストリームのコンテンツの消去
クエリの使用法
Caché クエリは JDBC のフレームワークに適合するよう設計されていますが、JDBC の直接的な呼び出しを、ダイナミック・クエリの単純で完全なインタフェースで隠蔽することにより、さらに高レベルでの抽象化が可能になります。このインタフェースは、SQL 文の作成、パラメータの結合、クエリの実行、結果セットの検索のメソッドを備えています。
クラス・クエリ
Caché は、クラスの一部としてクエリを定義できます。その後、これらのクエリはコンパイルされ、実行時に呼び出すことができます。
事前に定義されたクエリを呼び出すには、CacheQuery クラスを使用します。
-
Caché サーバに接続します (この手順の詳細は、"Connection オブジェクトの生成" を参照してください)。
-
以下のコードを使用して、CacheQuery オブジェクトのインスタンスを生成します。
myQuery = new CacheQuery(factory, classname, queryname);
factory は既存の接続を指定します。classname は、クエリを実行するクラスを指定します。queryname は、クラスの一部である事前定義のクエリ名を指定します。
-
CacheQuery オブジェクトのインスタンスを生成すると、事前定義のクエリを呼び出せるようになります。
java.sql.Result ResultSet = myQuery.execute(parm1);
このメソッドは最大 3 つの引数を受け取り、クエリに直接渡します。4 つ以上の引数を受け取るクエリの場合は、引数値の配列として引数を渡すようにします。このメソッドは、標準 JDBC ResultSet オブジェクトのインスタンスを返します。