Caché eXTreme での Java の使用法

Caché eXTreme での Java の
使用法
Version 2012.2
2012 年 09 月 12 日
InterSystems Corporation 1 Memorial Drive Cambridge MA 02142 www.intersystems.com
Caché eXTreme での Java の使用法
Caché Version 2012.2 2012 年 09 月 12 日
Copyright © 2012 InterSystems Corporation
All rights reserved.
このドキュメントは、 Sun Microsystems、RenderX Inc.、 アドビ システムズ および ワールドワイド・ウェブ・コンソーシアム(www.w3c.org)のツールと
情報を使用して、 Adobe Portable Document Format (PDF)で作成およびフォーマットされました。主要ドキュメント開発ツールは、InterSystemsが構
築したCacheéと Javaを使用した特別目的のXML処理アプリケーションです。
,
,
Caché WEBLINK, Distributed Cache Protocol, M/SQL, M/NET および M/PACT は InterSystems Corporation の登録商標です。
,
,
and
,
InterSystems TrakCare, InterSystems Jalapeño Technology, Enterprise Cache Protocol, ECP および InterSystems Zen は InterSystems Corporation の
登録商標です。
ここで使われている他の全てのブランドまたは製品名は、各社および各組織の商標または登録商標です。
このドキュメントは、インターシステムズ社(住所:One Memorial Drive, Cambridge, MA 02142)あるいはその子会社が所有する企業秘密および秘密
情報を含んでおり、インターシステムズ社の製品を稼動および維持するためにのみ提供される。この発行物のいかなる部分も他の目的のために使
用してはならない。また、インターシステムズ社の書面による事前の同意がない限り、本発行物を、いかなる形式、いかなる手段で、その全てまたは
一部を、再発行、複製、開示、送付、検索可能なシステムへの保存、あるいは人またはコンピュータ言語への翻訳はしてはならない。
かかるプログラムと関連ドキュメントについて書かれているインターシステムズ社の標準ライセンス契約に記載されている範囲を除き、ここに記載さ
れた本ドキュメントとソフトウェアプログラムの複製、使用、廃棄は禁じられている。インターシステムズ社は、ソフトウェアライセンス契約に記載され
ている事項以外にかかるソフトウェアプログラムに関する説明と保証をするものではない。さらに、かかるソフトウェアに関する、あるいはかかるソフ
トウェアの使用から起こるいかなる損失、損害に対するインターシステムズ社の責任は、ソフトウェアライセンス契約にある事項に制限される。
前述は、そのコンピュータソフトウェアの使用およびそれによって起こるインターシステムズ社の責任の範囲、制限に関する一般的な概略である。完
全な参照情報は、インターシステムズ社の標準ライセンス契約に記され、そのコピーは要望によって入手することができる。
インターシステムズ社は、本ドキュメントにある誤りに対する責任を放棄する。また、インターシステムズ社は、独自の裁量にて事前通知なしに、本ド
キュメントに記載された製品および実行に対する代替と変更を行う権利を有する。
インターシステムズ社の製品に関するサポートやご質問は、以下にお問い合わせください:
Tel:
Fax:
Email:
InterSystems Worldwide Customer Support
+1 617 621-0700
+1 617 374-9391
[email protected]
目次
このドキュメントについて ................................................................................................... 1
1 はじめに ..................................................................................................................... 3
1.1 概要 .................................................................................................................. 3
1.2 インストールと構成 ............................................................................................... 3
1.2.1 要件 .......................................................................................................... 4
1.2.2 インストール ................................................................................................ 4
1.2.3 すべてのプラットフォームに対して必須の環境変数 ........................................... 4
1.2.4 Windows の構成 .......................................................................................... 5
1.2.5 Mac OS X 構成 ........................................................................................... 5
1.2.6 UNIX の構成 .............................................................................................. 5
1.3 eXTreme アプリケーションのサンプル ...................................................................... 5
1.3.1 XEP のサンプル .......................................................................................... 5
1.3.2 ダイナミック・オブジェクトのサンプル ............................................................... 6
1.3.3 グローバル API のサンプル ........................................................................... 6
1.3.4 サンプル・データ・クラス ................................................................................ 6
2 eXTreme Event Persistence の使用法 .............................................................................. 9
2.1 Event Persistence の概要 ...................................................................................... 9
2.1.1 永続イベントを格納および照会する単純なアプリケーション ............................... 10
2.2 EventPersister の作成と接続 ................................................................................ 13
2.3 スキーマのインポート .......................................................................................... 15
2.3.1 スキーマ・インポート・モデル ........................................................................ 15
2.3.2 スキーマ・インポート・メソッド ........................................................................ 16
2.3.3 アノテーションの使用法 .............................................................................. 17
2.3.4 IdKey の使用法 ......................................................................................... 20
2.4 イベントの格納と変更 .......................................................................................... 21
2.4.1 イベント・インスタンスの作成と永続イベントの格納 ........................................... 21
2.4.2 格納されたイベントへのアクセス ................................................................... 22
2.4.3 インデックス更新の制御 .............................................................................. 23
2.5 クエリの使用法 ................................................................................................... 24
2.5.1 クエリの作成と実行 .................................................................................... 24
2.5.2 クエリ・データの処理 ................................................................................... 25
2.5.3 EventQueryIterator<> の使用法 ................................................................... 25
2.5.4 フェッチ・レベルの定義 ............................................................................... 26
2.6 XEP からの Caché メソッドの呼び出し .................................................................... 27
2.7 スキーマ・マッピング・ルール ................................................................................ 27
2.7.1 インポートされるクラスの要件 ....................................................................... 27
2.7.2 名前付け規約 ........................................................................................... 28
2.7.3 データ型のマッピング ................................................................................. 28
2.7.4 InterfaceResolver の実装 ............................................................................ 30
3 eXTreme ダイナミック・オブジェクトの使用法 .................................................................... 33
3.1 XDO 接続を開くおよび閉じる ............................................................................... 34
3.2 ダイナミック・オブジェクトの使用法 ......................................................................... 35
3.2.1 ダイナミック・オブジェクトおよびデータベース・オブジェクトの作成 ...................... 35
3.2.2 新規データベース・オブジェクトの挿入 .......................................................... 36
3.2.3 既存のデータベース・オブジェクトの変更 ....................................................... 38
3.2.4 プロパティ番号の使用 ................................................................................ 39
Caché eXTreme での Java の使用法 iii
3.3 トランザクション処理 ............................................................................................ 40
3.3.1 トランザクションの使用法 ............................................................................. 40
4 グローバル API の使用法 ............................................................................................. 43
4.1 グローバル API の概要 ....................................................................................... 44
4.1.1 グローバル配列の概要 ............................................................................... 44
4.1.2 ノードを作成およびフェッチするための簡単なアプリケーション .......................... 45
4.2 接続の作成 ....................................................................................................... 47
4.3 グローバル配列の構築 ........................................................................................ 48
4.3.1 NodeReference でのノードの作成 ................................................................. 49
4.3.2 ターゲット・アドレスの設定 ........................................................................... 50
4.3.3 ターゲットのサブノードのアドレス指定 ............................................................ 51
4.3.4 ノードの作成と削除 .................................................................................... 52
4.4 グローバル配列にわたる反復 ............................................................................... 54
4.4.1 一連のノードの取得 ................................................................................... 54
4.4.2 開始ポイントと反復処理の順序の制御 ........................................................... 55
4.4.3 ターゲット・アドレスのすべてのサブノードへのアクセス ...................................... 57
4.5 グローバル配列のデータの取得 ........................................................................... 58
4.5.1 ノード値のフェッチ ..................................................................................... 58
4.5.2 ターゲット・アドレスからの添え字の読み取り .................................................... 60
4.6 シリアル化された値リストの使用法 ......................................................................... 62
4.6.1 ValueList の作成、格納、およびフェッチ ........................................................ 63
4.6.2 ValueList 要素の読み取り ........................................................................... 64
4.7 複数のグローバル配列へのアクセス ...................................................................... 66
4.7.1 グローバル名へのアクセス ........................................................................... 66
4.7.2 グローバル配列のディレクトリの使用法 .......................................................... 67
4.7.3 ネームスペースへのアクセス ........................................................................ 69
4.8 トランザクションとロック ......................................................................................... 70
4.8.1 トランザクションの制御 ................................................................................ 70
4.8.2 ロックの取得および解放 .............................................................................. 71
4.8.3 トランザクションでのロックの使用 ................................................................... 72
4.9 Caché メソッドの呼び出し ..................................................................................... 73
4.10 グローバル API の要件と規約 ............................................................................. 74
4.10.1 グローバル配列の名前付け規約 ................................................................. 74
4.10.2 グローバル API を他の eXTreme API と共に使用する方法 ............................. 75
4.10.3 複数レベルのグローバル配列での照合順 .................................................... 75
4.10.4 スレッド・セーフに関する考慮事項 ............................................................... 76
5 eXTreme クラスのクイック・リファレンス ............................................................................. 77
5.1 XEP クイック・リファレンス ..................................................................................... 77
5.1.1 XEP メソッドのリスト .................................................................................... 78
5.1.2 クラス PersisterFactory ............................................................................... 79
5.1.3 クラス EventPersister .................................................................................. 80
5.1.4 クラス Event .............................................................................................. 85
5.1.5 クラス EventQuery<> .................................................................................. 88
5.1.6 クラス EventQueryIterator<> ........................................................................ 90
5.1.7 インタフェース InterfaceResolver ................................................................... 91
5.1.8 クラス XEPException ................................................................................... 91
5.2 XDO クイック・リファレンス .................................................................................... 91
5.2.1 XDO メソッドのリスト ................................................................................... 92
5.2.2 クラス DatabaseConnectionFactory ............................................................... 93
5.2.3 インタフェース DatabaseConnection .............................................................. 93
iv Caché eXTreme での Java の使用法
5.2.4 インタフェース DynamicObject ..................................................................... 95
5.2.5 XDO 例外 .............................................................................................. 100
5.3 グローバルのクイック・リファレンス ........................................................................ 101
5.3.1 グローバル API メソッドのリスト .................................................................... 101
5.3.2 クラス ConnectionContext .......................................................................... 104
5.3.3 インタフェース Connection ......................................................................... 105
5.3.4 インタフェース GlobalsDirectory .................................................................. 110
5.3.5 インタフェース NodeReference .................................................................... 111
5.3.6 インタフェース ValueList ............................................................................ 119
5.3.7 クラス ByteArrayRegion ............................................................................. 122
5.3.8 グローバル例外クラス ................................................................................ 123
5.3.9 グローバル実装クラス ................................................................................ 125
Caché eXTreme での Java の使用法 v
このドキュメントについて
Caché eXTreme とは、ある一連の Java テクノロジで、これによって、高パフォーマンス永続ストレージ・エンジンとして
Caché を XTP (Extreme Transaction Processing) アプリケーションで活用できます。標準的な Caché Java バインディン
グと異なり、すべての eXTreme API では、非常に高速のプロセス内接続を使用して Caché データにアクセスすることが
できます。
このドキュメントで説明する項目は以下のとおりです。
•
はじめに — eXTreme プラットフォーム・アーキテクチャの概要および一般的なインストール手順を説明します。
•
eXTreme Event Persistence の使用法 — 単純な Java オブジェクトを XTP 永続イベントとして反映する XEP API に
ついて説明します。
•
eXTreme ダイナミック・オブジェクトの使用法 — Caché データへのオブジェクト指向のアクセスを提供する XDO API
について説明します。
•
グローバル API の使用法 — Caché 多次元データ・ストレージへの直接アクセスを提供するグローバル API につい
て説明します。
•
eXTreme クラスのクイック・リファレンス — eXTreme API クラスのメソッドのクイック・リファレンスを提供します。
詳細な目次もあります。
関連ドキュメント
以下のドキュメントにも関連資料が含まれています。
•
JavaDoc for the InterSystems Java Connectivity API は、<cache-root>/dev/java/doc/index.html にあります。
•
Caché での Java の使用法 — Java アプリケーションで Caché オブジェクトを直接使用するための簡単な方法を提
供する Caché Java バインディングのガイドです。
•
JDBC での Caché の使用法 — Caché JDBC ドライバを使用して外部アプリケーションから Caché に接続する方法、
および Caché から外部 JDBC データ・ソースにアクセスする方法について説明します。
•
Caché Jalapeño での Java の使用法 — Jalapeño の使用方法について説明します。これは、マッピングなしで簡単に
POJO (Plain Old Java Objects) を格納し、それにアクセスできる軽量な永続ツールです。
•
"Caché Java バインディングおよび JDBC クイックスタート・チュートリアル" では、Java バインディングを使用した作
業の概要を示します。これには Java バインディング・アプリケーションの完全なサンプルが付属しています。
一般的な情報については、"InterSystems のドキュメントの使用法" を参照してください。
Caché eXTreme での Java の使用法 1
1
はじめに
Caché eXTreme は、XTP (Extreme Transaction Processing) アプリケーション用に最適化された高パフォーマンス永続
ストレージ・エンジンとして Caché を活用できるようにする一連のテクノロジです。
標準の Java バインディングと異なり、eXTreme API は Caché との通信に TCP/IP を使用しません。代わりに、(標準 Java
JNI および Caché Callin API を介して実装される) 高速のメモリ内接続を使用し、Caché インスタンスと同じプロセスで実
行されます。Caché サーバと Java アプリケーションは同じマシン上にある必要がありますが、それでもなおアプリケーショ
ンで Caché ECP を使用して、リモート・マシンのデータにアクセスできます。
1.1 概要
Caché eXTreme のコンポーネントには以下のものが含まれます。
•
プロセス内 JDBC — TCP/IP の代わりに JNI を使用して実行される JDBC。
•
eXTreme Event Persistence (XEP) — 単純な Java オブジェクトを XTP 永続イベントとして投影し、高速のストレージ
および処置を実現します。これは、低遅延のオブジェクトおよびイベント・ストリーム・データ・アクセスのための軽量
API です (“eXTreme Event Persistence の使用法” を参照)。
•
ダイナミック・オブジェクト API — Caché データへのオブジェクト指向アクセスを提供します。Caché クラス内のデー
タへのアクセスは動的です。つまり、クラスが Java アプリケーションのコンパイル時に既知である必要はなく、コード
を生成する必要もありません (“eXTreme ダイナミック・オブジェクトの使用法” を参照)。
•
グローバル API — Caché グローバル配列への直接アクセスを提供し、最高の速度および柔軟性を可能にします
(“グローバル API の使用法” を参照)。
eXTreme API は、次に示すような Java アプリケーションとの統合のために設計されています。
•
イベント SOA および動的モジュール用の OSGi。
•
Esper などの CEP (複雑なイベント処理 (Complex Event Processing)) エンジン。
•
メッセージング 統合 (JMS、AMQP、他)。
1.2 インストールと構成
このセクションでは、要件を示し、Caché をインストールして eXTreme API を使用できるようにご使用の環境を構成する
手順を示します。
Caché eXTreme での Java の使用法 3
はじめに
1.2.1 要件
•
Java JDK バージョン 1.6。
•
Caché 2010.2 以降
•
アプリケーションで XEP を使用する場合、Caché User ネームスペースが存在し、かつ書き込み可能であることが必
要です (“eXTreme Event Persistence の使用法” を参照)。
1.2.2 インストール
•
•
Caché をインストールするときに、以下のように開発環境を選択します。
–
Windows では、インストール中に Setup Type: Development オプションを選択します。
–
UNIX® では、インストール中に 1) Development - Install Cache server and all language
bindings オプションを選択します ("Caché インストール・ガイド" の UNIX® および Linux のセクションにある
“インストール・スクリプトの実行” を参照)。
Caché をセキュリティ・レベル 2 でインストールした場合、管理ポータルを開いて、[ホーム] > [セキュリティ管理] >
[サービス] に移動し、%Service_CallIn を選択して、[ ] ボックスにチェックが付いていることを確認しま
す。
Caché をセキュリティ・レベル 1 (最小) でインストールした場合、これには既にチェックが付いているはずです。
1.2.3 すべてのプラットフォームに対して必須の環境変数
eXTreme アプリケーションを実行するために、以下の環境変数をすべてのプラットフォーム上で適切に設定する必要が
あります。
•
GLOBALS_HOME 環境変数を Caché インストール環境の <cache-root> ディレクトリのフル・パスに設定する必要
があります (システムの <cache-root> の場所については “Caché の既定のインストール・ディレクトリ” を参照)。
注釈
CACHEMGRDIR の非推奨
以前のリリースでは、必須環境変数は CACHEMGRDIR であり、<cache-root> ではなく <cache-root>/mgr
ディレクトリに設定していました。この変数は非推奨となっています。両方の変数が設定されている場合、
GLOBALS_HOME が使用されます。
•
ご使用のパスに <cache-root>/bin が含まれている必要があります。
–
Windows では、このパスを PATH 環境変数に追加します。
–
UNIX® では、このパスを LD_LIBRARY_PATH 環境変数に追加します。
–
Mac OS X では、このパスを LD_LIBRARY_PATH 環境変数に追加します。
ご使用のパス変数に複数の <cache-root>/bin パスが含まれている場合 (例えば、Caché のインスタンスを複数イ
ンストールした場合)、最初のパスのみが使用され、その他のパスは無視されます。
•
CLASSPATH 環境変数に、必須のJAR ファイル (CacheJDBC.jar、CacheDB.jar、および CacheeXTreme.jar) への
フル・パスが含まれている必要があります ("Caché での Java の使用法" の “Caché Java クラス・パッケージ” を参
照)。または、これらのファイルは Java コマンド行の classpath 引数で指定できます。
4 Caché eXTreme での Java の使用法
eXTreme アプリケーションのサンプル
1.2.4 Windows の構成
•
Windows 上の Java 仮想マシンの既定のスタック・サイズは、eXTreme アプリケーションを実行するには小さすぎま
す (eXTreme アプリケーションを既定のスタック・サイズで実行すると、Java が EXCEPTION_STACK_OVERFLOW を
レポートします)。eXTreme アプリケーションを実行するときにスタック・サイズを一時的に変更するには、以下のコマ
ンド行引数を追加します。
-Xss1024k
1.2.5 Mac OS X 構成
•
Cache バイナリでの許可を有していることを確認します (ユーザを cacheusr グループに追加)。
1.2.6 UNIX の構成
•
Cache バイナリでの許可を有していることを確認します (ユーザを cacheusr グループに追加)。
•
環境変数 LD_PRELOAD を Java インストール環境内の libjsig.so (Java によるシグナル処理の変則性の解決を可
能にするライブラリ) のパスに設定します。以下に例を示します (使用しているシェルによって異なります)。
setenv LD_PRELOAD /my_jdk_path/jdk1.6.0_11/jre/lib/amd64/libjsig.so
または
set LD_PRELOAD=/my_jdk_path/jdk1.6.0_11/jre/lib/amd64/libjsig.so
Java インストール環境のルートの下の libjsig.so のパスは、プラットフォーム間、または Java リリース間で異なる場合
があります。以下のコマンドを使用して、ご使用のシステムでこのパスを検索できます。
find $JAVA_HOME -name libjsig.so -print
ここで、JAVA_HOME は、Java インストール環境のルート・ディレクトリに設定されます。
注釈
LD_PRELOAD 変数の設定は、eXTreme アプリケーションがシグナル・ハンドラの設定を行う他のサード・
パーティのコンポーネントも使用する場合に重要です。この変数により、Java は、Caché によって設定され
るシグナル・ハンドラを Java 独自のシグナル・ハンドラと結合でき、その結果 2 つのハンドラは相互に干渉
しなくなります。この変数の設定に失敗するとシステム・クラッシュを引き起こす可能性があります。
1.3 eXTreme アプリケーションのサンプル
アプリケーションのサンプルは、3 つの eXTreme API すべてで使用可能です。使用可能なコマンド行オプションのリスト
を表示するには、コマンド行引数 -h を指定してサンプルを実行します。
1.3.1 XEP のサンプル
XEP のサンプル・ファイルは、<cache-root>/dev/java/samples/extreme/xep/test/ にあります。便宜上、これらのファ
イルは、コンパイル先も <cache-root>/dev/java/samples にある extremesamples.jar です。用意されているサンプル・
プログラムは以下のとおりです。
•
RunAll.java — 他のサンプル・プログラムのすべてを順番に実行するプログラムです。
Caché eXTreme での Java の使用法 5
はじめに
•
Coverage.java — 接続、スキーマのインポート、XEP イベントの格納、照会、更新および削除などの基本機能をテス
トします。また、サポート対象のデータ型のほとんどを制御します。
•
SingleString.java — 最も基本的な XEP テスト・プログラムです。これは、データベースに接続し、文字列フィールド
を 1 つだけ含む単純なクラスをインポートし、このクラスに対応する複数のイベントの格納およびロードを行います。
•
FlightLog.java — XEP 完全継承モデルを示す例です。これは、時刻、場所、職員、乗客などの航空会社フライト情
報を追跡します。
•
Benchmark.java — XEP API のパフォーマンス・テストを行います。
•
IdKeys.java — 複合 IdKey 機能を追加することで Benchmark テストを拡張します。
•
Threads.java — マルチスレッド XEP テスト・プログラムです。これは、Java スレッド・クラスを拡張し、Basic.java テス
トを使用して、複数のスレッドを使用する XEP をテストします。
これらのプログラムの詳細ドキュメントは、"Caché JavaDoc" (<cache-root>/dev/java/doc/index.html) を参照してくださ
い。<cache-root>/dev/java/samples/extreme/xep/samples/ にあるサポート・ファイルは、サンプル・プログラムのテ
スト・データを提供します。
1.3.2 ダイナミック・オブジェクトのサンプル
以下の XDO のサンプル・プログラムは、<cache-root>/dev/java/samples/extreme/xdo にあります。
•
XDODemo.java — eXTreme ダイナミック・オブジェクト API のデモおよびパフォーマンス・テストを行います。
このプログラムは、コンパイル先も <cache-root>/dev/java/samples にある extremesamples.jar です。
1.3.3 グローバル API のサンプル
グローバル API サンプル・アプリケーション (com.intersys.globals.samples.Sample) のコンパイル先は、
<cache-root>/dev/java/lib/JDK16 にある cacheextreme.jar です。このプログラムを実行するには、以下のコマンドを
入力します。
java -Xss1024k -cp %jarpath% com.intersys.globals.samples.Sample -pause
ここで、%jarpath% は、 %GLOBALS_HOME%/dev/java/lib/JDK16/cacheextreme.jar に設定されています。
この jar ファイルには、ソース・ファイル Sample.java のコピーも含まれており、以下のコマンドで現在のディレクトリに抽
出できます。
jar -xf %jarpath% com/intersys/globals/samples/Sample.java
1.3.4 サンプル・データ・クラス
このドキュメントの例では、Caché Samples ネームスペースの CosTutorial.Person および Sample.Person エクステントを
頻繁に使用し、データの格納および取得の例を示します。
注釈
これらのエクステントの内容は、[システム] > [グローバル]に移動し、左の列の選択項目から [Namespace]
および [Samples] を選択し、目的のエクステントの [view] リンクをクリックすることで管理ポータルに表示
できます (CosTutorial.Person エクステントは CosTutorial.PersonD ではなく PersonD の下にリストされ
ています)。
CosTutorial.Person
この非常に単純な Caché クラスには、以下の宣言が含まれています。
6 Caché eXTreme での Java の使用法
eXTreme アプリケーションのサンプル
•
property DOB as %Date;
•
property Name as %String;
•
property Phone as %String(COLLATION="EXACT",MAXLEN=12);
•
index Phone on Phone [Unique];
次のコマンドをコピーして、Caché ターミナルに貼り付け、エクステントに入力するか、エクステントのすべてのオ
ブジェクトを削除できます。
//Switch to the Samples namespace:
zn "Samples"
// Delete all instances of CosTutorial.Person from the extent:
Do ##class(CosTutorial.Person).%KillExtent()
// Create seven new instances of CosTutorial.Person:
Do ##class(CosTutorial.Person).Populate(7)
構造に関する完全な詳細は、クラスリファレンスの CosTutorial.Person のエントリを参照してください。Caché
ObjectScript の例については、"Caché ObjectScript チュートリアル" (“Caché オブジェクトと SQL” で始まる)
を参照してください。
Sample.Person
このドキュメントの例の一部は、Sample.Person エクステントをデータ・ソースとして使用します。次のコマンドを
コピーして、Caché ターミナルに貼り付け、エクステントに入力するか、エクステントのすべてのオブジェクトを削
除できます。
//Switch to the Samples namespace:
zn "Samples"
// Delete all instances of Sample.Person from the extent:
Do ##class(Sample.Person).%KillExtent()
// Create seven new instances of Sample.Person:
Do ##class(Sample.Person).Populate(7)
構造に関する詳細は、クラスリファレンスの Sample.Person" のエントリを参照してください。このクラスには、シ
リアル・プロパティが含まれているため、このクラスを XDO API (“eXTreme ダイナミック・オブジェクトの使用法”
を参照) で使用することはできません。
Sample.Person から ResultSet を返す
以下の例は、サンプル・データを含む ResultSet を返す単純なクエリを示しています。
// Get a resultset containing Name and DOB properties.
java.sql.ResultSet myResults = null;
try {
String sql="Select Name, DOB from Sample.Person Order By Name";
myResults = jdbcConnection.prepareStatement(sql).executeQuery();
}
catch (java.sql.SQLException e) { System.out.println("Query failed: " + e.getMessage()); }
ResultSet は、JDBC 接続を使用して Sample.Person エクステントにクエリを実行することで生成されます (例に
ついては、"JDBC での Caché の使用法" の “JDBC データベースへのアクセス” を参照してください)。myResults
オブジェクトの各行には、"Name" および "DOB" プロパティが含まれており、それらは CosTutorial.Person な
どの別のエクステントにデータを読み込むための入力として使用できます。
Caché eXTreme での Java の使用法 7
2
eXTreme Event Persistence の使用法
Caché eXTreme Event Persistence (XEP) は、Java 構造化データの非常に高速な格納および取得を可能にします。こ
れにより、グローバル API の機能を利用する高速かつ効率的なオブジェクトからグローバルへのマッピング・アルゴリズ
ムが実装されますが (“グローバル API の使用法” を参照)、グローバル API の知識は必要ありません。XEP は、複雑
なデータ構造の最適なマッピングのためのスキーマ生成を制御する方法を提供しますが、単純なデータ構造のスキー
マは、多くの場合、変更することなく生成および使用できます。グローバル API と異なり、XEP ではプロセス内通信と
TCP/IP 接続のどちらも使用できます。
この章で説明する項目は以下のとおりです。
•
Event Persistence の概要 — 永続イベントの概念および用語について紹介し、XEP API を使用するコードの簡単な
例を示します。
•
EventPersister の作成と接続 — EventPersister クラスのインスタンスを作成する方法、およびそれを使用して
eXTreme または TCP/IP データベース接続を開き、テストし、閉じる方法について説明します。
•
スキーマのインポート — Java クラスを分析するため、および対応する Caché イベントのスキーマを生成するための
メソッドおよびアノテーションについて説明します。
•
イベントの格納と変更 — 永続イベントの格納、変更、および削除に使用する Event クラスのメソッドについて説明し
ます。
•
クエリの使用法 — クエリ結果セットを作成および処理する EventQuery<> クラスのメソッドについて説明します。
•
XEP からの Caché メソッドの呼び出し — XEP アプリケーションから Caché ObjectScript メソッド、関数、およびプロ
シージャを呼び出すことができる EventPersister メソッドについて説明します。
•
スキーマ・マッピング・ルール — Java クラスが Caché イベント・スキーマにどのようにマップされるかについて詳しく
説明します。
2.1 Event Persistence の概要
永続イベントは、Java オブジェクトにデータ・フィールドの永続コピーを格納する Caché データベース・オブジェクトです。
既定では、eXTreme Event Persistence API は、各イベントを通常の %Persistent オブジェクトとして格納します。ストレー
ジは、その他の手段 (オブジェクト、SQL、直接グローバル・アクセスなど) でデータが Caché にアクセスできるように自動
的に構成されます。この章で説明する Caché の概念 (クラス・エクステント、オブジェクト ID と IdKey、およびストレージ
定義) の詳細は、"Caché プログラミング入門ガイド" の “永続クラスの SQL プロジェクション” を参照してください。
XEP スキーマは、Java オブジェクト内のデータ構造を Caché 永続イベントにどのように投影するのかを定義します。ス
キーマは、2 つの使用可能なオブジェクト・プロジェクション・モデルのいずれかを使用できます (詳細は “スキーマ・イ
ンポート・モデル” を参照してください)。既定のモデルは、フラット・スキーマです。そのスキーマでは、参照オブジェクト
Caché eXTreme での Java の使用法 9
eXTreme Event Persistence の使用法
がすべてシリアル化されて、インポートされたクラスの一部として格納され、スーパークラスから継承したフィールドはすべ
て、それらが、インポートされたクラスのネイティブ・フィールドであるかのように格納されます。これは、最も高速かつ効率
的なモデルですが、元の Java クラス構造に関する情報は何も保持されません。その情報を保持する必要がある場合
は、フル・スキーマ・モデルを使用できます。このモデルでは、Java ソース・クラスと Caché の投影されたクラスとの間に
1 対 1 のリレーションシップを作成することで、完全な Java 継承構造が保持されますが、パフォーマンスがわずかに劣
化することがあります。
スキーマがインポートされると、XEP を使用して非常に高いレートでデータの格納、照会、更新、および削除を行えます。
フラット・スキーマを使用している場合は、インデックスの更新を非同期で実行できます。挿入されたイベントは、照会に
対して、あるいは完全オブジェクトまたはグローバル・アクセスに対してすぐに使用できます。
永続イベントのフィールドは、プリミティブで、そのラッパ、一時データ型、オブジェクト (組み込み/連続オブジェクトとし
て投影)、列挙、および java.util.List、java.util.Set、および java.util.Map から派生したデータ型にできます。これらのデー
タ型を配列、入れ子になったコレクション、および配列のコレクションに含めることもできます。静的フィールドはすべて、
既定で除外されます。詳細は、“スキーマのインポート” および “スキーマ・マッピング・ルール” を参照してください。
以下のクラスが、XEP のメイン機能を提供します。
•
EventPersister は、データベース接続の確立、スキーマのインポート、サーバ上での Caché ObjectScript メソッドお
よび関数の呼び出し、およびトランザクションの制御に使用できるメソッドを提供します。
•
Event は、イベントの格納、更新、または削除、クエリの作成、インデックス更新の制御を行うメソッドを提供します。
•
EventQuery<> は、データベースから、指定したクラスのイベントをフェッチする単純なクエリを実行します。結果セッ
トを繰り返し処理し、個別のイベントの更新および削除を行うためのメソッドが提供されています。
2.1.1 永続イベントを格納および照会する単純なアプリケーション
このセクションでは、XEP を使用して永続イベントを作成し、それにアクセスする 2 つの非常に単純なアプリケーションに
ついて説明します。
•
StoreEvents プログラム — Caché データベースへの eXTreme 接続を開き、イベントを格納するためのスキーマを作
成し、Event のインスタンスを使用してオブジェクトの配列を永続イベントとして格納し、接続を閉じて終了します。
•
QueryEvents プログラム — StoreEvents と同じネームスペースにアクセスする新しい eXTreme 接続を開き、
EventQuery<> のインスタンスを作成して前に格納されたイベントを読み取りおよび削除し、接続を閉じて終了しま
す。
注釈
これらのアプリケーションは、システムを排他的に使用し、2 つの連続したプロセスで実行されることが前提と
なっています。
どちらのプログラムも、XEP サンプル・プログラムで定義されているクラスの 1 つである
xep.samples.SingleStringSample のインスタンスを使用します (サンプル・プログラムの詳細は “XEP のサンプ
ル” を参照してください)。
2.1.1.1 StoreEvents プログラム
StoreEvents では、EventPersister の新しいインスタンスが作成され、Caché サーバ上で特定のネームスペースに接続
されます。SingleStringSample クラス用にスキーマがインポートされ、テスト・データベースが、そのクラスのエクステント
から既存のイベントをすべて削除することで初期化されます。Event のインスタンスが作成され、SingleStringSample オ
ブジェクトの配列を永続イベントとして格納するために使用されます。その後、接続が終了されます。その新しいイベント
は Caché データベース内で永続化され、QueryEvents プログラムによってアクセスされるようになります (次のセクション
で説明します)。
10 Caché eXTreme での Java の使用法
Event Persistence の概要
StoreEvents プログラム : スキーマの作成とイベントの格納
import com.intersys.xep.*;
import xep.samples.SingleStringSample;
public class StoreEvents {
private static String className = "xep.samples.SingleStringSample";
private static SingleStringSample[] eventData = SingleStringSample.generateSampleData(12);
public static void main(String[] args) {
for (int i=0; i < eventData.length; i++) {
eventData[i].name = "String event " + i;
}
try {
System.out.println("Connecting and importing schema for " + className);
EventPersister myPersister = PersisterFactory.createPersister();
myPersister.connect("User","_SYSTEM","SYS");
try{ // delete any existing SingleStringSample events, then import new ones
myPersister.deleteExtent(className);
myPersister.importSchema(className);
}
catch (XEPException e) { System.out.println("import failed:\n" + e); }
Event newEvent = myPersister.getEvent(className);
long[] itemIDs = newEvent.store(eventData); // store array of events
System.out.println("Stored " + itemIDs.length + " of "
+ eventData.length + " objects. Closing connection...");
newEvent.close();
myPersister.close();
}
catch (XEPException e) {System.out.println("Event storage failed:\n" + e);}
} // end Main()
} // end class StoreEvents
StoreEvents.Main() が呼び出される前に、xep.samples.SingleStringSample.generateSampleData() メソッドが呼
び出されて、サンプル・データ配列 eventData が生成されます (サンプル・クラスの詳細は “XEP のサンプル”
を参照してください)。
この例では、XEP メソッドは以下のアクションを実行します。
重要
•
PersisterFactory.createPersister() は、EventPersister の新しいインスタンスである myPersister を作成し
ます。
•
EventPersister.connect() は、User ネームスペースへの eXTreme プロセス内接続を確立します。
•
EventPersister.importSchema() は、SingleStringSample クラスを分析し、そのスキーマをインポートします。
•
EventPersister.deleteExtent() を呼び出すと、SingleStringSample エクステントから既存のテスト・データを
削除することで、データベースがクリーン・アップされます。
•
EventPersister.getEvent() は、SingleStringSample イベントを処理するために使用される Event の新しい
インスタンスである newEvent を作成します。
•
Event.store() は、入力として eventData 配列を受け入れ、その配列内のオブジェクトごとに新しい永続イ
ベントを作成します。(代わりに、コードで eventData 配列をループして個々のオブジェクトごとに store() を
呼び出すこともできますが、この例ではそのようにする必要はありません。)
•
Event.close() および EventPersister.close() は、イベントが格納された後に newEvent および myPersister
に対して呼び出されます。これは、ネイティブ・コード・リソースを解放し、メモリ・リークを回避するために必
要です。
常に close() を呼び出してメモリ・リークを回避
Event および EventPersister のインスタンスが範囲外になるか再使用される前に、これらのインスタン
スで必ず close() を呼び出すことが重要です。それらを閉じないと、深刻なメモリ・リークが発生すること
があります。それは、Java ガーベッジ・コレクションでは、基盤となるネイティブ・コードによって割り当てら
れたリソースを解放できないためです。
これらのメソッドについては、すべてこの章で後で詳しく説明します。eXTreme 接続を開き、テストし、閉じることに関する
詳細は、“EventPersister の作成と接続” を参照してください。スキーマの作成の詳細は、“スキーマ・インポート・メソッ
Caché eXTreme での Java の使用法 11
eXTreme Event Persistence の使用法
ド” を参照してください。Event クラスの使用とエクステントの削除の詳細は、“イベントの格納と変更” を参照してくださ
い。
2.1.1.2 QueryEvents プログラム
この例では、StoreEvents プロセスの終了後、直ちに QueryEvents が実行されることを前提としています (“StoreEvents
プログラム” を参照してください)。QueryEvents は、StoreEvents と同じネームスペースにアクセスする新しいデータ
ベース接続を確立します。EventQuery<> のインスタンスが作成され、前に格納されたイベントに繰り返し処理を行い、
それらのデータを出力し、それらを削除します。
QueryEvents プログラム : 永続イベントのフェッチと処理
import com.intersys.xep.*;
import xep.samples.SingleStringSample;
public class QueryEvents {
public static void main(String[] args) {
EventPersister myPersister = null;
EventQuery<SingleStringSample> myQuery = null;
try {
// Open a connection, then set up and execute an SQL query
System.out.println("Connecting to query SingleStringSample events");
myPersister = PersisterFactory.createPersister();
myPersister.connect("User","_SYSTEM","SYS");
try {
Event newEvent = myPersister.getEvent("xep.samples.SingleStringSample");
String sql = "SELECT * FROM xep_samples.SingleStringSample WHERE %ID BETWEEN 3 AND ?";
myQuery = newEvent.createQuery(sql);
newEvent.close();
myQuery.setParameter(1,12); // assign value 12 to SQL parameter 1
myQuery.execute();
}
catch (XEPException e) {System.out.println("createQuery failed:\n" + e);}
// Iterate through the returned data set, printing and deleting each event
SingleStringSample currentEvent;
currentEvent = myQuery.getNext(null); // get first item
while (currentEvent != null) {
System.out.println("Retrieved " + currentEvent.name);
myQuery.deleteCurrent();
currentEvent = myQuery.getNext(currentEvent); // get next item
}
myQuery.close();
myPersister.close();
}
catch (XEPException e) {System.out.println("QueryEvents failed:\n" + e);}
} // end Main()
} // end class QueryEvents
この例では、XEP メソッドは以下のアクションを実行します。
•
EventPersister.createPersister() および EventPersister.connect() が再び呼び出され (StoreEvents の場
合と同様)、User ネームスペースへの新しい接続が確立されます。
•
EventPersister.getEvent() は、SingleStringSample エクステントに対するクエリの作成に使用される Event
の新しいインスタンスである newEvent を作成します。クエリが作成された後、newEvent は、その close() メ
ソッドを呼び出すことで破棄されます。
•
Event.createQuery() は、SingleStringSample イベントの EventQuery<> のインスタンスである myQuery を
作成します。SQL 文は、3 と変数パラメータ値の間のオブジェクト ID を持つ永続 SingleStringSample イベ
ントすべてを取得するクエリを定義します。
•
EventQuery<>.setParameter() は、値 12 を SQL パラメータに割り当てます。
•
EventQuery<>.execute() はこのクエリを実行します。クエリが正常に実行された場合、myQuery に、そのク
エリに一致する SingleStringSample イベントすべてのオブジェクト ID をリストする結果セットが含まれるよ
うになります。
12 Caché eXTreme での Java の使用法
EventPersister の作成と接続
•
EventQuery<>.getNext() は、引数として null を指定して呼び出され、それにより、結果セットの最初の項
目がフェッチされ、変数 currentEvent に割り当てられます。
•
while ループ内で以下のように実行されます。
–
currentEvent の name フィールドが出力されます。
–
EventQuery<>.deleteCurrent() がデータベースから最後にフェッチされたイベントを削除します。
–
EventQuery<>.getNext() が引数として最後にフェッチされたイベントを指定して再び呼び出され、その
メソッドが、そのイベントの次のイベントをフェッチする必要があることが指定されます。
これ以上項目がない場合、getNext() が null を返し、ループが終了します。
•
EventQuery<>.close() および EventPersister.close() は、すべてのイベントが出力および削除された後に
myQuery および myPersister に対して呼び出されます。これは、ネイティブ・コード・リソースを解放し、メモ
リ・リークを回避するために必要です。
これらのメソッドについては、すべてこの章で後で詳しく説明します。eXTreme 接続を開き、テストし、閉じることに関する
詳細は、“EventPersister の作成と接続” を参照してください。EventQuery<> のインスタンスの作成および使用の詳細
は、“クエリの使用法” を参照してください。
重要
常に close() を呼び出してメモリ・リークを回避
EventQuery<> および EventPersister のインスタンスが範囲外になるか再使用される前に、これらのイ
ンスタンスで必ず close() を呼び出すことが重要です。それらを閉じないと、深刻なメモリ・リークが発生
することがあります。それは、Java ガーベッジ・コレクションでは、基盤となるネイティブ・コードによって割
り当てられたリソースを解放できないためです。
2.2 EventPersister の作成と接続
EventPersister クラスは、XEP API の主なエントリ・ポイントです。その API は、データベースへの接続、スキーマのイン
ポート、トランザクションの処理、および Event のインスタンスの作成を行い、データベース内のイベントにアクセスするた
めのメソッドを提供します。
EventPersister のインスタンスは、次のメソッドによって作成され、破棄されます。
•
PersisterFactory.createPersister() — EventPersister の新しいインスタンスを返します。
•
EventPersister.close() — この EventPersister インスタンスを閉じ、それに関連するネイティブ・コード・リソースを解
放します。
以下のメソッドを使用して、接続を作成します。
•
EventPersister.connect() — namespace、username、password の String 引数を取り、指定した Caché ネームスペー
スへの eXTreme プロセス内接続を確立します。
オプションで、追加の host および port 引数を取り、eXTreme 接続の代わりに TCP/IP 接続を確立します。
1 つのプロセスで存在できる eXTreme Connection インスタンスは 1 つのみであり、すべての Connection 変数はその
インスタンスへの参照であると理解することが大切です。XEP API と他の eXTreme API を同じプロセスで使用する場合、
それらは基礎となる同じ接続を共用することになります (“グローバル API を他の eXTreme API と共に使用する方法”
を参照してください)。
以下の例は、プロセス内 eXTreme 接続を確立します。
Caché eXTreme での Java の使用法 13
eXTreme Event Persistence の使用法
EventPersister の作成と接続 : eXTreme 接続の作成
// Open an eXTreme connection
String namespace = "USER";
String username = "_SYSTEM";
String password = "SYS";
EventPersister myPersister = PersisterFactory.createPersister();
myPersister.connect(namespace,username,password);
// perform event processing here . . .
myPersister.close();
PersisterFactory.createPersister() メソッドは、EventPersister の新しいインスタンスを作成します。1 つのプロ
セスで必要なインスタンスは 1 つのみです。
EventPersister.connect() メソッドは、プロセス内 eXTreme 接続を確立します。現在のプロセスに接続が存在し
ない場合、新しい eXTreme 接続が作成されます。接続が既に存在している場合は、そのメソッドによって既存
の接続オブジェクトへの参照が返されます。
アプリケーションを終了する準備が整ったら、EventPersister.close() メソッドを呼び出して、基盤となるネイティ
ブ・コードによって使用されたリソースを解放する必要があります。
重要
常に close() を呼び出してメモリ・リークを回避
EventPersister のインスタンスが範囲外になる前に、そのインスタンスで必ず close() を呼び出すことが
重要です。それを閉じないと、深刻なメモリ・リークが発生することがあります。それは、Java ガーベッジ・
コレクションでは、基盤となるネイティブ・コードによって割り当てられたリソースを解放できないためです。
TCP/IP 接続の確立
XEP アプリケーションが別のマシン上のデータベースにアクセスする必要がある場合、プロセス内 eXTreme 接続ではな
く標準の TCP/IP 接続を確立するほうが適していることがあります。TCP/IP 接続のほうが少し低速ですが、その相違は、
格納されるイベントの複雑さによって異なります。フィールドが 1 つまたは 2 つのみの非常に単純なイベントでは、eXTreme
接続のほうが大幅に高速です。より複雑なイベントの場合、相違はさほど明確ではなく、非常に複雑なイベントでは無視
できる程度である可能性があります。
TCP/IP 接続は、以下の例に示すように connect() の呼び出しでオプションの host および port 引数が指定されている
場合に確立されます。
EventPersister の作成と接続 : TCP/IP 接続の作成
// Open a TCP/IP connection
String host = "127.0.0.1";
int port = 1972;
myPersister.connect(host, port, "User", "_SYSTEM", "SYS");
// perform event processing here . . .
myPersister.close();
EventPersister.connect() メソッドが host および port 引数、およびその後に前の例と同じ namespace、username、
および password 引数を指定して呼び出されます (この例ではハードコードされています)。これにより、指定さ
れたホスト・マシンの指定されたポートへの TCP/IP 接続が確立されます。
基礎となる接続へのアクセス
XEP は、グローバル API の上にある層であり、同じ基礎となる接続を使用します。次のメソッドは、基礎となる eXTreme
および JDBC 接続を返します。
•
EventPersister.getConnection() — 基礎となる eXTreme intersys.globals.Connection オブジェクトを返します。接続
が eXTreme ではなく、TCP/IP である場合は例外をスローします。
•
EventPersister.getJDBCConnection() — 基礎となる JDBC 接続を返します。
eXTreme Connection オブジェクトは、このドキュメントに記載されている他の API も使用する XEP アプリケーションで役
立つ可能性があります。それは、それらすべてで同じ基礎となる接続が使用されるためです。eXTreme 接続の詳細は、
グローバル API の章の “接続の作成” を参照してください。
14 Caché eXTreme での Java の使用法
スキーマのインポート
2.3 スキーマのインポート
Java クラスのインスタンスを永続イベントとして格納するには、その前にそのクラスのスキーマをインポートする必要があ
ります。スキーマによって、イベントが格納されるデータベース構造が定義されます。多くのクラスでは、Java クラスにメタ
情報を追加することなく、スキーマをインポートできます。スキーマのインポート方法をカスタマイズする必要がある場合、
またはそれが望ましい場合は、アノテーションを Java クラスに適用できます。
このセクションでは、以下の項目について説明します。
•
スキーマ・インポート・モデル — XEP によってサポートされる 2 つのスキーマ・インポート・モデルについて説明しま
す。
•
スキーマ・インポート・メソッド — importSchema() および importSchemaFull() メソッドを使用して、Java クラスを分析
し、情報をインポートして対応するデータベース・スキーマを生成します。
•
アノテーションの使用法 — XEP アノテーションを Java クラスに追加して、作成する必要があるインデックスを指定
し、インポートしないフィールドまたはシリアル化する必要があるフィールドを示すことができます。
•
IdKey の使用法 — アノテーションを使用して、IdKey (既定のオブジェクト ID の代わりに使用するインデックス値) を
指定できます。IdKey はフル・スキーマをインポートする場合に必要です。
2.3.1 スキーマ・インポート・モデル
XEP は、フラット・スキーマとフル・スキーマの 2 つの異なるスキーマ・インポート・モデルを提供しています。これらのモ
デル間の主な相違は、Java オブジェクトが Caché イベントに投影される方法です。
•
埋め込みオブジェクト・プロジェクション・モデル (フラット・スキーマ) — フラット・スキーマ をインポートします。そのス
キーマでは、インポートされたクラスによって参照されるオブジェクトがすべてシリアル化されて埋め込まれ、すべて
の祖先クラスで宣言されたフィールドはすべて、それらが、インポートされたクラス自体で宣言されているかのように
収集され、投影されます。そのクラスのインスタンスのすべてのデータは、単一の Caché %Library.Persistent オブ
ジェクトとして格納され、元の Java クラス構造に関する情報は保持されません。
•
フル・オブジェクト・プロジェクション・モデル (フル・スキーマ) — フル・スキーマをインポートします。そのスキーマで
は、インポートされたクラスによって参照されるオブジェクトがすべて別の Caché %Persistent オブジェクトとして投影
されます。継承されたフィールドは、同様に Caché %Persistent クラスにインポートされている祖先クラスのフィール
ドへの参照として投影されます。Java ソース・クラスと Caché の投影されたクラスの間には 1 対 1 の対応があるた
め、Java クラス継承構造が保持されます。
フル・オブジェクト・プロジェクションでは、元の Java クラスの継承構造が保持されますが、パフォーマンスに影響する場
合があります。パフォーマンスが重要であり、イベント・スキーマが比較的単純である場合、フラット・オブジェクト・プロジェ
クションが最適な選択になります。パフォーマンスの低下を許容できる場合、より豊富な機能および複雑なスキーマのた
めに、フル・オブジェクト・プロジェクションを使用できます。
2.3.1.1 埋め込みオブジェクト・プロジェクション・モデル (フラット・スキーマ)
既定では、XEP は、平坦化することで参照オブジェクトを投影するスキーマをインポートします。つまり、インポートされた
クラスによって参照されるオブジェクトがすべてシリアル化されて埋め込まれ、すべての祖先クラスで宣言されたフィール
ドはすべて、それらが、インポートされたクラス自体で宣言されているかのように収集され、投影されます。対応する Caché
イベントは、%Library.Persistent を拡張し、シリアル化されて埋め込まれたオブジェクト (元の Java オブジェクトに外部オ
ブジェクトへの参照が含まれていた) を含んでいます。
つまり、フラット・スキーマでは、厳密な意味での継承は Caché 側に保持されません。例えば、以下の 3 つの Java クラ
スを考えてみます。
Caché eXTreme での Java の使用法 15
eXTreme Event Persistence の使用法
class A {
String a;
}
class B extends class A {
String b;
}
class C extends class B {
String c;
}
クラス C をインポートすると、以下の Caché クラスができます。
Class C Extends
Property a
Property b
Property c
}
%Persistent ... {
As %String;
As %String;
As %String;
対応する Caché イベントは、特別にインポートしない限り、A と B のいずれのクラスに対しても生成されません。Caché
側のイベント C は、A も B も拡張しません。インポートされると A および B は、以下の構造になります。
Class A Extends
Property a
}
Class B Extends
Property a
Property b
}
%Persistent ... {
As %String;
%Persistent ... {
As %String;
As %String;
すべての処理は、対応する Caché イベントに対してのみ実行されます。例えば、タイプ C のオブジェクトに対して store()
を呼び出すと、対応する C Caché イベントのみが格納されます。
Java の子クラスが、そのスーパークラスでも宣言される同じ名前のフィールドを非表示にすると、XEP エンジンは常にそ
の子フィールドの値を使用します。
2.3.1.2 フル・オブジェクト・プロジェクション・モデル (フル・スキーマ)
フル・オブジェクト・モデルでは、一致する継承構造を Caché に作成することで、Java 継承モデルを保持するスキーマを
インポートします。すべてのオブジェクト・フィールドをシリアル化してすべてのデータを単一の Caché オブジェクトに格
納するのではなく、スキーマによって Java ソース・クラスと Caché の投影されたクラスとの間に 1 対 1 のリレーションシッ
プが確立されます。フル・オブジェクト・プロジェクション・モデルでは、参照されるクラスがそれぞれ別々に格納され、指
定されているクラスのフィールドが、対応する Caché クラスのオブジェクトへの参照として投影されます。
参照されるクラスには、ユーザ定義 IdKey (@Id または @Index — “IdKey の使用法” を参照) を作成するアノテーショ
ンが含まれている必要があります。オブジェクトが格納されるときは、参照されるすべてのオブジェクトが最初に格納され、
結果の IdKey がその親オブジェクトに格納されます。残りの XEP と同様に、一意性チェックは実行されず、既存のデー
タの変更または上書きは試みられません。データは単に、可能な限り速い速度で追加されます。IdKey 値が、既に存在
しているイベントを参照している場合、それは単にスキップされ、その既存のイベントの上書きが試みられることはありま
せん。
@Embedded クラス・レベル・アノテーションを使用すると、アノテーションで指定されたクラスのインスタンスを別々に格納
するのではなく、シリアル化されたオブジェクトとして埋め込むことで、フル・スキーマを最適化できます。
注釈
フル・オブジェクト・モデルの使用法の例は、FlightLog サンプル・プログラム (“XEP のサンプル” にリストされ
ている) を参照してください。
2.3.2 スキーマ・インポート・メソッド
XEP スキーマは、2 つの使用可能なモデルのいずれでも使用できます (前に “スキーマ・インポート・モデル” で説明
したとおり)。以下のメソッドを使用して、Java クラスを分析し、目的のタイプのスキーマをインポートします。
16 Caché eXTreme での Java の使用法
スキーマのインポート
•
EventPersister.importSchema() — フラット・スキーマ をインポートします。.jar ファイル名、完全修飾クラス名、または
クラス名の配列を指定する引数を取り、すべてのクラスおよび指定された場所で検出されたすべての依存性をイン
ポートします。正常にインポートされたクラスすべての名前を含む String 配列を返します。
•
EventPersister.importSchemaFull() — フル・スキーマ をインポートします。importSchema() と同じ引数を取り、同じク
ラス・リストを返します。このメソッドによってインポートされるクラスは、ユーザ生成 IdKey を宣言する必要があります
(“IdKey の使用法” を参照してください)。
•
Event.isEvent() — 静的 Event メソッド。引数としてすべての型の Java オブジェクトまたはクラス名を取り、指定され
ているオブジェクトが、有効な XEP イベント (“インポートされるクラスの要件” を参照) として投影可能かどうかを調
べるためのテストを行い、それが有効でない場合は適切なエラーをスローします。
インポート・メソッドは、使用されるスキーマ・モデルを除いて同一です。以下の例は、単純なテスト・クラスおよびその依
存クラスをインポートします。
スキーマのインポート : クラスとその依存関係のインポート
パッケージ test の以下のクラスがインポートされます。
public class MainClass {
public MainClass() {}
public string myString;
public test.Address myAddress;
}
public class Address {
public string street;
public string city;
public string state;
}
以下のコードは、isEvent() を呼び出してメイン・クラス test.MainClass が投影可能であることを確認してから、
importSchema() を使用してそのメイン・クラスをインポートします。test.MainClass がインポートされるときに、依
存クラス test.Address も自動的にインポートされます。
try {
Event.isEvent("test.MainClass"); // throw an exception if class is not projectable
myPersister.importSchema("test.MainClass");
}
catch (XEPException e) {System.out.writeln("Import failed:\n" + e);}
この例では、依存クラス test.Address のインスタンスは、シリアル化されて test.MainClass の他のフィールドとして同じ
Caché オブジェクトに埋め込まれます。代わりに importSchemaFull() が使用された場合、格納された test.MainClass の
インスタンスには、別の Caché クラス・エクステントに格納されている test.Address のインスタンスへの参照が含まれま
す。
2.3.3 アノテーションの使用法
XEP エンジンは、Java クラスを調べることで、XEP イベント・メタデータを推測します。追加情報は、アノテーションを使用
して Java クラスで指定できます。アノテーションは com.intersys.xep.annotations パッケージにあります。Java オブジェ
クトは、XEP 永続イベントの定義に準拠している限り (“インポートされるクラスの要件” を参照)、Caché イベントとして投
影され、アノテーションは必要ありません。
アノテーションには、投影されるクラス内の個別のフィールドに適用されるものと、クラス全体に適用されるものがあります。
•
フィールド・アノテーション — インポートされるクラスのフィールドに適用されます。
–
@Id — そのフィールドが IdKey として機能するようになることを指定します。
–
@Serialized — フィールドをシリアル化形式で格納および取得する必要があることを示します。
–
@Transient — フィールドをインポートから除外する必要があることを示します。
Caché eXTreme での Java の使用法 17
eXTreme Event Persistence の使用法
•
クラス・アノテーション — インポートされるクラス全体に適用されます。
–
@Embedded — フル・スキーマでこのクラスのフィールドを、参照ではなく (フラット・スキーマと同様に) 埋め込み
とする必要があることを示します。
–
@Index — クラスのインデックスを宣言します。
–
@Indices — 同じクラスの複数のインデックスを宣言します。
@Id (フィールド・レベル・アノテーション)
@Id でマークされたフィールドの値は、標準のオブジェクト ID を置換する IdKey として使用されます (“IdKey
の使用法” を参照してください)。このアノテーションは、クラスごとに 1 つのフィールドでのみ使用でき、そのプ
ロパティは String、int、または long である必要があります (double は許容されますが推奨されません)。複合
IdKey を作成するには、代わりに @Index アノテーションを使用します。@Id のアノテーションが付いたクラスは、
@Index を使用して複合プライマリ・キーも宣言することはできません。両方のアノテーションが同じクラスに対
して使用されている場合、例外がスローされます。
以下のパラメータを指定する必要があります。
•
generated — XEP がキー値を生成する必要があるかどうかを指定する boolean。
–
generated = true — (既定の設定) キー値は Caché によって生成され、@Id としてアノテーション
を付けたフィールドは java.lang.Long である必要があります。このフィールドは、挿入または保存の前
は null であることが前提となっており、そのような操作の完了時に XEP によって自動的に入力されま
す。
–
generated=false — アノテーションを付けたフィールドのユーザ割り当て値が IdKey 値として使用
されます。フィールドは、String、int、Integer、long、または Long にできます。
次の例では、ssn フィールドのユーザ割り当て値がオブジェクト ID として使用されます。
import com.intersys.xep.annotations.Id;
public class Person {
@Id(generated=false)
Public String ssn;
public String name;
Public String dob;
}
@Serialized (フィールド・レベル・アノテーション)
@Serialized アノテーションは、該当のフィールドをシリアル化形式で格納および取得する必要があることを
示します。
このアノテーションは、java.io.Serializable インタフェース (配列を含みます。これは暗黙的にシリアル化可能で
す) を実装するフィールドの格納を最適化します。XEP エンジンは、データの格納または取得のための既定の
メカニズムを使用するのではなく、シリアル・オブジェクト用の関連する読み取りまたは書き込みメソッドを呼び出
します。アノテーションが付いたフィールドがシリアル化可能でない場合は、例外がスローされます。シリアル化
フィールドの投影の詳細は、“データ型のマッピング” を参照してください。
例:
18 Caché eXTreme での Java の使用法
スキーマのインポート
import com.intersys.xep.annotations.Serialized;
public class MyClass {
@Serialized
public xep.samples.Serialized
serialized;
@Serialized
public int[][][][]
quadIntArray;
@Serialized
public String[][]
doubleStringArray;
}
// xep.samples.Serialized:
public class Serialized implements java.io.Serializable {
public String name;
public int
value;
}
@Transient (フィールド・レベル・アノテーション)
@Transient アノテーションは、該当のフィールドをインポートから除外する必要があることを示します。アノテー
ションを付けられたフィールドは、Caché に投影されず、イベントが格納される、またはロードされるときに無視さ
れます。
例:
import com.intersys.xep.annotations.Transient;
public class MyClass {
// this field will NOT be projected:
@Transient
public String transientField;
// this field WILL be projected:
public String projectedField;
}
@Embedded (クラス・レベル・アノテーション)
@Embedded アノテーションは、フル・スキーマが生成される場合に使用できます (“スキーマ・インポート・モデ
ル” を参照してください)。Caché に投影するときに、このクラスのフィールドを、参照ではなく (フラット・スキーマ
と同様に) シリアル化して埋め込む必要があることを示します。
例:
import com.intersys.xep.annotations.Embedded;
@Embedded
public class Address {
String street;
String city;
String zip;
State
state;
}
import com.intersys.xep.annotations.Embedded;
public class MyOuterClass {
@Embedded
public static class MyInnerClass {
public String
innerField;
}
}
@Index (フィールド・レベル・アノテーション)
@Index アノテーションを使用して、インデックスを宣言できます。
以下のパラメータに引数を指定する必要があります。
•
name — 複合インデックスの名前を含む String。
•
fields — 複合インデックスを構成するフィールドの名前を含む String の配列。
•
type — インデックス・タイプ。xep.annotations.IndexType 列挙には、以下の使用可能なタイプがあります。
–
IndexType.none — 既定値。インデックスがないことを示します。
Caché eXTreme での Java の使用法 19
eXTreme Event Persistence の使用法
–
IndexType.bitmap — ビットマップ・インデックス ("Caché SQL の使用法" の “ビットマップ・インデック
ス” を参照してください)。
–
IndexType.bitslice — ビットスライス・インデックス ("Caché SQL の使用法" の “概要” を参照して
ください)。
–
IndexType.simple — 1 つ以上のフィールドに対する標準インデックス。
–
IndexType.idkey — 標準 ID の代わりに使用されるインデックス (“IdKey の使用法” を参照してくだ
さい)。
例:
import com.intersys.xep.annotations.Index;
import com.intersys.xep.annotations.IndexType;
@Index(name="indexOne",fields={"ssn","dob"},type=IndexType.idkey)
public class Person {
public String name;
public Date dob;
public String ssn;
}
@Indices (クラス・レベル・アノテーション)
@Indices アノテーションを使用すると、1 つのクラスに対してさまざまなインデックスからなる 1 つの配列を指
定できます。その配列の各要素は、@Index タグです。
例:
import com.intersys.xep.annotations.Index;
import com.intersys.xep.annotations.IndexType;
import com.intersys.xep.annotations.Indices;
@Indices({
@Index(name="indexOne",fields={"myInt","myString"},type=IndexType.simple),
@Index(name="indexTwo",fields={"myShort","myByte","myInt"},type=IndexType.simple)
})
public class MyTwoIndices {
public int myInt;
public Byte myByte;
public short myShort;
public String myString;
}
2.3.4 IdKey の使用法
IdKey は、既定のオブジェクト ID の代わりに使用されるインデックス値です。単純 IdKey と複合 IdKey のどちらも XEP
によってサポートされており、フル・スキーマでインポートされる Java クラスにはユーザ生成 IdKey が必要です (“スキー
マ・インポート・メソッド” を参照してください)。単一フィールドに対する IdKey は @Id アノテーションで作成できます。複
合 IdKey を作成するには、IndexType idkey と共に @Index アノテーションを追加します。例えば、以下のクラスを指定
したとします。
class Person {
String name;
Integer id;
Date dob;
}
既定のストレージ構造では、添え字として標準オブジェクト ID を使用します。
^PersonD(1)=$LB("John",12,"1976-11-11")
以下のアノテーションは、name および id フィールドを使用して、標準オブジェクト ID を置き換える newIdKey という名
前の複合 IdKey を作成します。
@Index(name="newIdKey",fields={"name","id"},type=IndexType.idkey)
20 Caché eXTreme での Java の使用法
イベントの格納と変更
これは、以下のグローバル構造になります。
^PersonD("John",12)=$LB("1976-11-11")
XEP では、SQL コマンドなど他の方法で追加された IdKey も処理されます ("Caché SQL の使用法" の “インデックス
での Unique、PrimaryKey、IDKey キーワードの使用” を参照してください)。XEP エンジンは、基本クラスに IdKey が含
まれているかどうかを自動的に判別し、適切なグローバル構造を生成します。
IdKey の使用法にはいくつかの制限があります。
•
IdKey を宣言するクラスには、それが他のインデックスも宣言している場合、非同期にインデックスを付けることはで
きません。
•
複合 IdKey ではフィールドの数に制限はありませんが、フィールドが string、int、Integer、long、または Long である
ことが必要です。double も使用できますが、非推奨です。
•
IdKey 値は一意である必要があります。IdKey がユーザ生成である場合、一意性は呼び出し元のアプリケーション
で確保する必要があり、XEP によって強制されることはありません。アプリケーションで、データベースに既に存在し
ているキー値を持つイベントの追加が試みられると、その試みは暗黙的に無視され、既存のイベントは変更されま
せん。
•
非常に高い継続的な挿入レートを必要とするまれな特定の状況では、パフォーマンスが低下することがあります。
IdKey に基づくイベントの取得、更新、および削除を可能にする Event メソッドの説明は、“格納されたイベントへのアク
セス” を参照してください。
IdKey および標準 Caché ストレージ・モデルの詳細は、"Caché グローバルの使用法" の “多次元ストレージの SQL お
よびオブジェクトの使用法” を参照してください。SQL での IdKey の詳細は、"Caché SQL の使用法" の “インデックス
の定義と構築” を参照してください。
サンプル・プログラム IdKeyTest および FlightLog は、IdKey の使用例を示しています (サンプル・プログラムの詳細は、
“XEP のサンプル” を参照してください)。
2.4 イベントの格納と変更
クラスのスキーマがインポートされると (“スキーマのインポート” を参照)、Event のインスタンスを作成して、そのクラス
のイベントを格納し、それにアクセスできます。Event クラスは、永続イベントの格納、更新、または削除、そのクラス・エク
ステントに対するクエリの作成、インデックス更新の制御を行うメソッドを提供します。このセクションでは、以下の項目に
ついて説明します。
•
イベント・インスタンスの作成と永続イベントの格納 — Event のインスタンスの作成方法およびそれを使用して指定
したクラスの永続イベントを格納する方法について説明します。
•
格納されたイベントへのアクセス — 指定したクラスの永続イベントをフェッチ、変更、および削除する Event メソッド
について説明します。
•
インデックス更新の制御 — インデックス・エントリを更新するタイミングを制御することで処理の効率性を高めることが
できる Event メソッドについて説明します。
2.4.1 イベント・インスタンスの作成と永続イベントの格納
Event クラスのインスタンスは、以下のメソッドによって作成され、破棄されます。
•
EventPersister.getEvent() — className String 引数を取り、指定したクラスのイベントを格納し、それにアクセスでき
る Event のインスタンスを返します。オプションで、インデックス・エントリを更新する既定の方法を指定する indexMode
引数を取ります (詳細は、“インデックス更新の制御” を参照してください)。
Caché eXTreme での Java の使用法 21
eXTreme Event Persistence の使用法
•
Event.close() — この Event インスタンスを閉じ、それに関連するネイティブ・コード・リソースを解放します。
注釈
ターゲット・クラス
Event のインスタンスは、getEvent() の呼び出しで className 引数によって指定されたクラスのイベントのみを
格納、アクセス、または照会できます。この章では、クラス className を、ターゲット・クラスと呼びます。
以下の Event メソッドは、ターゲット・クラスの Java オブジェクトを永続イベントとして格納します。
•
store() — ターゲット・クラスの 1 つ以上のインスタンスをデータベースに追加します。引数として 1 つのイベント、ま
たは複数のイベントからなる 1 つの配列を取り、格納されているイベントごとに long データベース ID (データベー
ス ID を返すことができない場合は 0) を返します。
イベントが格納されるときは、どのようなテストも行われず、既存のデータが変更されたり、上書きされることはありません。
各イベントは、可能な限り速い速度でエクステントに追加されるか、指定されたキーを持つイベントが既にデータベース
に存在する場合は暗黙的に無視されます。
以下の例は、SingleStringSample クラスの Event のインスタンスを作成し、それを使用して Java SingleStringSample オ
ブジェクトの配列を永続イベントとして格納します。
イベントの格納と変更 : オブジェクトの配列の格納
SingleStringSample[] eventData = SingleStringSample.generateSampleData(12);
long itemID = 0;
int itemCount = 0;
try {
Event newEvent = myPersister.getEvent("xep.samples.SingleStringSample");
for (int i=0; i < eventData.length; i++) {
try {
itemID = newEvent.store(eventData[i]); // store event
itemCount++;
}
catch (XEPException e) {System.out.println("Not a valid event:\n" + e);}
}
System.out.println("Stored " + itemCount + " of " + eventData.length + " events");
newEvent.close();
}
catch (XEPException e) {System.out.println("Event storage failed:\n" + e);}
注釈
SingleStringSample クラスを定義および使用するサンプル・プログラムの詳細は、“XEP のサンプル” を参照
してください。
2.4.2 格納されたイベントへのアクセス
永続イベントが格納されると、そのターゲット・クラスの Event インスタンスが、イベントを読み取り、更新、および削除する
ための以下のメソッドを提供します。
•
deleteObject() — 引数としてデータベース・オブジェクト ID または IdKey を取り、データベースから指定したイベン
トを削除します。
•
getObject() — 引数としてデータベース・オブジェクト ID または IdKey を取り、指定したイベントを返します。
•
updateObject() — 引数としてデータベース・オブジェクト ID または IdKey およびターゲット・クラスの Object を取り、
指定したイベントを更新します。
ターゲット・クラスが標準オブジェクト ID を使用する場合、それは long 値として指定されます (前のセクションで説明した
store() メソッドで返されるとおり)。ターゲット・クラスが IdKey を使用する場合、それは Object の配列として指定され、そ
の配列の各項目はその IdKey を構成するフィールドの 1 つの値です (“IdKey の使用法” を参照してください)。
以下の例では、一連の永続 SingleStringSample イベントが格納されていることと、事前に作成した配列 itemIdList にそ
れらのイベントのいくつかに対するオブジェクト ID 値が含まれていることが前提となっています (配列は、事前の store()
の呼び出しまたは後で “クエリの作成と実行” で説明するようにクエリによって返される可能性があります)。この例は、
22 Caché eXTreme での Java の使用法
イベントの格納と変更
配列を読み取り、対応する永続イベントをフェッチします。配列の前半に含まれているイベントは更新され、残りは削除さ
れます。
イベントの格納と変更 : イベントのフェッチ、更新、および削除
// itemIdList is a previously created array of SingleStringSample event Ids
try {
Event newEvent = myPersister.getEvent("xep.samples.SingleStringSample");
int lastUpdate = itemIdList.length/2; // discard items with Ids higher than this
int itemCount = 0;
for (int i=0; i < itemIdList.length; i++) {
try {
SingleStringSample eventData = (SingleStringSample)newEvent.getObject(itemIdList[i]);
if (i<=lastUpdate) {
eventData.name = eventData.name + " updated!";
newEvent.updateObject(itemIdList[i], eventData);
itemCount++;
} else {
newEvent.deleteObject(itemIdList[i]);
}
}
catch (XEPException e) {System.out.println("Failed to process event:\n" + e);}
}
System.out.println("Updated " + itemCount + " of " + itemIdList.length + " events");
newEvent.close();
}
catch (XEPException e) {System.out.println("Event processing failed:\n" + e);}
注釈
SingleStringSample クラスを定義および使用するサンプル・プログラムの詳細は、“XEP のサンプル” を参照
してください。
テスト・データの削除
テスト・データベースを初期化する際は、多くの場合、クラス全体を削除するか、指定されたエクステントのすべてのイベ
ントを削除すると便利です。以下の EventPersister メソッドは、クラスおよびエクステントを Caché データベースから削
除します。
•
deleteClass() — 引数として className 文字列を取り、指定した Caché クラスを削除します。
•
deleteExtent() — 引数として className 文字列を取り、指定したクラスのエクステントのすべてのイベントを削除しま
す。
2.4.3 インデックス更新の制御
既定では、データベース内のイベントに対して動作する Event メソッドの 1 つの呼び出しを実行するときに、インデック
スは更新されません (“格納されたイベントへのアクセス” を参照してください)。インデックスは非同期に更新され、更新
は、すべてのトランザクションが完了し、Event インスタンスが閉じられた後にのみ実行されます。一意のインデックスに
対して一意性のチェックは実行されません。
注釈
このセクションは、標準オブジェクト ID または生成された IdKey を使用するクラスにのみ適用されます (“IdKey
の使用法” を参照してください)。ユーザ割り当て IdKey を持つクラスは、同期でのみ更新できます。
この既定のインデックス作成動作を変更する方法はいくつかあります。Event インスタンスが EventPersister.getEvent()
によって作成される場合 (“イベント・インスタンスの作成と永続イベントの格納” を参照)、オプションの indexMode パラ
メータを設定して既定のインデックス作成動作を指定できます。以下のオプションを使用できます。
•
Event.INDEX_MODE_ASYNC_ON — 非同期のインデックス作成を可能にします。これは、indexMode パラメータが指
定されていない場合の既定の設定です。
•
Event.INDEX_MODE_ASYNC_OFF — startIndexing() メソッドが呼び出されない限り、インデックス作成は実行されま
せん。
Caché eXTreme での Java の使用法 23
eXTreme Event Persistence の使用法
•
Event.INDEX_MODE_SYNC — インデックス作成は、エクステントが変更されるたびに実行されます。これは多数のト
ランザクションの場合は非効率的になる可能性があります。クラスにユーザ割り当て IdKey がある場合は、このイン
デックス・モードを指定する必要があります。
以下の Event メソッドを使用すると、ターゲット・クラスのエクステントに対する非同期インデックス更新を制御できます。
•
startIndexing() — ターゲット・クラスのエクステントに対して非同期インデックス作成を開始します。インデックス・モー
ドが Event.INDEX_MODE_SYNC である場合は、例外をスローします。
•
stopIndexing() — エクステントに対する非同期インデックス作成を停止します。Event インスタンスを閉じるときにイン
デックスを更新しないようにする場合は、Event.close() を呼び出す前にこのメソッドを呼び出します。
•
waitForIndexing() —int timeout 値を引数として取り、非同期インデックス作成が完了するまで待機します。timeout
値は、待機する秒数を指定します (-1 の場合は永久に待機し、0 の場合は直ちに返します)。インデックス作成が
完了した場合は true を返し、インデックス作成が完了する前に待機がタイムアウトした場合は false を返します。
インデックス・モードが Event.INDEX_MODE_SYNC である場合は、例外をスローします。
2.5 クエリの使用法
Event のインスタンスは、EventQuery<> のインスタンスを作成することで、そのターゲット・クラスのエクステントに対して
制限付き SQL クエリを実行できます。EventQuery<> クラスは、ターゲット・クラスのエクステントに対して、事前に定義さ
れた SQL クエリを実行するメソッドと、そのクエリ結果セットにアクセスして、データベースから個別のイベントを取得、更
新、および削除できる関連メソッドを提供します。
以下の項目について説明します。
•
クエリの作成と実行 — EventQuery<> クラスのメソッドを使用してクエリを実行する方法について説明します。
•
クエリ・データの処理 — EventQuery<> 結果セットの項目にアクセスし、それを変更する方法について説明します。
•
EventQueryIterator<> の使用法 — 結果セットの項目にアクセスまたはその項目を変更するための代替メソッド
(Iterator に類似) について説明します。
•
フェッチ・レベルの定義 — クエリによって返されるデータの量の制御方法について説明します。
2.5.1 クエリの作成と実行
以下のメソッドは、EventQuery<> のインスタンスを作成および破棄します。
•
Event.createQuery() — SQL クエリのテキストを含む String 引数を取り、EventQuery<T> のインスタンスが返されま
す。パラメータ T は、親 Event のターゲット・クラスです。
•
EventQuery<>.close() — この EventQuery<> インスタンスを閉じ、それに関連するネイティブ・コード・リソースを解放
します。
EventQuery<T> のインスタンスによって実行されるクエリは、指定した汎用タイプ T (クエリ・オブジェクトを作成した Event
インスタンスのターゲット・クラス) の Java オブジェクトを返します。EventQuery<> クラスによってサポートされるクエリは、
以下に示すとおり、SQL の SELECT 文のサブセットです。
•
クエリは、SELECT 節、FROM 節、および (オプションで) WHERE、ORDER BY などの標準 JDBC SQL 節から構成さ
れる必要があります。
•
SELECT 節および FROM 節は、構文的に正当ですが、現実的にはクエリ実行中には無視されます。マップされてい
るすべてのフィールドは、常に、ターゲット・クラス T のエクステントからフェッチされます。
24 Caché eXTreme での Java の使用法
クエリの使用法
•
SQL 式は、任意の型の配列、組み込みオブジェクト、または組み込みオブジェクトのフィールドのいずれも参照でき
ません。
•
Caché システム生成オブジェクト ID は、%ID として参照することができます。先頭の % のおかげで、これはフィール
ドが呼び出した id と Java クラス内で競合しません。
以下の EventQuery<> メソッドは、クエリを定義および実行します。
•
setParameter() — この EventQuery<> と関連付けられた SQL クエリのパラメータを結合します。int index および
Object value を引数として取ります。ここで index は設定するパラメータを指定し、value は、指定されているパラメー
タに結合する値です。
•
execute() — この EventQuery<> と関連付けられた SQL クエリを実行します。クエリが正常に実行された場合、この
EventQuery<> には、後で説明するメソッドでアクセスできる結果セットが含まれます (“クエリ・データの処理” およ
び “EventQueryIterator<> の使用法” を参照してください)。
以下の例は、xep.samples.SingleStringSample エクステント内のイベントに対して単純なクエリを実行します。
クエリの使用法 : クエリの作成と実行
Event newEvent = myPersister.getEvent("xep.samples.SingleStringSample");
String sql =
"SELECT * FROM xep_samples.SingleStringSample WHERE %ID BETWEEN ? AND ?";
EventQuery<SingleStringSample> myQuery = newEvent.createQuery(sql);
myQuery.setParameter(1, 3); // assign value 3 to first SQL parameter
myQuery.setParameter(2,12); // assign value 12 to second SQL parameter
myQuery.execute(); // get resultset with IDs between 3 and 12
2.5.2 クエリ・データの処理
以下の EventQuery<> メソッドは、クエリ結果セットの項目にアクセスし、変更します。
•
getNext() — 引数としてターゲット・クラスのオブジェクトを取り、結果セットの次の項目を返します (引数が null の
場合は結果セットの最初の項目を返します)。結果セットにそれ以上項目がない場合は、null を返します。
•
getAll() — オブジェクトの配列として結果セット全体を返します。
•
deleteCurrent() — データベースから getNext() によって最後にフェッチされたイベントを削除します。
•
updateCurrent() — 引数としてターゲット・クラスのオブジェクトを取り、それを使用して getNext() に最後にフェッチさ
れたイベントを更新します。
クエリの使用法 : EventQuery<> での反復
// Iterate through the returned data set, printing and deleting each event
SingleStringSample currentEvent = new SingleStringSample();
currentEvent = myQuery.getNext(currentEvent);
while (currentEvent != null) {
System.out.println("Retrieved " + currentEvent.name);
myQuery.deleteCurrent();
currentEvent = myQuery.getNext(currentEvent);
}
myQuery.close();
2.5.3 EventQueryIterator<> の使用法
EventQueryIterator<> クラスは、EventQuery<> クラスの代わりとなるものです。提供する機能はまったく同じですが、動
作方法が標準 Java Iterator により類似しています。
Caché eXTreme での Java の使用法 25
eXTreme Event Persistence の使用法
注釈
クエリ結果には、EventQuery<> メソッドを直接呼び出すか、または EventQueryIterator<> のインスタンスを取
得してそのメソッドを使用することによってアクセスできますが、これらのアクセス・メソッド両方を同時に使用し
ないでください。反復子を取得してそのメソッドを呼び出し、同時に EventQuery<> メソッドも直接呼び出すと、
予期できない結果を招く可能性があります。
以下の EventQuery<> メソッドは、EventQueryIterator<E> のインスタンスを作成します (ここで E は親 EventQuery<E>
と同じターゲット・クラスです)。
•
getIterator() — ターゲット・クラスのエクステントに対するクエリの結果に繰り返し処理を実行するために使用できる
EventQueryIterator<E> を返します。
以下の EventQueryIterator<> メソッドは、クエリ結果セットにリストされるターゲット・クラスのイベントにアクセスし、変更し
ます。
•
hasNext() — クエリ結果セットにさらに行がある場合、true を返し、行がない場合は false を返します。
•
next() — 結果セット内の次の項目を返します。
•
remove() — データベースから next() によって最後にフェッチされたイベントを削除します。
•
set() — 引数としてターゲット・クラスのオブジェクトを取り、その値を next() によって最後にフェッチされたイベントに
割り当てます。
クエリの使用法 : EventQueryIterator<> での反復
// Iterate through the returned data set, printing and deleting each event
EventQueryIterator<xep.samples.SingleStringSample> iterator = myQuery.getIterator();
SingleStringSample currentEvent = null;
while (iterator.hasNext()) {
currentEvent = iterator.next();
System.out.println("Retrieved " + currentEvent.name);
myQuery.deleteCurrent();
}
2.5.4 フェッチ・レベルの定義
フェッチ・レベルは、クエリを実行するときに返されるデータの量を制御するために使用できる Event プロパティです。こ
れは、基礎となるイベントが複雑で、かつイベント・データの小さいサブセットのみが必要な場合に特に便利です。
以下の EventQuery<> メソッドは、現在のフェッチ・レベルを設定し、返します。
•
getFetchLevel() — Event の現在のフェッチ・レベルを示す int を返します。
•
setFetchLevel() — 引数として Event フェッチ・レベル列挙の値の 1 つを取り、そのフェッチ・レベルを Event に対し
て設定します。
以下のフェッチ・レベル値がサポートされます。
•
Event.OPTION_FETCH_LEVEL_ALL — これは既定です。すべてのデータがフェッチされ、返されるイベントは完全
に初期化されます。
•
Event.OPTION_FETCH_LEVEL_DATATYPES_ONLY — データ型フィールドのみがフェッチされます。これには、す
べてのプリミティブ型、すべてのプリミティブ・ラッパ、java.lang.String、java.math.BigDecimal、java.util.Date、
java.sql.Date、java.sql.Time、java.sql.Timestamp、および enum 型が含まれます。その他のフィールドはすべて null
に設定されます。
•
Event.OPTION_FETCH_LEVEL_NO_ARRAY_TYPES — 配列を除くすべてのタイプがフェッチされます。ディメンジョ
ンに関係なく、配列タイプのすべてのフィールドは null に設定されます。すべてのデータ型、オブジェクト・タイプ
(シリアル化タイプを含む) およびコレクションがフェッチされます。
26 Caché eXTreme での Java の使用法
XEP からの Caché メソッドの呼び出し
•
Event.OPTION_FETCH_LEVEL_NO_OBJECT_TYPES — オブジェクト・タイプを除くすべてのタイプがフェッチされま
す。シリアル化タイプもオブジェクト・タイプとみなされ、フェッチされません。すべてのデータ型、配列タイプ、および
コレクションがフェッチされます。
•
Event.OPTION_FETCH_LEVEL_NO_COLLECTIONS — java.util.List、java.util.Map、および java.util.Set の実装を
除くすべてのタイプがフェッチされます。
2.6 XEP からの Caché メソッドの呼び出し
以下の EventPersister メソッドは、Caché クラス・メソッドを呼び出します。
•
callClassMethod() — 指定した Caché ObjectScript クラス・メソッドを呼び出します。className および methodName
に対して String 引数を取り、ほかに Caché メソッドに渡される 0 個以上の引数を取ります。String、int、long、また
は double のインスタンスになる Object として Caché メソッド返り値を返します。
•
callVoidClassMethod() — 指定した Caché ObjectScript void クラス・メソッドを呼び出します。className および
methodName に対して String 引数を取り、ほかに Caché メソッドに渡される 0 個以上の引数を取ります。
以下の EventPersister メソッドは Caché 関数およびプロシージャを呼び出します ("Caché ObjectScript の使用法" の
“ユーザ定義コード” を参照してください)。
•
callFunction() — 指定した Caché ObjectScript 関数を呼び出します。functionName および routineName に対して
String 引数を取り、ほかに Caché メソッドに渡される 0 個以上の引数を取ります。String、int、long、または double
のインスタンスになる Object として Caché 関数の返り値を返します。
•
callProcedure() — 指定した Caché ObjectScript プロシージャを呼び出します。procedureName および routineName
に対して String 引数を取り、ほかに Caché メソッドに渡される 0 個以上の引数を取ります。
2.7 スキーマ・マッピング・ルール
このセクションでは、Java クラスが Caché イベント・スキーマにどのようにマップされるかについて詳細に説明します。ここ
で説明する内容は以下のとおりです。
•
インポートされるクラスの要件 — 永続イベントとして投影できるオブジェクトを作成するために Java クラスが満たす
必要がある構造ルールについて説明します。
•
名前付け規約 — Java クラスおよびフィールドの名前を Caché の名前付け規則に従うように変換する方法について
説明します。
•
データ型のマッピング — 使用できる Java データ型をリストし、これらが対応する Caché のデータ型にどのようにマッ
プされるかについて説明します。
•
InterfaceResolver の実装 — インポート中に InterfaceResolver インタフェースの実装を使用して、インタフェースと
して宣言されたフィールドの実際のクラスを返すことができます。
2.7.1 インポートされるクラスの要件
XEP スキーマ・インポート・メソッドは、以下の要件を満たさない限り、Java クラスに対して有効なスキーマを作成できませ
ん。
Caché eXTreme での Java の使用法 27
eXTreme Event Persistence の使用法
•
インポートされる Caché クラスが、格納されたイベントにクエリを実行してそれにアクセスするために使用される場合、
Java ソース・クラスは引数のないパブリック・コンストラクタを備えている必要があります。
•
Java ソース・クラスは、java.lang.Object として宣言されたフィールド、または java.lang.Object を宣言の一部として使
用する配列、リスト、セットまたはマップを含むことはできません。XEP エンジンがこのようなフィールドを検出すると、
例外がスローされます。
Event.isEvent() メソッドを使用して、Java クラスまたはオブジェクトを分析し、それが XEP の意味で有効なイベントを作
成できるかどうかを判定できます。前述の条件に加えて、以下の条件が検出された場合、このメソッドは XEPException
をスローします。
•
循環した依存関係
•
決まった形式のない List または Map
•
String、プリミティブ、プリミティブ・ラッパのいずれでもない Map キー値
永続イベントのフィールドは、プリミティブで、そのラッパ、一時データ型、オブジェクト (組み込み/連続オブジェクトとし
て投影)、列挙、および java.util.List、java.util.Set、および java.util.Map から派生したデータ型にできます。これらのデー
タ型を配列、入れ子になったコレクション、および配列のコレクションに含めることもできます。
既定では、投影されるフィールドは、Java クラスの一部の機能を保持できません。特定のフィールドが以下の方法で変
更されます。
•
Java クラスに静的フィールドが含まれていても、これらは既定でプロジェクションから除外されます。対応する Caché
プロパティはありません。追加のフィールドは、@Transient アノテーションを使用して除外できます (“アノテーショ
ンの使用法” を参照)。
•
フラット・スキーマ (“スキーマ・インポート・モデル” を参照) では、内部 (入れ子にされた) Java クラスを含むすべて
のオブジェクト・タイプは、%SerialObject クラスとして Caché に投影されます。オブジェクト内のフィールドは、別の
Caché プロパティとして投影されません。このオブジェクトは、Caché ObjectScript の観点からは不明瞭です。
•
フラット・スキーマは、すべての継承されたフィールドを、それらが子クラスで宣言されたかのように投影します。
さまざまなデータ型を投影する方法の詳細は、“データ型のマッピング” を参照してください。
2.7.2 名前付け規約
対応する Caché クラスおよびフィールドの名前は Java での名前と同じです。ただし、Java では許可されているが Caché
では許可されていない以下の 2 つの特別な文字は例外です。
•
$ (ドル記号) は、Caché 側では "d" の 1 文字に投影されます。
•
_ (アンダースコア) は、Caché 側では "u" の 1 文字に投影されます。
クラス名は 255 文字に制限されます。この文字数はほとんどのアプリケーションで十分のはずです。ただし、対応するグ
ローバル名には 31 文字の制限があります。これは通常 1 対 1 マッピングには不十分なため、XEP エンジンは、31 文
字よりも長いクラス名用に透過的に一意のグローバル名を生成します。生成されるグローバル名は元の名前と同じでは
ありませんが、それでも簡単に認識できるはずです。例えば、xep.samples.SingleStringSample クラスは、グローバル名
xep.samples.SingleStrinA5BFD を受け取ります。
2.7.3 データ型のマッピング
永続イベントのフィールドは、以下のデータ型のいずれかにできます。
•
プリミティブ・タイプ、プリミティブ・ラッパおよび java.lang.String
28 Caché eXTreme での Java の使用法
スキーマ・マッピング・ルール
•
一時データ型 (java.sql.Time、java.sql.Date、java.sql.Timestamp および java.util.Date)
•
オブジェクト・タイプ (フラット・スキーマで埋め込み/シリアル・オブジェクトとして投影される)
•
Java enum データ型
•
java.util.List、java.util.Set および java.util.Map から派生したデータ型
•
入れ子になったコレクション (例えばマップのリスト) および配列のコレクション
•
上記のいずれかの配列
以下のセクションでは、現在サポートされている Java タイプおよび対応する Caché タイプをリストします。
プリミティブおよびプリミティブ・ラッパ
以下の Java プリミティブおよびラッパは Caché %String としてマップされます。
•
char, java.lang.Character, java.lang.String
以下の Java プリミティブおよびラッパは Caché %Integer としてマップされます。
•
boolean, java.lang.Boolean
•
byte, java.lang.Byte
•
int, java.lang.Integer
•
long, java.lang.Long
•
short, java.lang.Short
以下の Java プリミティブおよびラッパは Caché %Float としてマップされます。
•
double, java.lang.Double
•
float, java.lang.Float
一時データ型
以下の Java 一時データ型は Caché %String としてマップされます。
•
java.sql.Date
•
java.sql.Time
•
java.sql.Timestamp
•
java.util.Date
オブジェクト・タイプ
インポートされる Java クラス (importSchema() または importFullSchema() の呼び出しで指定されるターゲット・
クラス) は、Caché %Persistent クラスとして投影されます。必須情報も、スーパークラスおよび依存クラスからイ
ンポートされますが、スキーマ・インポート・モデル (“スキーマ・インポート・モデル” を参照) によってこの情報
が Caché にどのように格納されるのかが決定されます。
•
フラット・スキーマでは、インポートされたクラスでフィールド・タイプとして現れたクラスは、%Serial Caché ク
ラスとして投影され、親 %Persistent クラスに埋め込まれます。インポートされたクラスのスーパークラスは投
影されません。代わりに、スーパークラスから継承されたすべてのフィールドが、インポートされたクラスのネ
イティブ・フィールドであるかのように投影されます。
Caché eXTreme での Java の使用法 29
eXTreme Event Persistence の使用法
•
フル・スキーマでは、スーパークラスおよび依存クラスは、独立した %Persistent Caché クラスとして投影さ
れ、インポートされるクラスには、それらのクラスへの参照が含まれるようになります。
java.lang.Object クラスはサポートされていないクラスです。XEP エンジンが java.lang.Object として宣言された
フィールド、またはこれを使用する配列、リスト、セット、マップを検出すると例外がスローされます。
シリアル化
@Serialized アノテーション (“アノテーションの使用法” を参照) のマークが付けられたフィールドはすべて
%Binary としてシリアル化形式で投影されます。
配列
以下の規則が配列に適用されます。
•
バイト配列および文字配列を除いて、プリミティブ型、プリミティブ・ラッパ型、および一時データ型のすべて
の 1 次元配列は、基本ベース型のリストとしてマップされます。
•
1 次元バイト配列 (byte[] および java.lang.Byte[]) は %Binary としてマップされます。
•
1 次元文字配列 (char[] および java.lang.Character[]) は %String としてマップされます。
•
オブジェクトの 1 次元配列はオブジェクトのリストとしてマップされます。
•
すべての多次元配列は、%Binary としてマップされ、Caché ObjectScript の観点からは不明瞭です。
•
配列は暗黙的にシリアル化可能であり、@Serialized のアノテーションを付けることができます。
列挙
Java enum 型は、Caché %String として投影され、名前のみが格納されます。Caché から取得されると、Java
enum オブジェクト全体が再構成されます。列挙の配列、リスト、およびその他のコレクションもサポートされます。
コレクション
java.util.List および java.util.Set から派生したクラスは、Caché リストとして投影されます。java.util.Map から派
生したクラスは、Caché 配列として投影されます。決まった形式のない Java リスト、セットおよびマップはサポー
トされません (タイプ・パラメータを使用する必要があります)。入れ子になったリスト、セットおよびマップ、配列の
リスト、セットおよびマップ、ならびにリスト、セットまたはマップの配列はすべて、%Binary として投影され、Caché
に関しては不明瞭と見なされます。
2.7.4 InterfaceResolver の実装
フラット・スキーマがインポートされるとき、継承階層に関する情報は保持されません (“スキーマ・インポート・モデル” を
参照してください)。これにより、インタフェースとして宣言されているタイプを持つフィールドを処理するときに問題が発生
します。これは、XEP エンジンは、フィールドの実際のクラスを把握する必要があるためです。既定では、そのようなフィー
ルドはフラット・スキーマにインポートされません。この動作は、com.intersys.xep.InterfaceResolver の実装を作成し、処
理中の特定のインタフェース・タイプを解決することで、変更できます。
注釈
InterfaceResolver は、フラット・スキーマ・インポート・モデルにのみ関連しており、Java クラス継承構造は保持
されません。フル・スキーマ・インポート・モデルでは、Java と Caché のクラスの間に 1 対 1 のリレーションシッ
プが確立されるため、インタフェースの解決に必要な情報が保持されます。
InterfaceResolver の実装は、フラット・スキーマ・インポート・メソッド importSchema() を呼び出す前に EventPersister
に渡されます (“スキーマ・インポート・メソッド” を参照してください)。これにより、XEP エンジンに、処理中にインタフェー
ス・タイプを解決する方法が提供されます。以下の EventPersister メソッドは、使用される実装を指定します。
30 Caché eXTreme での Java の使用法
スキーマ・マッピング・ルール
•
EventPersister.setInterfaceResolver() — 引数として InterfaceResolver のインスタンスを取ります。importSchema()
が呼び出されると、指定されたインスタンスを使用して、インタフェースとして宣言されたフィールドを解決します。
以下の例は、クラスごとに InterfaceResolver の異なるカスタマイズされた実装を呼び出して、2 つの異なるクラスをイン
ポートします。
スキーマ・マッピング・ルール : InterfaceResolver の適用
try {
myPersister.setInterfaceResolver(new test.MyFirstInterfaceResolver());
myPersister.importSchema("test.MyMainClass");
myPersister.setInterfaceResolver(new test.MyOtherInterfaceResolver());
myPersister.importSchema("test.MyOtherClass");
}
catch (XEPException e) {System.out.writeln("Import failed:\n" + e);}
setInterfaceResolver() の最初の呼び出しによって、インポート・メソッドの呼び出し中に使用する実装として
MyFirstInterfaceResolver (次の例で説明) の新しいインスタンスが設定されます。この実装は、
setInterfaceResolver() が再び呼び出されて別の実装が指定されるまで、importSchema() のすべての呼び出し
で使用されます。
importSchema() の最初の呼び出しで、クラス test.MyMainClass がインポートされます。これには、インタフェー
ス test.MyFirstInterface として宣言されたフィールドが含まれています。MyFirstInterfaceResolver のインスタ
ンスが、そのインポート・メソッドで使用され、このフィールドの実際のクラスが解決されます。
setInterfaceResolver() の 2 回目の呼び出しによって、importSchema() が再び呼び出されたときに使用する新
しい実装として別の InterfaceResolver クラスのインスタンスが設定されます。
InterfaceResolver のすべての実装で、以下のメソッドを定義する必要があります。
•
InterfaceResolver.getImplementationClass() は、インタフェースとして宣言されたフィールドの実際のデータ型を返
します。このメソッドには以下のパラメータがあります。
–
interfaceClass — 解決されるインタフェース。
–
declaringClass — interfaceClass として宣言されたフィールドが含まれているクラス。
–
fieldName — インタフェースとして宣言された declaringClass のフィールドの名前が含まれている文字列。
次の例は、インタフェース、そのインタフェースの実装、およびそのインタフェースのインスタンスを解決する
InterfaceResolver の実装を定義します。
スキーマ・マッピング・ルール : InterfaceResolver の実装
この例では、解決されるインタフェースは、test.MyFirstInterface です。
package test;
public interface MyFirstInterface{ }
test.MyFirstImpl クラスは、InterfaceResolver によって返される必要がある test.MyFirstInterface の実装です。
package test
public class MyFirstImpl implements MyFirstInterface {
public MyFirstImpl() {}
public MyFirstImpl(String s) { fieldOne = s; }
public String fieldOne;
}
InterfaceResolver の以下の実装は、インタフェースが test.MyFirstInterface である場合はクラス test.MyFirstImpl
を返し、それ以外の場合は null を返します。
Caché eXTreme での Java の使用法 31
eXTreme Event Persistence の使用法
package test
import com.intersys.xep.*;
public class MyFirstInterfaceResolver implements InterfaceResolver {
public MyFirstInterfaceResolver() {}
public Class<?> getImplementationClass(Class declaringClass,
String fieldName, Class<?> interfaceClass) {
if (interfaceClass == xepdemo.MyFirstInterface.class) {
return xepdemo.MyFirstImpl.class;
}
return null;
}
}
MyFirstInterfaceResolver のインスタンスが setInterfaceResolver() によって指定されている場合、importSchema()
の後続の呼び出しでは自動的にそのインスタンスが使用されて、test.MyFirstInterface として宣言されている
すべてのフィールドが解決されます。そのようなフィールドごとに、パラメータ declaringClass をそのフィールドを
含むクラスに、fieldName をそのフィールドの名前に、interfaceClass を test.MyFirstInterface に設定して、
getImplementationClass() メソッドが呼び出されます。このメソッドは、インタフェースを解決し、test.MyFirstImpl
か null のいずれかを返します。
32 Caché eXTreme での Java の使用法
3
eXTreme ダイナミック・オブジェクトの使用法
状況によっては、オブジェクトのプロパティに迅速にアクセスできることが、標準の Caché Java バインディングを使用す
ることの利便性より重要な場合があります。Caché eXTreme ダイナミック・オブジェクト (XDO) クラスは、永続データベー
ス・オブジェクトの挿入、更新、および削除を行うための非常に効率の良いメカニズムを実現します。標準のバインディン
グと XDO オブジェクト (パッケージ com.intersys.xdo) の最も大きな違いは以下のとおりです。
•
ダイナミック・オブジェクトによってアクセスされるクラスは、実行時に定義されます。コンパイル済みプロキシ・クラス
は必要ありません。
•
eXTreme 接続では、Caché と通信する際、TCP/IP ではなく、Caché カーネルやオブジェクト・サーバへのプロセス
内呼び出しを使用します。
•
ダイナミック・オブジェクトには、単なるサーバ上のデータへのポインタではなく実際のデータが含まれています。現
在サポートされているプロパティのデータ型は、int、Integer、long、Long、double、Double、BigDecimal、String、
Date、Time、および Timestamp です。
•
ダイナミック・オブジェクトはプロパティ値のみを含み、メソッド呼び出しにはアクセスできません。
インストールと構成に関して追加の要件があります (“インストールと構成” を参照)。
com.intersys.xdo API に含まれている主なクラスは以下の 2 つです。
•
DatabaseConnection — Cache データベースへの物理接続と論理接続を表します。このクラスは、DynamicObject
のインスタンスの作成、インデックスの更新、およびトランザクションの制御を行うメソッドを提供します。
•
DynamicObject — 実行時に指定された Caché クラス・エクステントの永続オブジェクトを表します。ダイナミック・オ
ブジェクトには、指定されたクラスのプロパティに対応するフィールドがあり、それらのフィールドの値を設定または変
更するメソッドを提供します。ダイナミック・オブジェクトは、クラスのエクステントに DatabaseConnection を介してア
クセスし、エクステント内のオブジェクトを作成、変更、または削除するメソッドを提供します。
この章では、これらのクラスの使用方法について説明します。以下の項目について説明します。
•
XDO 接続を開くおよび閉じる — DatabaseConnection のインスタンスを作成し、eXTreme 接続を確立する方法に
ついて説明します。
•
ダイナミック・オブジェクトの使用法 — DynamicObject のインスタンスを作成し、それを使用して、データベース内の
オブジェクトを作成、変更、または削除する方法について説明します。
•
トランザクション処理 — DatabaseConnection トランザクション・メソッドの使用法について説明します。
注釈
この章では、メソッドの概要については説明しますが、メソッドのオーバーロードおよびシグニチャについては
入手可能な情報すべてを記載してはいません。詳細は、メソッド名のリンクをクリックするか、“XDO クイック・リ
ファレンス” セクションのリストを参照してください。
Caché eXTreme での Java の使用法 33
eXTreme ダイナミック・オブジェクトの使用法
3.1 XDO 接続を開くおよび閉じる
XDO DatabaseConnection は、すべての eXTreme 接続クラスと同様に、基盤となる JDBC 接続に依存しています。他
のものとは異なり、JDBC 接続を自動的に作成することはありません。以下の 2 つの接続オブジェクトを作成する必要が
あります。
•
JDBC Connection オブジェクトは、基盤となる eXTreme 接続を提供します。接続 URL には、特別な予約ホスト名
SPCHOST を含める必要があります。
•
DatabaseConnection オブジェクトは、JDBC eXTreme 接続と DynamicObject のインスタンス間のインタフェースを
提供します (後の “ダイナミック・オブジェクトの使用法” で説明)。
注釈
1 つのプロセスで存在できる eXTreme JDBC Connection インスタンスは 1 つのみであり、そのプロセス内の
他のすべての Connection および DatabaseConnection 変数はそのインスタンスへの参照であると理解するこ
とが大切です。XDO API と他の eXTreme API を同じプロセスで使用する場合、それらは基礎となる同じ接続
を共用することになります (“グローバル API を他の eXTreme API と共に使用する方法” を参照してください)。
1 つのプロセスで一度に開くことができる eXTreme JDBC 接続は 1 つのみです。それは、標準 JDBC 接続インタフェー
スを使用して確立されますが ("JDBC での Caché の使用法" の “JDBC 接続の確立” を参照)、localhost または
IP アドレスの代わりに特別な予約ホスト名 SPCHOST を使用します。これにより、XDO トランザクションを、SQL クエリお
よび他のトランザクションと同じコンテキストの一部にすることができます。この接続は、それ以外は、ローカル IP アドレス
(localhost または 127.0.0.1)を使用する通常の JDBC 接続と機能的に同一であり、すべての同じ目的に使用でき
ます。
以下のメソッドを使用して、XDO 接続を作成または終了します。
•
DatabaseConnectionFactory.createJNIDatabaseConnection() — DatabaseConnection のインスタンスを返します。
•
DatabaseConnection.connect() — namespace、username、および password 引数を取り、指定されている Caché ネー
ムスペースのデータベースに接続します。この namespace は、JDBC 接続 URL で指定されているものと同一である
ことが必要です。
•
DatabaseConnection.disconnect() — Caché データベースから切断します。
以下のコードを実行すると、SPCHOST 識別子を使用する Samples ネームスペースへの JDBC 接続が作成されてから、
その eXTreme JDBC 接続を使用する DatabaseConnection オブジェクトが作成されます。
XDO 接続を開くおよび閉じる
java.sql.Connection jdbcConnection = null;
DatabaseConnection xdoConnection = null;
String namespc = "Samples";
String url = "jdbc:Cache://SPCHOST:1972/" + namespc;
String user = "_SYSTEM";
String password = "SYS";
try {
Class.forName ("com.intersys.jdbc.CacheDriver");
jdbcConnection = java.sql.DriverManager.getConnection(url,user,password);
xdoConnection = DatabaseConnectionFactory.createJNIDatabaseConnection();
xdoConnection.connect(namespc, user, password);
// insert XDO application code here
}
catch (XDOException e) { System.out.println(e.getMessage()); }
catch (Exception e) { System.out.println(e.getMessage()); }
finally {
try {
if (xdoConnection!=null) xdoConnection.disconnect();
if (jdbcConnection!=null) jdbcConnection.close();
}
34 Caché eXTreme での Java の使用法
ダイナミック・オブジェクトの使用法
catch (XDOException e) { System.out.println(e.getMessage()); }
catch (Exception e) { System.out.println(e.getMessage()); }
}
java.sql.getConnection() メソッドの呼び出しでは、URL に SPCHOST を指定することで初期 eXTreme JDBC 接
続が作成されます (SPC は “Single Process Communication (単一プロセス通信)” の略語です。URL 文字列
の構成方法の一般的な説明は、"JDBC での Caché の使用法" の “JDBC 接続 URL の定義” を参照してく
ださい)。
createJNIDatabaseConnection() の呼び出しによって、XDO DatabaseConnection オブジェクトが作成されま
す。
connect() メソッドの呼び出しは、JDBC Connection オブジェクトによって使用される URL の中のものと同じネー
ムスペースを指定する必要があります。connect() メソッドは、事前に確立された JDBC 接続 (ネームスペースと
ホスト名 SPCHOST で識別される) を使用するため、URL 全体を指定する必要はありません。
接続を開いた後、データベースにアクセスできます (ここに挿入可能なコードについては、“新規データベース・
オブジェクトの挿入” および “既存のデータベース・オブジェクトの変更” の例を参照してください)。
finally 節で、その disconnect() メソッドを呼び出すことで、DatabaseConnection オブジェクトが終了します。
これは、標準 JDBC localhost 接続と同様に独立して使用できる JDBC Connection オブジェクトに影響を
与えることはありません。この例では、その close() メソッドを呼び出すことで、JDBC 接続が終了します。
3.2 ダイナミック・オブジェクトの使用法
このセクションでは、DynamicObject クラスについて説明します。このクラスは、Java アプリケーションが Caché データ
ベースの永続オブジェクトにアクセスできるようにするメソッドを提供します。以下の項目について説明します。
•
ダイナミック・オブジェクトおよびデータベース・オブジェクトの作成 — DynamicObject の作成方法、およびそれが関
連付けられている永続データベース・オブジェクトと対話する方法について説明します。
•
新規データベース・オブジェクトの挿入 — 指定したクラスの空の DynamicObject を作成し、そのプロパティの値を
設定し、新規データベース・オブジェクトをそれらのプロパティと共に作成する方法について説明します。
•
既存のデータベース・オブジェクトの変更 — 既存のデータベース・オブジェクトのプロパティ値を含む DynamicObject
のインスタンスを作成し、DynamicObject プロパティの値を読み取り、データベース・オブジェクトを更新する方法に
ついて説明します。
•
プロパティ番号の使用 — 名前ではなく番号で DynamicObject プロパティを指定する方法について説明します。
3.2.1 ダイナミック・オブジェクトおよびデータベース・オブジェクトの作成
DynamicObject のインスタンスは、指定されているクラス・エクステントの永続データベース・オブジェクトにアクセスする
ために使用されます (エクステントの基本的な情報は、"Caché プログラミング入門ガイド" の “クラスとエクステント” を
参照してください)。ダイナミック・オブジェクトには、指定されたクラスのプロパティに対応するフィールドが含まれており、
それらのフィールドの読み取りまたは書き込みを実行するメソッドを提供します。それは、エクステント内のオブジェクトを
挿入、更新、および削除できます。
アタッチされたオブジェクトとアタッチ解除されたオブジェクト
DynamicObject のインスタンスは、作成されるときに必ず特定のクラス・エクステントと関連付けられます。また、そのエク
ステント内の特定のターゲット・オブジェクトと関連付けることもできます。このような場合、ダイナミック・オブジェクトはター
ゲットにアタッチされているといい、ターゲットを更新または削除できます。それ以外の場合、そのダイナミック・オブジェ
クトはアタッチ解除されており、そのエクステントに新規ターゲット・オブジェクトを作成してアタッチできます。
Caché eXTreme での Java の使用法 35
eXTreme ダイナミック・オブジェクトの使用法
DatabaseConnection インタフェースには、DynamicObject のアタッチ解除されているインスタンスを作成する createNew()
メソッドと、アタッチされているインスタンスを作成する openId() メソッドが用意されています。
createNew()
アタッチ解除されているダイナミック・オブジェクトを作成し、そのオブジェクトは、そのクラスのエク
ステントに新規ターゲット・オブジェクトを作成してアタッチできます。詳細および例については、“新
規データベース・オブジェクトの挿入” を参照してください。
openId()
指定されたクラス・エクステント内のターゲット・オブジェクトにアタッチされているダイナミック・オブ
ジェクトを作成します。ダイナミック・オブジェクトは、ターゲット・オブジェクトと同じプロパティ値を含
み、ターゲットを更新または削除できます。詳細および例については、“既存のデータベース・オ
ブジェクトの変更” を参照してください。
Caché データベース内で変更を行える DynamicObject メソッドは 4 つあります。それらの動作は、そのダイナミック・オ
ブジェクトがアタッチされているかアタッチ解除されているかに応じて異なります。
メソッド
アタッチされている場合
アタッチ解除されている場合
insert()
現在のターゲットからアタッチ解除し、新規ターゲッ
ト・オブジェクトを作成してアタッチします。
新規ターゲット・オブジェクトを作成してアタッチし
ます。
update()
ターゲット・オブジェクト内のデータを更新します。
例外をスローします。
save()
update() とまったく同じようにターゲットを更新しま
す。
insert() のように新規ターゲットを作成してアタッチ
します。
delete()
ターゲット・オブジェクトをデータベースから削除し
ます。
例外をスローします。
これらの 4 つのメソッドはすべて、オプションの deferIndices および timeout 引数を取ることができ、それらは、トランザク
ション処理を最適化するために使用されます。
注釈
一意のキー制約
insert() と save() のどちらも、新規データベース・オブジェクトを挿入できますが、一意のキー制約が原因で挿
入が失敗した場合、それらの動作は異なります。insert() が失敗した場合、例外がスローされます。save() が失
敗した場合、挿入の失敗の原因となったデータベース・オブジェクトがアタッチされて更新されます。
3.2.2 新規データベース・オブジェクトの挿入
このセクションでは、DatabaseConnection.createNew() メソッドを使用して DynamicObject の空のインスタンスを作成す
る方法、ダイナミック・オブジェクトのプロパティ値を設定する方法、およびそれらの値を含む新規データベース・オブジェ
クトを作成する方法について説明します。
•
DatabaseConnection.createNew() — className 文字列を取り、クラス className のものに対応する空のプロパティ・
フィールドを持つ DynamicObject を返します。新規ダイナミック・オブジェクトがアタッチ解除され、そのクラスのエク
ステントに新規データベース・オブジェクトを作成してアタッチできます。
以下の DynamicObject メソッドはインスタンスのプロパティ値を定義し、値をデータベース内のターゲット・オブジェクト
に保存し、必要に応じてそのインスタンスに対してガーベッジ・コレクションを実行します。
•
cleanup() — DynamicObject を破棄し、その基盤となっている JNI ネイティブ・リソースを解放し、メモリ・リークを回避
します。このメソッドは、DynamicObject のインスタンスが再使用されるか範囲外になる前に必ず呼び出す必要があ
ります。
•
set() — property および value 引数を取り、ダイナミック・オブジェクトの指定されたプロパティを指定された値に設定
します。value のデータ型は、int、Integer、long、Long、double、Double、BigDecimal、String、Date、Time、または
36 Caché eXTreme での Java の使用法
ダイナミック・オブジェクトの使用法
Timestamp である必要があります。このセクションの例では、property 引数を名前文字列として指定していますが、
番号として指定することもできます (“プロパティ番号の使用” を参照してください)。
•
insert() — ダイナミック・オブジェクトのプロパティ値のコピーを含む新規データベース・オブジェクトを作成してアタッ
チします。DynamicObject が既にアタッチされている場合、新規ターゲット・オブジェクトが作成されてアタッチされ
る前に、それがアタッチ解除されます。
•
update() — DynamicObject のデータをターゲット・オブジェクトにコピーするか、アタッチされていない場合は例外を
スローします。
以下のコードは、新規 CosTutorial.Person ダイナミック・オブジェクトを作成し、そのプロパティの値を設定し、それをデー
タベースに保存します。その後、1 つのプロパティの値を変更し、そのターゲット・オブジェクトを更新します。最後に、同
じダイナミック・オブジェクトを使用して、異なるデータベース・オブジェクトを作成してアタッチします。
注釈
この例では、エラー・チェックを行いません。CosTutorial.Person エクステントが空であり、このコード例が
TRY/CATCH ブロック内で実行されていると仮定しています (“XDO 接続を開くおよび閉じる” の例を参照して
ください)。管理ポータルで CosTutorial.Person エクステントを表示する方法および Caché ターミナルを使用し
てエクステントを削除またはエクステントに入力する方法の手順は、“サンプル・データ・クラス” を参照してくだ
さい。
新規データベース・オブジェクトの挿入
// xdoConnection is a previously created DatabaseConnection object
DynamicObject objPerson = xdoConnection.createNew("CosTutorial.Person");
objPerson.set("phone", "123-456-1111");
// required unique index field
objPerson.set("name", "Jones, Oscar");
objPerson.set("dob", java.sql.Date.valueOf("1929-06-22"));
objPerson.insert();
// create and attach a new database object
// We entered the wrong dob! Update the target object with the correct dob
objPerson.set("dob", java.sql.Date.valueOf("1959-08-31"));
objPerson.update();
// change the dob property in the database object
// Now give "Jones, Oscar" a second phone number
objPerson.set("phone", "123-456-9999");
// required unique index field
objPerson.insert();
// create a second new database object
objPerson.cleanup();
// destroy the DynamicObject when done.
createNew() メソッドは、クラス CosTutorial.Person のデータベース・オブジェクトを表す DynamicObject objPerson
を作成します。objPerson のフィールドはすべて null です。
set() の最初の 3 つの呼び出しによって、objPerson の name、phone、および dob プロパティに値が割り当てら
れます。標準 java.sql.Date valueOf() メソッドが使用されて、日付文字列が Date に変換されます。
insert() メソッドは、CosTutorial.Person エクステントに新規永続オブジェクトを作成し、それに objPerson で定
義されているプロパティ値が入力されます。これで、ダイナミック・オブジェクトは、新しく作成されたターゲット・
オブジェクトにアタッチされます。
set() の次の呼び出しによって、objPerson の dob プロパティの値が変更され、update() の呼び出しによって新
しい値がターゲット・オブジェクトに保存されます。
set() の最後の呼び出しによって、objPerson の phone プロパティの値が変更されます。insert() の呼び出しに
よって、現在のターゲット・オブジェクトがアタッチ解除され、新しいオブジェクトが作成されてアタッチされます。
その新規ターゲット・オブジェクトには、新しい phone 値が含まれていますが、name と dob には以前と同じ値
が含まれています (objPerson の name または dob の値のみが変更されていた場合、CosTutorial.Person エク
ステントには、phone プロパティの一意のインデックスが含まれているため、insert() は例外をスローします)。
objPerson が不要になったときに、cleanup() メソッドが呼び出されて、それを破棄し、その基盤となっている JNI
ネイティブ・リソースを解放します (これはメモリ・リークを回避するために実行する必要があります)。
Caché eXTreme での Java の使用法 37
eXTreme ダイナミック・オブジェクトの使用法
重要
常に cleanup() を呼び出してメモリ・リークを回避
DynamicObject のインスタンスが範囲外になるか再使用される前に、これらのすべてのインスタンスで
cleanup() を呼び出すことが重要です。ダイナミック・オブジェクトが作成されるときに、基盤となる JNI ネ
イティブ・コードによってリソースが割り当てられますが、それは Java ガーベッジ・コレクションによって管
理されません。cleanup() を呼び出してこれらのリソースを解放しないと、メモリ・リークが発生します。
3.2.3 既存のデータベース・オブジェクトの変更
このセクションでは、DatabaseConnection.openId() メソッドを使用して、指定されているターゲット・データベース・オブ
ジェクトと同じプロパティ値を含む DynamicObject のインスタンスを作成する方法、ダイナミック・オブジェクトを使用して
ターゲットを更新または削除する方法について説明します。
•
DatabaseConnection.openId() — エクステント className 内のターゲット・オブジェクトを識別する className および
Id 引数を取り、ターゲットと同じプロパティ値を含む DynamicObject を返します。返されたオブジェクトは、ターゲッ
ト・オブジェクトにアタッチされ、それを更新または削除できます。
以下の DynamicObject メソッドは、openId() の呼び出しが成功したかどうかをテストし、ダイナミック・オブジェクトの Id お
よびプロパティの値を返し、ターゲット・オブジェクトを削除します。
•
isNull() — openId() によって返されたオブジェクト参照が null かどうかをテストします。null と判断されるのは、指定
した Id 値を持つオブジェクトが見つからない場合です。
•
getId() — アタッチされている場合はターゲット・オブジェクトの Id 値を返し、アタッチ解除されている場合は空の文
字列 ("") を返します。
•
delete() — ターゲット・オブジェクトをデータベースから削除します。ターゲットがアタッチされていない場合は、例外
をスローします。
•
プロパティ・ゲッター・メソッド — property 引数を取り、指定されているプロパティの値を返します。個々のメソッド名
は、返される変数のデータ型を示しています。以下のデータ型のプロパティ・ゲッター・メソッドがあります。
int getInt()
double getDouble()
Date getDate()
Integer getIntegerWrapper()
Double getDoubleWrapper()
Time getTime()
long getLong()
BigDecimal getBigDecimal()
Timestamp getTimestamp()
Long getLongWrapper()
String getString()
このセクションの例では、property 引数を名前文字列として指定していますが、番号として指定することもできます
(“プロパティ番号の使用” を参照してください)。
以下のコードは、CosTutorial.Person エクステント内の Id 値が 1 および 2 のターゲット・オブジェクトを開き、それらの
プロパティ値を出力し、それらをデータベースから削除します。
注釈
この例では、CosTutorial.Person エクステントに、前のセクション (“新規データベース・オブジェクトの挿入”
を参照) の例で作成した 2 つのオブジェクトが含まれていることと、それらのオブジェクトが Id 値 1 および 2 を
持っていることが前提となっています。この例では、Id 値はハード・コード化されたリストで提供されています。
結果セットから Id 値を読み取る実用的な例については “トランザクション処理” を参照してください。このコー
ド例は TRY/CATCH ブロック内にあると仮定しています (“XDO 接続を開くおよび閉じる” の例を参照してくだ
さい)。
38 Caché eXTreme での Java の使用法
ダイナミック・オブジェクトの使用法
既存のデータベース・オブジェクトの変更
DynamicObject objPerson = null;
String[] idList = {"1","2"};
// create a list of Ids to open
for (String newId:idList) {
objPerson = xdoConnection.openId("CosTutorial.Person", newId);
if (objPerson.isNull()) {
System.out.println("Invalid Id:" + newId);
} else {
System.out.println( "Person " + objPerson.getId() + ":"
+ ", phone: " + objPerson.getString("phone")
+ " name: " + objPerson.getString("name")
+ " dob: " + objPerson.getDate("dob") );
objPerson.delete();
}
if (objPerson != null) objPerson.cleanup();
}
openId() メソッドは、Id 値 newId を持つ既存の CosTutorial.Person データベース・オブジェクト内のデータのコ
ピーを含む DynamicObject を返します。
isNull() メソッドは、指定されている Id 値を持つオブジェクトが見つかったことを確認するテストを実行します。
isNull() が false を返す場合、DynamicObject のこのインスタンスは使用できず、エラー・メッセージが出力さ
れます。
getId() メソッドが使用されて、取得したデータベース・オブジェクトの Id が出力され、プロパティ・ゲッター・メソッ
ド getString() および getDate() が使用されて、その phone、name、および dob プロパティが出力されます。
そのプロパティが出力された後、delete() メソッドが呼び出されて、CosTutorial.Person エクステントから現在の
ターゲットが削除されます。
ループの繰り返しそれぞれの後に、cleanup() メソッドを呼び出し、DynamicObject を破棄して、その基盤となっ
ている JNI ネイティブ・リソースを解放する必要があります。古いインスタンスが破棄される前に新規インスタンス
が objPerson 変数に割り当てられた場合、または最後のインスタンスが破棄される前に変数が範囲外になった
場合、メモリ・リークが発生します。
3.2.4 プロパティ番号の使用
set() メソッドおよびプロパティ・ゲッター・メソッド (“既存のデータベース・オブジェクトの変更” で説明) は、property 引
数として名前文字列と数値のいずれでも受け入れることができます。このセクションの前の例では、名前文字列を使用し
ましたが、同じプロパティを繰り返し参照する場合は、プロパティ番号を指定するほうが効率的です。DynamicObject の
以下のメソッドは、指定されているプロパティ名のプロパティ番号を返します。
•
getPropertyNumber() — propertyName 文字列を引数として受け入れ、その指定された名前に対応するプロパティ
番号 (システムによって割り当てられる任意の識別番号) を返します。
以下のコードは、新規 DynamicObject を作成し、一連のプロパティ番号変数を定義し、それらの変数をゲッターとセッ
ターの両方のメソッドで使用します (わかりやすくするために、この例では 1 つのオブジェクトのみを定義します。複数の
オブジェクトを処理する例については、“トランザクション処理” を参照してください)。
プロパティ番号の使用
DynamicObject objPerson = null;
int propName = 0;
int propPhone = 0;
int propDOB = 0;
try {
// Initialize dynamic object and property number variables
objPerson = xdoConnection.createNew("CosTutorial.Person");
propName = objPerson.getPropertyNumber("Name");
propPhone = objPerson.getPropertyNumber("Phone");
propDOB = objPerson.getPropertyNumber("DOB");
// Set the object properties and print them
objPerson.set(propName,"Fudd, Elmer");
objPerson.set(propPhone,"123-456-7890");
objPerson.set(propDOB, java.sql.Date.valueOf("1940-01-01"));
Caché eXTreme での Java の使用法 39
eXTreme ダイナミック・オブジェクトの使用法
System.out.println("Current name: " + objPerson.getString(propName)
+ ", phone: " + objPerson.getString(propPhone)
+ ", DOB: " + objPerson.getDate(propDOB) );
}
catch (XDOException e) {System.out.println( "XDO error: \n" + e.getMessage()); }
finally { objPerson.cleanup(); }
新規 DynamicObject が作成され、getPropertyNumber() の呼び出しによって、クラスの 3 つのプロパティそれ
ぞれのプロパティ番号変数が定義されます。プロセス内で変数を定義する必要があるのは 1 回のみであり、そ
れらの変数は CosTutorial.Person にアクセスする DynamicObject のどのインスタンスでも使用できます。
set() の呼び出しでは、プロパティ番号を使用して各プロパティの値が設定されます。
print 文では、プロパティ・ゲッター・メソッド getString() および getDate() でプロパティ番号が使用されて、新し
く定義された phone、name、および dob プロパティが出力されます。
3.3 トランザクション処理
このセクションでは、高速なトランザクション処理を実行および最適化する際に最も便利なメソッドについて説明します。
以下の項目について説明します。
•
トランザクションの使用 — トランザクションの開始、コミット、およびロールバック方法について説明します。
3.3.1 トランザクションの使用法
DatabaseConnection インタフェースには、トランザクション処理を制御するいくつかのメソッドが用意されています。この
セクションでは、以下のメソッドの使用法について説明します。
•
startTransaction() — トランザクションを開始します (このトランザクションは別のトランザクション内に入れ子になって
いる場合あり)。
•
commit() — 1 レベルのトランザクションをコミットします。
•
rollback() — トランザクションのすべてのレベルをロールバックします。
•
transactionLevel() — 現在のトランザクション・レベル (トランザクション内でない場合は 0) を返します。
以下の例は、データベースへの新規 CosTutorial.Person オブジェクトの挿入を試みる一連のトランザクションを処理しま
す。各トランザクションで、ダイナミック・オブジェクトは、Name および DOB の値を 1 つのソースから取得し、Phone の値
を 2 番目のソースから取得し、これらの値を含む新規データベース・オブジェクトの挿入を試みます。この例は、一意の
キーの例外から回復するように設計されています。この例外は、トランザクションによって値 "123-456-2222" を持つ
Phone プロパティを含むオブジェクトの挿入が試みられたときにスローされます。
注釈
クエリが既に java.sql.ResultSet myResults (“サンプル・データ・クラス” のクエリの例を参照) を返しており、プ
ロパティ番号変数 propName、propDOB、および propPhone が既に定義されている (前の “プロパティ番号の
使用” で例示) と仮定します。
トランザクションの使用法 : startTransaction()、commit()、rollback() および transactionLevel()
// Create list of phone numbers to be used during transaction processing
int phoneCount = 0;
String[] phoneList = {"123-456-1111","123-456-2222","123-456-3333",
"123-456-4444","123-456-5555"};
// Add an object that will force a unique key exception during processing
try {
objPerson.set(propPhone,"123-456-2222");
objPerson.insert();
40 Caché eXTreme での Java の使用法
トランザクション処理
}
catch (XDOException e) { System.out.println("Error initializing: \n" + e.getMessage()); }
// Start transaction processing
try {
while (myResults.next() && phoneCount<phoneList.length) {
boolean phoneAdded = false;
try {
objPerson.set(propName,myResults.getString("Name"));
objPerson.set(propDOB,myResults.getDate("DOB"));
do {
// Assign the next phone number and try to insert.
objPerson.set(propPhone,phoneList[phoneCount++]);
try {
xdoConnection.startTransaction();
objPerson.insert();
if (xdoConnection.transactionLevel()>0) {
xdoConnection.commit();
System.out.println("Committed " + objPerson.getString(propName)
+ ", phone: " + objPerson.getString(propPhone)
+ ", DOB: " + objPerson.getDate(propDOB) );
phoneAdded = true;
}
}
catch (XDOException e) {
// Rollback if a database object already uses this phone number.
xdoConnection.rollback();
System.out.println("\nError assigning to " + objPerson.getString(propName)
+ " - phone " + objPerson.getString(propPhone) + " already in use.\n
" );
}
} while (!phoneAdded && phoneCount<phoneList.length);
}
catch (XDOException e) {System.out.println("XDO error: \n" + e.getMessage());}
}
}
catch (java.sql.SQLException e) {System.out.println("SQL error: " + e.getMessage());}
catch (Exception e) {System.out.println("Unexpected error: " + e.getMessage());}
finally { objPerson.cleanup(); }
トランザクション処理が開始される前に、Phone 値 "123-456-2222" を持つオブジェクトがデータベースに挿
入されます。phoneList 配列の 2 番目の項目に同じ値が含まれているため、トランザクションによってその挿入
が試みられると一意のキーの例外がスローされます。
while ループは、phoneList または myResults のいずれかの終わりに到達するまでトランザクションを処理しま
す。ResultSet myResults の行ごとに、Name および DOB の値が取得され、set() が呼び出されて、それらがダ
イナミック・オブジェクト objPerson 内の対応するフィールドに割り当てられます。
後に続く処理では、phoneList から電話番号を取得し、それを objPerson の Phone プロパティに割り当て、トラ
ンザクションを開始し、データベース内での新規オブジェクトの作成を試みます。このトランザクションが失敗し
た場合、トランザクションが正常に処理されるか、phoneList にそれ以上項目がなくなるまで Phone の新しい値
で処理が繰り返されます。
•
電話番号が、phoneList から取得され、objPerson の Phone プロパティに割り当てられます。
•
startTransaction() が呼び出されます。
•
insert() が呼び出され、objPerson がデータベースに保存されます。例外が発生すると、制御が catch ブ
ロックに渡され、そこで rollback() が呼び出され、エラー・メッセージが出力されます。
•
transactionLevel() を呼び出すと、トランザクションがロールバックされた場合に 0 が返されます。これが実
行された場合、新規トランザクションが同じ Name および DOB プロパティと、異なる Phone プロパティを使
用して試行されます。
•
挿入が正常に実行された場合、commit() が呼び出され、現在のプロパティが出力され、myResults の次の
行 (存在する場合) で処理が続行されます。
この例のコードは以下のような出力を生成します。
Caché eXTreme での Java の使用法 41
eXTreme ダイナミック・オブジェクトの使用法
Committed Cooke,Edward A, phone: 123-456-1111, DOB: 1989-08-13
Error assigning to Jafari,Elizabeth M. - phone 123-456-2222 already in use.
Committed Jafari,Elizabeth M., phone: 123-456-3333, DOB: 1961-07-03
Committed Levin,Alvin M., phone: 123-456-4444, DOB: 1974-11-19
Committed Zevon,Maria V., phone: 123-456-5555, DOB: 1975-09-10
42 Caché eXTreme での Java の使用法
4
グローバル API の使用法
Caché 多次元ストレージは、さまざまなデータ構造の実装に使用できる高速かつ柔軟なストレージ・モデルを提供しま
す。Caché は、多次元ストレージを使用して、データをオブジェクトまたはSQLテーブルとして構造化しますが、他の多く
の構造とすることも同様に可能です。グローバル API により、グローバル配列 (多次元ストレージ・モデルの基盤) への
直接アクセスが可能になり、独自のデータ構造の実装が可能になります。
グローバル API は、非常に速いストレージ用に、またいくつかの基本的なデータ型 (int、long、double、byte[]、String、
および ValueList (シリアル化リスト)) の取得用に最適化されています。これは、Caché オブジェクトに格納されているデー
タへの高速アクセスを実現する eXTreme ダイナミック・オブジェクト (XDO) API と共に同じアプリケーションで使用する
こともできます。
グローバル API は、標準の Java バインディングのように TCP/IP を介して通信するのではなく、Caché インスタンスと同
じプロセスで実行されます。Caché サーバと Java アプリケーションは同じマシン上にある必要がありますが、そのアプリ
ケーションは、必要に応じてリモート・マシン上のデータにアクセスできます。
多次元ストレージ・モデルの概要については、この章で後述する “グローバル配列の概要” を参照してください。グロー
バル配列の構造および ObjectScript アプリケーションでの使用法の詳細は、Caché グローバルの使用法 を参照してく
ださい。この章では、以下の項目について説明します。
•
グローバル API の概要 — グローバル配列の概念および用語について紹介し、グローバル API を使用するコード
の簡単な例を示します。
•
接続の作成 — eXTreme 接続を開き、テストし、閉じる Connection クラスのメソッドについて説明します。
•
グローバル配列の構築 — 多次元グローバル配列内のノードを作成、変更、または削除する NodeReference クラス
のメソッドについて説明します。
•
グローバル配列にわたる反復 — グローバル配列のノードへの高速アクセスを可能にする反復メソッドについて説明
します。
•
グローバル配列のデータの取得 — グローバル配列から値を取得するメソッドについて説明します。
•
シリアル化された値リストの使用法 — 単一ノードにサポートされているすべてのデータ型の複数の値を格納するた
めの実用的な方法を提供し、シリアル化されたリストを作成してこれにアクセスするための ValueList クラスのメソッド
の使用法について説明します。
•
複数のグローバル配列へのアクセス — すべての利用可能なネームスペースのすべてのグローバル配列をリストし、
これにアクセスするための GlobalsDirectory クラスおよび関連するメソッドの使用法について説明します。
•
トランザクションとロック — トランザクションでのグローバル API の使用法について説明します。
•
Caché メソッドの呼び出し — グローバル API アプリケーションから Caché ObjectScript メソッド、関数、およびプロ
シージャを呼び出すことができる Connection メソッドについて説明します。
•
グローバル API の要件と規約 — 名前付け規約および eXTreme API 間のやり取りについて説明します。
Caché eXTreme での Java の使用法 43
グローバル API の使用法
注釈
グローバルの用語
Caché ドキュメントの他の部分では、グローバル配列は、単純にグローバルと呼ばれる場合が多いです。このド
キュメントでは、グローバル API の名前との混同を回避するために、長い用語グローバル配列を使用します。
4.1 グローバル API の概要
このセクションでは、グローバル API の背後にある基本概念について説明します。以下の項目について説明します。
•
グローバル配列の概要 — グローバル配列の概念および用語について説明します。
•
ノードを作成およびフェッチするための簡単なアプリケーション — グローバル API の使用法の簡単な例を示します。
4.1.1 グローバル配列の概要
Caché グローバル配列は、すべてのスパース配列のように、ツリー構造です (連続的に番号付けされたリストではありま
せん)。スパース配列の背後にある基本概念は、Java パッケージの名前付け規約に例えて示すことができます。パッケー
ジ内の各クラスは、一連の識別子から構成されるネームスペースによって一意に識別されます。例えば、2 つのクラス
main.foo.SubFoo および main.bar.UnderBar のみを含むパッケージについて考えてみます。これらのネームスペースを
構成する 5 つの識別子は、スパース配列の要素として以下のように表示できます。
main -->|--> foo --> SubFoo
|--> bar --> UnderBar
他の指定可能なネームスペース (main、main.bar など) を使用するクラスを作成できますが、これらのクラスが存在しない
場合、リソースは使用されません。
Java クラスのように、Caché グローバル配列の要素は、任意の数の識別子によって構成されるネームスペースによって
一意に識別されます。グローバル配列構造のすべてのネームスペースは、ノードと呼ばれます。ノードは、データを含む
か、子ノードを持つか、またはこれらの両方を持つ必要があります。子ノードを持っているがデータを含まないノードは、
値なしノードと呼ばれます。
ルート識別子 (Java パッケージの main など) は、グローバル名と呼ばれます。ネームスペース内の他のすべての識別
子は、添え字と呼ばれます。ノードの完全なネームスペース (グローバル名プラス添え字) は、ノード・アドレスです。
Caché の表現では、ノード・アドレスは、曲折アクセント記号 (^) の後にグローバル名を続け、さらにコンマで区切られた
添え字リストを括弧で囲んで続けることによって記号で表されます。例えば、Java パッケージの例と同じ識別子を使用す
るグローバル配列の場合、配列のノードは以下のように表されます。
(valueless
(valueless
(node with
(valueless
(node with
root node)
node)
value)
node)
value)
^main
^main("foo")
^main("foo","SubFoo") = <value>
^main("bar")
^main("bar","UnderBar") = <value>
配列のルート・ノードは、単純に ^main です。添え字リストはありません。データを含む 2 つのノードは、
^main("foo","SubFoo") と ^main("bar","UnderBar") です。ノード ^main、^main("foo")、および ^main("bar") は、すべて値
なしです。
特定のノードのすべての下位ノードは、そのノードのサブノードと呼ばれます。例えば、^main("foo","SubFoo") は
^main("foo") のサブノードであり、4 つすべての添え字の付いたノードは ^main のサブノードです。
用語ノード・レベルは、添え字リスト内の添え字数を表します。例えば、^main("bar","UnderBar") は、レベル 2 ノードで
す。このアドレスには、レベル 1 添え字 ("bar")、およびレベル 2 添え字 ("UnderBar") があります。
44 Caché eXTreme での Java の使用法
グローバル API の概要
この例では、すべての添え字が文字列ですが、数値も使用できます。グローバル API では、Java データ型 String、int、
long、または double を使用して、添え字を指定できます。これらはすべて、同じ添え字リストで使用できます。例えば、
^myNode(1,"two",3.14) は、有効なノード・アドレスです。
名前付けのルールのリストについては、“グローバル配列の名前付け規約” のセクションを参照してください。グローバ
ル配列の構造の詳細は、"Caché グローバルの使用法" の “グローバルの論理構造” および "Caché ObjectScript
チュートリアル" の “配列” を参照してください。
4.1.2 ノードを作成およびフェッチするための簡単なアプリケーション
このセクションでは、以下の非常に簡単な 2 つのアプリケーション (グローバル API を使用してグローバル配列のノード
を作成するアプリケーションと、そのノードにアクセスするアプリケーション) について説明します。
•
CreateNodes プログラム — Caché データベースへの eXTreme 接続を開き、2 つのノードを持つ永続グローバル配
列を作成し、接続を閉じて終了します。
•
FetchNodes プログラム — 新しい eXTreme 接続を開き、データベースにアクセスして CreateNodes によって作成
された両方のノードの値をフェッチします。その後、そのグローバル配列を削除し、接続を閉じて終了します。
これらのアプリケーションは、システムを排他的に使用し、2 つの連続したプロセスで実行されることが前提となっていま
す。
4.1.2.1 CreateNodes プログラム
CreateNodes では、新しいグローバル接続オブジェクトが作成され、Caché サーバ上で User ネームスペースに接続さ
れます。2 つのノードを持つ新しいグローバル配列が Caché データベースに追加され、接続が閉じられ、プログラムが
終了します。
CreateNodes プログラム : 接続を開きノードを作成
import com.intersys.globals.*;
public class CreateNodes {
public static void main(String[] args) {
Connection myConn = ConnectionContext.getConnection();
try {
myConn.connect("User", "_SYSTEM", "SYS");
NodeReference nodeRef = myConn.createNodeReference("myGlobal");
// Create a new global array with two nodes
nodeRef.set("Hello world");
// create root node ^myGlobal
nodeRef.appendSubscript("sub1");
// point to node address ^myGlobal("sub1")
nodeRef.set("This is a subscripted node"); // create subnode ^myGlobal("sub1")
nodeRef.close();
myConn.close();
}
catch (GlobalsException e) { System.out.println(e.getMessage()); }
} // end Main()
} // end class CreateNodes
この例では、グローバル API メソッドは以下のアクションを実行します。
•
ConnectionContext.getConnection() は、このプロセスのために myConn という名前の新しい Connection
オブジェクトを作成します。
•
Connection.connect() は、User ネームスペースと関連付けられたデータベースにアクセスする接続を開き
ます。
•
Connection.createNodeReference() は、NodeReference オブジェクト nodeRef を作成します。これには、
^myGlobal という名前のグローバル配列のルート・ノードへの参照が含まれます。
•
NodeReference.set() は、データベースに新しい永続ノードを作成します。グローバル配列 ^myGlobal は、
nodeRef オブジェクトに指定されているアドレスにある値が set() によって割り当てられるまで、データベー
ス内に存在しません。
Caché eXTreme での Java の使用法 45
グローバル API の使用法
•
NodeReference.appendSubscript() は、ノード参照に添え字を追加します。そのノード参照は、
^myGlobal("sub1") を指すようになり、set() が再び呼び出されて、そのアドレスに永続ノードを作成します。
•
NodeReference.close() を呼び出す必要があります。これは、Java ガーベッジ・コレクションでは、JNI ネイ
ティブ・コードによって nodeRef に割り当てられたメモリを解放できないためです。
•
Connection.close() は、接続を終了し、JNI ネイティブ・コード・リソースを解放します。新しいグローバル配
列 ^myGlobal の両方のノードは、接続が閉じた後 Caché データベースに残ります。
重要
常に close() を呼び出してメモリ・リークを回避
Connection および NodeReference のインスタンスが範囲外になるか再使用される前に、これらのイン
スタンスで必ず close() を呼び出すことが重要です。それらを閉じないと、深刻なメモリ・リークが発生す
ることがあります。それは、Java ガーベッジ・コレクションでは、基盤となる JNI ネイティブ・コードによって
割り当てられたリソースを解放できないためです。
これらのメソッドについては、すべてこの章で後で詳しく説明します。eXTreme 接続を開き、テストし、閉じることに関する
詳細は、“接続の作成” を参照してください。ノードの作成、またはその値の変更のための NodeReference オブジェク
トの使用法の詳細は、“グローバル配列の構築” を参照してください。ノード参照の添え字の指定の詳細は、“ターゲッ
ト・アドレスの設定” を参照してください。
4.1.2.2 FetchNodes プログラム
この例では、CreateNodes プロセスの終了後、直ちに FetchNodes が実行されることを前提としています。FetchNodes
は、CreateNodes と同じネームスペースにアクセスする新しい eXTreme 接続を作成します。新しいノード参照オブジェ
クトを使用して、データベースからルート・ノード ^myGlobal およびサブノード ^myGlobal("sub1") の値をフェッチし、グ
ローバル配列がプロセス間で存続されていることを示します。グローバル配列は削除され、接続が閉じられ、プログラム
が終了します。
FetchNodes プログラム : 既存のノードの値をフェッチ
import com.intersys.globals.*;
class FetchNodes {
public static void main(String[] args) {
Connection myConn = ConnectionContext.getConnection();
try {
myConn.connect("User", "_SYSTEM", "SYS");
NodeReference nodeRef = myConn.createNodeReference("myGlobal");
// Read both existing nodes
System.out.println("Value of ^myGlobal is " + nodeRef.getString());
nodeRef.appendSubscript("sub1");
// point to subnode
System.out.println("Value of ^myGlobal(\"sub1\") is " + nodeRef.getString());
nodeRef.setSubscriptCount(0);
// point to root node
nodeRef.kill();
// delete entire array
nodeRef.close();
myConn.close();
}
catch (GlobalsException e) { System.out.println(e.getMessage()); }
} // end Main()
} // end class FetchNodes
この例では、グローバル API メソッドは以下のアクションを実行します。
•
getConnection()、connect()、および createNodeReference() メソッドが、CreateNodes で呼び出されたとき
と同じように、再度呼び出されます。このプロセスのために新しい eXTreme 接続オブジェクトが作成され、
User ネームスペースへの新しい接続が確立されます。新しいノード参照オブジェクト nodeRef が作成され、
最初は ^myGlobal (CreateNodes によって前に作成されたグローバル配列) のルート・ノードを指します。
•
NodeReference.getString() は、データベースからルート・ノード ^myGlobal の値をフェッチし、それを Java
String として返します。
46 Caché eXTreme での Java の使用法
接続の作成
•
CreateNodes の場合と同様に、appendSubscript() メソッドが使用されて、添え字 "sub1" が参照されるノー
ド・アドレスに追加されます。NodeReference オブジェクトは、サブノード ^myGlobal("sub1") を指すように
なり、getString() が再度呼び出されて、そのサブノードの値を返します。
•
NodeReference.setSubscriptCount() は、添え字リストの添え字数を減らすことで、参照されるアドレスを変
更するメソッドです。この場合、添え字数はゼロであることを指定します。参照されるアドレスからすべての
添え字が削除されているため、NodeReference オブジェクトはもう一度ルート・ノード ^myGlobal を指しま
す。
•
NodeReference.kill() は、参照されるノードおよびそのサブノードすべてをデータベースから削除するメソッ
ドです。この場合、ルート・ノード ^myGlobal とサブノード ^myGlobal("sub1") の両方とも削除され、空のグ
ローバル配列もデータベースから削除されます。
•
myConn と nodeRef の両方の close() メソッドが再び呼び出され、メモリ・リークを回避します。これは、JNI
ネイティブ・コードによってそれらに割り当てられたメモリは、Java ガーベッジ・コレクションでは解放できな
いためです。
これらのメソッドについては、すべてこの章で後で詳しく説明します。さまざまなデータ型のノード値をフェッチする
getString() およびその他のメソッドの詳細は、“ノード値のフェッチ” を参照してください。ノード参照の添え字の変更の
詳細は、“ターゲット・アドレスの設定” を参照してください。永続ノードの削除の詳細は、“ノードの作成と削除” を参
照してください。
4.2 接続の作成
このセクションでは、基礎となる eXTreme Caché データベース接続への参照をカプセル化する Connection クラスにつ
いて説明します。
注釈
1 つのプロセスで存在できる eXTreme Connection インスタンスは 1 つのみであり、すべての Connection 変
数はそのインスタンスへの参照であると理解することが大切です。グローバル API と他の eXTreme API を同じ
プロセスで使用する場合、それらは基礎となる同じ接続を共用することになります (“グローバル API を他の
eXTreme API と共に使用する方法” を参照してください)。
現在のプロセスに接続が存在しない場合、ConnectionContext.getConnection() メソッドが使用されて新しい Connection
オブジェクトが返されます。接続が既に存在している場合は、そのメソッドによって既存の Connection オブジェクトへの
参照が返されます。
Connection の以下のメソッドは、接続、接続のテスト、および接続の破棄に使用されます。
•
connect() — 基礎となる接続オブジェクトを使用して、指定されたネームスペースへの接続を確立します。オプション
で、ユーザ名とパスワードを指定できます。アクセスされるネームスペースを読み取る、または変更するために、他の
メソッドを使用できます (この章で後述する “ネームスペースへのアクセス” を参照してください)。
•
IsConnected() — 接続オブジェクトにデータベースへの接続がある場合、true を返します。
•
close() — 基礎となる eXTreme 接続を閉じ、基盤となる JNI ネイティブ・コードによって割り当てられた関連リソース
を解放します。
以下の例は、2 つの Connection 変数を作成し、これら両方が同じ基礎となる接続を参照することを示します。
Caché eXTreme での Java の使用法 47
グローバル API の使用法
接続の作成
Connection myConn1 = ConnectionContext.getConnection();
Connection myConn2 = ConnectionContext.getConnection();
myConn1.connect("User", "_SYSTEM", "SYS");
System.out.println("myConn1 is " + myConn1.isConnected()
+ "; myConn2 is " + myConn2.isConnected());
// Prints: myConn1 is true; myConn2 is true
myConn2.close();
System.out.println("myConn1 is " + myConn1.isConnected()
+ "; myConn2 is " + myConn2.isConnected());
// Prints: myConn1 is false; myConn2 is false
myConn1.close(); // release native resources
この例では、このプロセスのどこにも既に存在している他の接続がないことが前提となっています。
Connection オブジェクト myConn1 が、ConnectionContext.getConnection() の呼び出しによって作成されま
す。Connection 変数 myConn2 が同じ方法で定義されますが、接続オブジェクトが既に存在しているため、
myConn2 は myConn1 と同じオブジェクトを参照するようになります。getConnection() の 2 回目の呼び出しは、
機能的には Connection myConn2 = myConn1; と同等です。
myConn1 変数が使用されて connect() が呼び出され、データベース・ネームスペース User への接続が確立さ
れます。各接続変数が、isConnected() の呼び出しを行います。どちらの呼び出しも true を返し、どちらかの
みが connect() を呼び出したとしても、両方の変数がデータベースにアクセスできるようになります。
myConn2 変数が close() を呼び出します。これにより、基礎となる接続が閉じられ、関連リソースが解放されま
す。メモリ・リークを回避するためには、これを実行する必要があります。それは、基盤となる JNI ネイティブ・コー
ドによって割り当てられたメモリは、Java ガーベッジ・コレクションでは解放できないためです。
両方の変数で isConnected() を再度呼び出し、close() が呼び出されたのが 1 回のみの場合でも、それらが両
方とも切断されたことを示します。
接続が閉じられていても、close() を myConn1 でも呼び出し、それが保持している可能性がある残りのネイティ
ブ・コード・リソースを解放します。
4.3 グローバル配列の構築
このセクションでは、グローバル配列でのアドレスの指定および、そのアドレスにあるノード値の追加、変更、または削除
を可能にする NodeReference クラスのメソッドについて説明します。以下の項目について説明します。
•
NodeReference でのノードの作成 — NodeReference のインスタンスを使用してグローバル配列を作成する方法に
ついて説明します。
•
ターゲット・アドレスの設定 — 添え字リストを制御することでノード参照がアクセスするアドレスを指定する方法につ
いて説明します。
•
ターゲットのサブノードのアドレス指定 — 添え字リストを変更することなくターゲットのサブノードにアクセスする方法
について説明します。
•
ノードの作成と削除 — データベースの内容を実際に変更する 4 つのメソッドについて詳しく説明します。
注釈
このセクションでは、主に、さまざまなグローバル配列構造でのデータの格納について説明します。データ取得
のメソッドと方法の詳細は、“グローバル配列のデータの取得” を参照してください。
48 Caché eXTreme での Java の使用法
グローバル配列の構築
4.3.1 NodeReference でのノードの作成
NodeReference クラスは、グローバル配列のノードへの参照をカプセル化します。このクラスは、ノードのアドレスを指定
するメソッドや、データベース内の対応する永続ノードを追加、変更、または削除するメソッドを提供します。Connection
の次のメソッドは、NodeReference のインスタンスを作成します。
•
Connection.createNodeReference() — NodeReference の新しいインスタンスを返し、オプションでグローバル名を指
定する name 引数を取ります。インスタンスが作成されるとき、ターゲット・アドレスは name によって指定されている
グローバル配列のルート・ノードになります。
注釈
ターゲット・アドレスとターゲット・ノード
ノード・アドレスは、グローバル配列名と 0 個以上の添え字のリストから構成されます。NodeReference オブジェ
クトには、グローバル名と添え字リスト・プロパティが含まれており、このプロパティには指定されたグローバル配
列内の 1 つの使用可能なアドレスへの参照を格納できます。これらのプロパティに格納されるアドレスは、ター
ゲット・アドレスと呼ばれます。データベースのターゲット・アドレスにノードが含まれている場合、それはターゲッ
ト・ノードと呼ばれます。
ここで使用している用語と概念の概要については、“グローバル配列の概要” を参照してください。
NodeReference のインスタンスが作成されるとき、データベースには何の追加も変更もありません。指定したグローバル
配列がデータベースにまだ含まれていない場合、それは、set() などの NodeReference メソッドによって永続ノードが作
成されるときに作成されます。
set() メソッドは value 引数を取り、それは既定でターゲット・ノードに割り当てられます。この値は、int、long、double、
byte[]、String、または ValueList にすることができます。値の後に、任意の数のオプションの subscript 引数を指定でき、
それによって、現在のターゲット・ノードのサブノードが指定されます (詳細は、“ターゲットのサブノードのアドレス指定”
を参照してください)。以下の例は、NodeReference のインスタンスを作成し、set() を使用してグローバル配列 ^myGlobal
に 2 つのノードを作成します。
NodeReference でのノードの作成
nodeRef = myConn.createNodeReference("myGlobal"); // target is root node^myGlobal
nodeRef.set("blue",3);
// create node ^myGlobal(3) = "blue"
nodeRef.set(123);
// set value of root node ^myGlobal to 123
nodeRef.set("red");
// change value of root node ^myGlobal to "red"
createNodeReference() の呼び出しによって、nodeRef という名前の NodeReference のインスタンスが作成され、
グローバル名プロパティの値として "myGlobal" が指定されます。ターゲット・アドレスは ^myGlobal ですが、
この時点ではデータベースに何も格納されていません。
set() の 1 回目の呼び出しで、値 blue と添え字 3 が指定され、それによってその値がサブノード ^myGlobal(3)
に割り当てられます。これで、データベースには永続グローバル配列 ^myGlobal が格納されます。それには 2
つのノード (^myGlobal(3) と値なしのルート・ノード ^myGlobal) があります。
set() の 2 回目の呼び出しでは、オプションの添え字がない値 123 が指定され、それによってその値がターゲッ
ト・ノード ^myGlobal に割り当てられます。
最後の呼び出しでも、値がターゲット・ノードに割り当てられ、それによってルート・ノード ^myGlobal の値が red
に変更されます。
set() メソッドは、データベースの内容を変更できる 4 つの NodeReference メソッドの 1 つです。これらのメソッドの詳細
は、“ノードの作成と削除” を参照してください。
Caché eXTreme での Java の使用法 49
グローバル API の使用法
4.3.2 ターゲット・アドレスの設定
多くの場合、set() の呼び出しの中でサブノードの添え字を指定すると便利ですが、添え字のハード・コード化されたリス
トは、多数のノードを操作する場合、すぐに管理が非常に困難になります。そのような場合は、ターゲット・アドレスを変更
するほうが実用的です。このセクションでは、添え字リスト・プロパティを制御して、NodeReference のインスタンスが、指
定したグローバル配列内の任意のアドレスをターゲットにできるようにするメソッドについて説明します。(グローバル名プ
ロパティを制御するメソッドも提供されています。それらについては、後で “複数のグローバル配列へのアクセス” で説
明します)。
注釈
添え字リストおよびノード・レベル
用語ノード・レベルは、添え字リスト内の添え字数を表します。例えば、^myGlobal("a","b","c") は、“レベル 3
ノード” です。これは、“3 つの添え字を持つノード” を別の方法で表現しているだけです。
以下のメソッドは、添え字リストの項目を追加または削除します。
•
appendSubscript() — subscript 引数 (int、long、double、または String) を取り、それをリストの最後に追加します。
•
setSubscriptCount() — subscriptPosition 引数を取り、指定された位置にある添え字の後の添え字をすべて削除す
ることで、リストを短くします。
以下のメソッドを使用して、添え字リスト内の項目を追加または削除することなく、既存の添え字にアクセスして変更する
こともできます。
•
getSubscriptCount() — ノード・レベル (リスト内の添え字の現在の数) を示す int 値を返します。
•
setSubscript() — 添え字を置換します。subscriptPosition および value 引数を取り、それらによって、置換される添
え字のノード・レベルと、新しい添え字として使用する値が指定されます。
以下の例は、NodeReference オブジェクトのノード・アドレスを構成し、set() を呼び出してターゲット・アドレスに値を格納
することで Caché データベースにグローバル配列を作成します。
ターゲット・アドレスの設定 : appendSubscript() での添え字の追加
nodeRef = myConn.createNodeReference("myGlobal"); // nodeRef points to ^myGlobal
nodeRef.appendSubscript("A");
// nodeRef points to ^myGlobal("A")
nodeRef.appendSubscript(1);
// nodeRef points to ^myGlobal("A",1)
nodeRef.set("hay");
// create persistent level 2 node ^myGlobal("A",1)
createNodeReference() の呼び出しによって nodeRef のグローバル名プロパティとして "myGlobal" が指定さ
れ、それによって初期ターゲット・アドレスがルート・ノード ^myGlobal になります。
appendSubscript() の呼び出しによって 2 つの添え字がターゲット・アドレスに追加され、それが ^myGlobal("A",1)
に変更されます。この時点では、データベースには何の変更もありません。
set() の呼び出しによって、ターゲット・アドレス ^myGlobal("A",1) に永続ノードが作成されます。
これで、Caché データベースには、3 つのノード (ターゲット・ノード ^myGlobal("A",1)、値なしノード ^myGlobal("A")、お
よび値なしルート・ノード ^myGlobal) を持つグローバル配列 ^myGlobal が格納されます。
添え字が添え字リストに追加されると、それは setSubscriptCount() によって削除されるか、setSubscript() によって変更
されるまで残ります。以下の例は、ターゲット・アドレスを ^myGlobal("A",1) に設定したままで開始されます。
ターゲット・アドレスの設定 : 添え字の削除と変更
// node reference currently points to ^myGlobal("A",1)
nodeRef.setSubscriptCount(1);
// go back to ^myGlobal("A")
nodeRef.setSubscript(1,"B");
// change target to ^myGlobal("B")
nodeRef.set("bee");
// create persistent level 1 node ^myGlobal("B")
nodeRef.setSubscriptCount(0);
// go back to root node ^myGlobal
nodeRef.set("this is the root");
// set the value of ^myGlobal
50 Caché eXTreme での Java の使用法
グローバル配列の構築
setSubscriptCount() の最初の呼び出しによって、添え字リストを最初の添え字の後で切り捨てるよう指定され、
ターゲット・アドレスが ^myGlobal("A") に変更されます。
setSubscript() の呼び出しによって、ターゲット・アドレスが ^myGlobal("B") に変更され、set() の呼び出しによっ
てそのアドレスに永続ノードが作成されます。
setSubscriptCount() の 2 回目の呼び出しによって、ノード・レベルとして 0 が指定され、添え字リストからすべ
ての添え字が削除されます。これで、ターゲット・アドレスは値なしルート・ノード ^myGlobal になり、set() の呼び
出しによって値がそのターゲット・ノードに割り当てられます。
この例は、ノード ^myGlobal("B") が追加されており、ルート・ノードの値が変更され、それによって、グローバル配列
^myGlobal に以下のノードと値が含まれるようになっています。
^myGlobal = "this is the root"
^myGlobal("A")
^myGlobal("A",1) = "hay"
^myGlobal("B") = "bee"
(valueless node)
setSubscript() メソッドは、subscriptPosition が添え字の現在の数よりも 1 つ多い数 (getSubscriptCount() +1) に設定さ
れている場合、新しい添え字を追加できます。これにより、以下の例に示すように、ノード・レベルをその値に設定して
setSubscript() を繰り返し呼び出すことで、同じ親ノードの下に一連のノードを作成したり、それらのノードにアクセスした
りできます。
ターゲット・アドレスの設定 : 一連のサブノードの作成
// node reference currently points to ^myGlobal
nodeRef.appendSubscript("C");
int nodelevel = nodeRef.getSubscriptCount()+1;
for (int ii = 1; ii < 4; ii++) {
nodeRef.setSubscript(nodelevel,ii);
nodeRef.set(ii*2);
// create three nodes ^myGlobal("C",<ii>)
}
現在のターゲット・アドレスは ^myGlobal であるため、appendSubscript() の呼び出しによってそのターゲット・ア
ドレスが ^myGlobal("C") に設定されます。
変数 nodelevel が使用されてループ内のレベルが指定されます。getSubscriptCount() の呼び出しが使用され
て、値が 2 (現在のノード・レベル +1) に設定されます。
ループ内で、setSubscript() の最初の呼び出しによって、添え字リストにレベル 2 添え字が追加されます。後続
の setSubscript() の各呼び出しによって、既存のレベル 2 添え字が新しい値に変更されます。
set() メソッドが、新しいターゲット・アドレスごとに呼び出され、新しいレベル 2 ノード ^myGlobal("C",1)、
^myGlobal("C",2)、および ^myGlobal("C",3) が作成されます。
この例は、以下のノードを ^myGlobal に追加します。
^myGlobal("C")
^myGlobal("C",1) = 2
^myGlobal("C",2) = 4
^myGlobal("C",3) = 6
(valueless node)
4.3.3 ターゲットのサブノードのアドレス指定
既定では、NodeReference メソッドは、ターゲット・アドレスにあるノードを処理します (“ターゲット・アドレスの設定” を
参照してください)。ただし、これらのメソッドの多くは、サブノード (ターゲット・ノードの下位ノード) のアドレスを指定する
オプションの引数を取ることができます。以下の例は、ターゲット・アドレスを変更することなく、いくつかの異なるノードの
値を設定します。
Caché eXTreme での Java の使用法 51
グローバル API の使用法
ターゲットのサブノードのアドレス指定
nodeRef = myConn.createNodeReference("myGlobal");
nodeRef.appendSubscript("A");
// Target address is ^myGlobal("A"), but set() specifies subnodes
nodeRef.set("myvalue1",1,"x");
// sets ^myGlobal("A",1,"x") = "myvalue1"
nodeRef.set("myvalue2",2);
// sets ^myGlobal("A",2) = "myvalue2"
nodeRef.set("myvalue3",3,"y","z"); // sets ^myGlobal("A",3,"y","z") = "myvalue3"
// Target address of nodeRef is still ^myGlobal("A")
nodeRef.set("myvalue0"); // sets ^myGlobal("A") = "myvalue0"
set() の最初の 3 回の呼び出しは、それぞれ添え字引数を指定します。ターゲット・アドレスは ^myGlobal("A")
であるため、これらの呼び出しによって、サブノード ^myGlobal("A","x",1)、^myGlobal("A",2)、および
^myGlobal("A",3,"y","z") の値が設定されます。これらの呼び出しのいずれによっても、nodeRef に格納されて
いる添え字リストは変更されません。
set() の最後の呼び出しでは、オプションの添え字は指定されず、ターゲット・ノード ^myGlobal("A") の値が設
定され、前の呼び出しによってターゲット・アドレスが変更されていないことが示されます。
注釈
多数のサブノードを処理する場合、添え字引数を指定するよりもターゲット・アドレスを変更するほうがわずかな
がら効率的です。このような状況で最適な方法については、この章で後述の “グローバル配列にわたる反復”
を参照してください。
set() および increment() に加えて、この章で別途説明している以下の NodeReference メソッドにより、添え字引数を使
用できます。
•
kill() および killNode() (“ノードの作成と削除”)。
•
getInt()、getLong()、getDouble()、getString()、getBytes()、getList()、および getObject() (“ノード値のフェッチ”)。
•
exists()、hasSubnodes()、nextSubscript()、および previousSubscript() (“グローバル配列にわたる反復”)。
•
acquireLock() および releaseLock() (“ロック” )。
4.3.4 ノードの作成と削除
グローバル API には、Caché データベースに接続し、そこに格納されているグローバル配列からデータを読み取る多数
のメソッドが含まれています。ただし、NodeReference クラスには、データベース内で実際に変更を行える 4 つのメソッ
ド (set()、increment()、kill()、および killNode()) のみが含まれています。このセクションでは、これらのメソッドの使用方法
について説明します。
set() および increment() でのノードの作成と変更
以下の NodeReference メソッドを使用して、特定の値を持つ永続ノードの作成、または既存のノードの値の変更を行え
ます。
•
set() — value 引数を取り、ターゲット・アドレスにその値を格納します。そのアドレスにノードが存在しない場合、値が
格納されるときに新しいノードが作成されます。value 引数は、int、long、double、byte[]、String、または ValueList
にできます。
•
increment() — int number 引数を取り、その数だけターゲット・ノードの値をインクリメントし、そのインクリメントした値
を long として返します。set() と異なり、これは、スレッドセーフなアトミック処理を使用して、ノードの値を変更します。
したがって、ノードは決してロックされません。このターゲット・ノード値は、int、long、または double にできます。ター
ゲット・アドレスにノードがない場合、このメソッドは 0 の値を持つ新しいノードを作成し、それを指定した数だけイン
クリメントします。
どちらのメソッドも、オプションの subscript 引数を取り、ターゲット・ノードのサブノードにアクセスできます (“ターゲットの
サブノードのアドレス指定” を参照してください)。以下の例では、set() および increment() の両方を使用して、ノード値
を作成および変更します。
52 Caché eXTreme での Java の使用法
グローバル配列の構築
ノードの作成と削除 : ノード値の設定とインクリメント
// Target address of nodeRef is root node ^myGlobal
nodeRef.set("first");
// create root node ^myGlobal = "first"
nodeRef.set(2);
// change value of ^myGlobal to int 2.
// Use increment() to create and change nodes
nodeRef.increment(2);
// increment value of root node ^myGlobal from 2 to 4.
nodeRef.increment(3,1);
// create new subnode ^myGlobal(1) = 3.
// Increment subnode ^myGlobal(1) and create subnodes ^myGlobal(2) and ^myGlobal(3)
for (int subnode = 1; subnode < 4; subnode++) {
nodeRef.increment(2,subnode);
// create node or increment value of node
}
set() の最初の呼び出しによって、ターゲット・アドレスであるルート・ノード ^myGlobal に "first" の String 値
が格納されます。これによって、1 つのノードを含む新しいグローバル配列 (これの名前も ^myGlobal) が作成さ
れます。2 回目の呼び出しによって、String 値を 2 の int 値に置き換えることにより、ターゲット・ノードの値が変
更されます。
increment() の最初の呼び出しによって、ターゲット・ノード ^myGlobal の値が 2 から 4 に変更されます。
2 回目の呼び出しによって subscript 引数が指定され、3 の値を持つ新しいサブノード ^myGlobal(1) が作成さ
れます。
for ループ内で、increment() が 3 つの異なる subscript 引数で 3 回呼び出されます。最初の反復で、既存の
サブノード ^myGlobal(1) の値が 3 から 5 に変更されます。次の 2 回の反復で、新しいサブノード ^myGlobal(2)
と ^myGlobal(3) がそれぞれ値 2 で作成されます。
kill() および killNode() でのノードの削除
ノードは、それに値がなく、値を持つサブノードもない場合、データベースから削除されます。最後の値がグローバル配
列から削除されると、グローバル配列全体も削除されます。NodeReference の以下のメソッドを使用して、データベース
から 1 つ以上のノード値を削除します。
•
kill() — 指定したノードの値およびその下位ノードすべての値を削除します。ルート・ノードを指定した場合は、その
グローバル配列全体が削除されます。このメソッドは、Caché の包含的 KILL コマンドに相当します。
•
killNode() — 指定したノードの値のみを削除します。そのノードは値なしになりますが、それにサブノードがある場合
は削除されません。サブノードの値は、影響を受けません。このメソッドは、Caché の ZKILL コマンドに相当します。
以下の例のいくつかに示すように、kill() と killNode() のどちらも、オプションの subscript 引数を取り、ターゲット・ノード
のサブノードにアクセスできます (“ターゲットのサブノードのアドレス指定” を参照してください)。
これらの例はすべて、ルート・ノード ^myGlobal が nodeRef のターゲット・アドレスであり、そのグローバル配列には最初
に以下のノードが含まれていることが前提となっています。
^myGlobal = 0
^myGlobal("A") =
^myGlobal("A",1)
^myGlobal("B") =
^myGlobal("B",1)
^myGlobal("B",2)
0
= 0
0
= 0
= 0
ノードの作成と削除 : 指定したノード値のみを削除する killNode() の使用法
nodeRef.killNode("A");
// only delete value of ^myGlobal("A")
killNode() の呼び出しによって、指定したサブノード ^myGlobal("A") の値のみが削除されます。これによって、
それは値なしになりますが、そのグローバル配列の一部のままです。これは ^myGlobal("A",1) に依然として値
があるためです。
ノードの作成と削除 : グローバル配列の 1つの分岐内のすべてのノードを削除する kill() の使用法
nodeRef.kill("B");
// kill ^myGlobal("B") and all of its subnodes
Caché eXTreme での Java の使用法 53
グローバル API の使用法
kill() の呼び出しによって、指定したサブノード ^myGlobal("B") の値と、その下の両方のノードが削除されます。
それらのノードは (前の例の ^myGlobal("A") とは異なり)、そのグローバル配列から完全に削除されます。これ
は、それらには値も、値を持つサブノードもないためです。そのグローバル配列内の残りの 3 つのノードへの影
響はありません。
ノードの作成と削除 : グローバル配列全体を削除する kill() の使用法
// These nodes are left after the previous examples:
//
^myGlobal = 0
//
^myGlobal("A") <valueless node>
//
^myGlobal("A",1) = 0
nodeRef.kill();
// kill all nodes in global array ^myGlobal
添え字引数が指定されてないため、kill() の呼び出しによって、ターゲット・ノード ^myGlobal とそのサブノードす
べての値が削除されます。これにより、値を持つノードが含まれなくなったため、そのグローバル配列全体が削
除されます。
4.4 グローバル配列にわたる反復
グローバル API は、1 つのグローバル配列の一部または全部に対して反復処理する方法を提供します。以下の項目で
は、グローバルのさまざまな反復メソッドについて説明します。
•
一連のノードの取得 — 親ノードの直下にあるサブノードのセットに対して反復処理する方法について説明します。
•
開始ポイントと反復処理の順序の制御 — カーソルの初期化方法と、照合の降順で反復処理する方法について説
明します。
•
ターゲット・アドレスのすべてのサブノードへのアクセス — ノード値およびサブノードの存在についてテストする方法
と、ノード・レベルに関係なくすべてのサブノードに対して反復処理する方法について説明します。
4.4.1 一連のノードの取得
このセクションでは、親ノードの直下にある一連のサブノードに対して反復処理する方法について説明します。例えば、
以下のグローバル配列があり、親ノード ^myNames("people") の下の 5 つのレベル 2 ノードに対して反復処理するとし
ます。
^myNames
^myNames("people")
^myNames("people","Anna") = 2
^myNames("people","Julia") = 4
^myNames("people","Misha") = 5
^myNames("people","Ruri") = 3
^myNames("people","Vlad") = 1
(valueless root node)
(valueless level 1 node)
nextSubscript() メソッドは現在のターゲット・ノードで開始し、同じ親ノードの下の同じノード・レベルにある次のノードを見
つけ、その最後の添え字を返します。例えば、そのターゲット・アドレスがレベル 2 ノード ^myNames("people","Anna")
に設定されている場合、そのメソッドは、次のノードからレベル 2 添え字 "Julia" を含む文字列を返します。
添え字が返されたら、それを使用してターゲット・アドレスを変更でき (“ターゲット・アドレスの設定” を参照)、nextSubscript()
は、昇順で次のノードを検索できます。nextSubscript() は、昇順でこれ以上ノードが見つからない場合、空の文字列 ("")
を返します。
昇順で最初の添え字を見つけるには、ターゲット添え字を空の文字列に設定します。例えば、レベル 2 添え字 "Anna"
を見つけるには、nextSubscript() を呼び出す前にターゲット・アドレスを ^myNames("people","") に設定します。
以下の例は、^myNames("people") の下にあるすべてのレベル 2 ノードに対して反復処理し、それぞれの情報を出力し
ます。
54 Caché eXTreme での Java の使用法
グローバル配列にわたる反復
一連のノードの取得 : ^myNames("people") の下にあるすべてのレベル 2 ノードの検索
// Find the first level 2 node under ^myNames("people")
NodeReference nodeRef = myConn.createNodeReference("myNames");
nodeRef.appendSubscript("people");
nodeRef.appendSubscript("");
String subscr = nodeRef.nextSubscript(); // Value of subscr is now "Anna"
// Iterate in ascending order until nextSubscript() returns ""
System.out.print("Ascend from first node: ");
while (!subscr.equals("")) {
nodeRef.setSubscript(nodeRef.getSubscriptCount(), subscr);
System.out.print("\"" + subscr + "\" ");
subscr = nodeRef.nextSubscript();
}
このコードは以下の行を出力します。
Ascend from first node: "Anna" "Julia" "Misha" "Ruri" "Vlad"
appendSubscript() の呼び出しによって、レベル 2 添え字が空の文字列に設定され、意図的に無効なターゲッ
ト・アドレス ^myNames("people","") が作成されます。この開始アドレスは、昇順で ^myNames("people") に存在
する可能性がある最初の子の前になります。
nextSubscript() の最初の呼び出しによって、昇順で最初に存在するレベル 2 添え字が返されます。これで、
subscr の値は "Anna" になります。
while ループの最初の反復で、setSubscript() が呼び出され、ターゲット・アドレスが ^myNames("people","Anna")
に設定されます。print 文によって、ターゲット・ノードの現在のレベル 2 添え字が出力され、nextSubscript() が
呼び出されて次のノードが検索されます。
while ループの後続の各反復で、次のレベル 2 添え字が返され、それがターゲット・アドレスの設定に使用さ
れ、出力されます。このループは、NextSubscript() が空の文字列 ("") を返したときに終了します。それは、検
索するノードがそれ以上ないためです。
この例は、非常に単純であり、いくつかの状況で失敗する可能性があります。グローバル配列の複数のレベルにデータ
がある場合、どうなるでしょうか。コードが、値なしノードから値をフェッチしようとする場合、どうなるでしょうか。最初のノー
ドから開始したくない場合、どうなるでしょうか。以下のセクションでは、これらの状況を処理する方法を説明します。
4.4.2 開始ポイントと反復処理の順序の制御
このセクションの例では、少し複雑なサブノードのセットを使用します。
^myNames
(valueless root node)
^myNames("dogs")
(valueless level 1 node)
^myNames("dogs","Balto") = 6
^myNames("dogs","Hachiko") = 8
^myNames("dogs","Lassie") = 9
^myNames("dogs","Lassie","Timmy") = 10
^myNames("dogs","Whitefang") = 7
最初のレベル 2 ノードで開始して昇順で反復する代わりに、この例では、途中から開始して降順で反復します。反復の
方向 (昇順または降順) は、以下の適切な NodeReference 反復メソッドを呼び出すことで制御します。
•
nextSubscript() — 照合の昇順で検索します (前述の例で示すとおりです)。
•
previousSubscript() — 照合の降順で検索します。
どちらのメソッドも現在のターゲット・ノードで開始し、同じ親ノードの下の同じノード・レベルにある次のノードを見つけ、
その最後の添え字 (または、ノードが見つからなければ "") を返します。
開始ポイントは以下のルールに従って指定されます。
Caché eXTreme での Java の使用法 55
グローバル API の使用法
•
開始添え字として空の文字列が指定されている場合、検索は、指定した方向で最初のノードの前から開始されま
す。例えば、ターゲット・アドレスとして ^myNames("dogs","") を指定した場合、nextSubscript() は "Balto" を、
previousSubscript() は "Whitefang" を返します。
•
開始添え字には、任意の有効な添え字値を指定でき、結果のターゲット・アドレスは既存のノードでなくてもかまい
ません。例えば、ターゲット・アドレスが ^myNames("dogs","M") である場合、nextSubscript() は "Whitefang" を、
previousSubscript() は "Lassie" を返します (レベル 3 ノード ^myNames("dogs","Lassie","Timmy") は見つかりま
せん。これは、検索ではターゲット・アドレスと同じレベルにあるノードのみが対象となるためです)。
注釈
空の文字列を添え字として使用する場合の注意
空の文字列の添え字は、検索の直前にターゲット・アドレスを初期化する場合以外は追加しないでください。空
の文字列を追加すると、無効なターゲット・アドレスが作成され、これにより、大部分の NodeReference メソッド
呼び出しでは GlobalsException がスローされます。
次の例は、nextSubscript() ではなく previousSubscript() を使用し、開始アドレスを ^myNames("people","") ではなく
^myNames("dogs","W") に設定します。これにより、照合順で "W" より前のレベル 2 添え字を持つ ^myNames("dogs")
のすべてのレベル 2 サブノードがフェッチされます。
開始ポイントと反復処理の順序の制御 : "W" からの降順
nodeRef.setSubscriptCount(0);
nodeRef.appendSubscript("dogs");
nodeRef.appendSubscript("W");
String subscr = nodeRef.previousSubscript();
System.out.print("Start at \"W\" and descend: ");
while (!subscr.equals("")) {
nodeRef.setSubscript(nodeRef.getSubscriptCount(), subscr);
System.out.print("\"" + subscr + "\"=" + nodeRef.getInt() + " ");
subscr = nodeRef.previousSubscript();
}
このコードは以下の行を出力します。
Start at "W" and descend: "Lassie"=9 "Hachiko"=8 "Balto"=6
appendSubscript() の呼び出しによって、開始アドレスがレベル 2 ノード ^myNames("dogs","W") に設定されま
す。そのアドレスにノードが実際に存在しているかどうかは関係ありません。これによって、単に添え字検索を開
始する位置が確立されます。
previousSubscript() の最初の呼び出しによって、照合順で ^myNames("dogs","W") より前の ^myNames("dogs")
の最初のレベル 2 サブノードが検索され、そのレベル 2 添え字が返されます。
while ループでは、照合の降順で "W" より前のそれぞれのレベル 2 添え字が返され、previousSubscript() が
空の文字列を返すとループは終了します。
この例では、この検索でグローバル配列 ^myNames のノードの多くは検出されません。
•
検索が降順で実行され、"Whitefang" が照合順で "W" より後であるため、ノード ^myNames("dogs","Whitefang")
は検出されません。
•
この検索ではレベル 2 添え字のみが対象となるため、ノード ^myNames("dogs","Lassie","Timmy") は検出されませ
ん。
•
この検索では ^myNames("dogs") の下のノードのみが対象となるため、^myNames("people") の下のレベル 2 ノード
は検出されません。
以下のセクションでは、グローバル配列 ^myNames のすべてのノードを検索し、どのノードに値が含まれているのかを判
別する方法を示します。
56 Caché eXTreme での Java の使用法
グローバル配列にわたる反復
4.4.3 ターゲット・アドレスのすべてのサブノードへのアクセス
previousSubscript() および nextSubscript() メソッドは、1 つのノード・レベルに対してのみ動作しましたが、各レベルのす
べてのサブノードを検索することもできます。NodeReference の以下のメソッドを使用すると、1 つのグローバル配列の
すべてのレベルを検索し、どのノードに値が含まれているのかを判別できます。
•
hasSubnodes() — ターゲット・ノードに下位ノードが含まれている場合、true を返します。
•
exists() — ターゲット・ノードに定義された値がある場合は true を返し、ノードにサブノードはあるが値はない場合
は false を返します。
以下の例にリストされている exampleShowGlobal() メソッドは、nextSubscript() および hasSubnodes() を使用して、グロー
バル配列 ^myNames のすべてのノードに対して反復し、繰り返し呼び出してすべてのレベルを処理します。exists() メソッ
ドを使用して、ノード値の読み取りを試みる前にそれらについてテストします。
exampleShowGlobal() のメイン・コード・ブロックは、hasSubnodes() を使用して反復呼び出しをトリガし、exists() を使用し
てノード値についてテストする以外は、前の例とほとんど同一です。
サブノードへのアクセス : exampleShowGlobal() — で再帰的にすべてのノード・レベルを検索
以下のコードは、^myNames への一時的なノード参照を、ターゲット・アドレスをそのルート・ノードに設定して作
成します。
NodeReference tempRef = myConn.createNodeReference("myNames");
exampleShowGlobal(tempRef, "^myNames(");
tempRef.close();
exampleShowArray() メソッドは、現在のターゲット・ノードの下にサブノードが検出されるたびに、それ自体を再
帰的に呼び出します。ターゲット・ノードごとに、すべてのサブノードに対して反復処理し、値がある場合 (ノード
によってはサブノードはあるがノード値がないことがあります)、それらの値を出力します。
public static void exampleShowGlobal(NodeReference aNodeRef, String aBaseName) {
try {
aNodeRef.appendSubscript("");
String subscr = aNodeRef.nextSubscript();
while (!subscr.equals("")) {
aNodeRef.setSubscript(aNodeRef.getSubscriptCount(), subscr);
if (aNodeRef.exists())
System.out.println(aBaseName + subscr + ") = " + aNodeRef.getInt());
if (aNodeRef.hasSubnodes())
exampleShowGlobal(aNodeRef, aBaseName + subscr + ",");
subscr = aNodeRef.nextSubscript();
}
}
catch (GlobalsException e) { System.out.println("exampleShowGlobal():" + e.getMessage()); }
finally { aNodeRef.setSubscriptCount(aNodeRef.getSubscriptCount() - 1); }
} // end exampleShowGlobal()
appendSubscript() の呼び出しによって、空の文字列が添え字リストに追加され、nextSubscript() が照合の昇順
で最初のノードの前から検索を開始するようになります。
while ループで、現在のレベルにある各兄弟ノードが検出されます。exists() の呼び出しがノードに値が含ま
れていることを示している場合、そのノード・アドレスおよび値が出力されます。
hasSubnodes() メソッドを使用して、下位ノードを持つ各ノードに対して exampleShowGlobal() の反復呼び出しを
トリガします。反復ごとに、それ以上サブノードが検出されなくなるまで 1 レベル下が検索されます。finally
節で、各反復の終わりに setSubscriptCount() が呼び出され、ターゲット・アドレスが前のレベルに戻ります。
この例は以下の出力を生成します。
Caché eXTreme での Java の使用法 57
グローバル API の使用法
^myNames("dogs","Balto")=6
^myNames("dogs","Hachiko")=8
^myNames("dogs","Lassie")=9
^myNames("dogs","Lassie","Timmy")=10
^myNames("dogs","Whitefang")=7
^myNames("people","Anna")=2
^myNames("people","Julia")=4
^myNames("people","Misha")=5
^myNames("people","Ruri")=3
^myNames("people","Vlad")=1
この出力は、[ホーム] > [グローバル] に移動し、左側のリストから User ネームスペースを選択し、^myNames の [ ]
リンクをクリックしたときに、管理ポータルに表示される出力に似ています。
照合順でノードが検出されて出力されても、それらがその順序でデータベースに追加されているとは限りません(実際は、
このテスト配列を作成したコードは、各ノードの値をループ・カウンタから取得しているいため、値は挿入の順序を示して
います)。Caché での照合順の決定方法の詳細は、“複数レベルのグローバル配列での照合順” を参照してください。
4.5 グローバル配列のデータの取得
グローバル API では、ノード参照がデータ型 int、long、double、または String の添え字を取ることができます。ノード値
は、それらの 4 つのデータ型のいずれかおよびbyte[] または Valuelist にすることができます。わかりやすくするために、
この章の前のセクションの例では、常に int または String 添え字およびノード値を使用しました。このセクションでは、サ
ポートされるデータ型の全範囲を割り当て、取得する方法について説明します。
•
ノード値のフェッチ — サポートされる Java データ型としてデータベースからノード値をフェッチしてそれらを返すメ
ソッドについて詳しく説明します。
•
ターゲット・アドレスからの添え字の読み取り — Java NodeReference オブジェクトの添え字リストを読み取り、適切な
データ型の変数として各添え字を返すことができるメソッドについて説明します。
4.5.1 ノード値のフェッチ
NodeReference クラスは、既知のデータ型 int、long、double、String、byte[]、または ValueList の値を持つノードをフェッ
チするためのデータ型固有のメソッドを提供します。さらに、getObject() メソッドは、未知のデータ型のノード値をフェッ
チし、それらを適切な型にキャストできる Object 変数として返します。
このセクションで説明する項目は以下のとおりです。
•
数値のフェッチ — int、long、および double の値をフェッチするための型固有のメソッドについて説明します。
•
String および byte[] 値のフェッチ — String および byte[] の値をフェッチするための型固有のメソッドについて説
明します。
•
未知のデータ型のノード値のフェッチ — 適切なデータ型にキャストできる Object 値をフェッチする getObject() メ
ソッドについて説明します。
注釈
値リストのフェッチ
ValueList クラスは、入れ子の ValueList など、サポートされているデータ型のいずれでも格納できるシリアル化
されたリストをカプセル化します。ValueList としてノード値をフェッチする getList() メソッドの完全な説明は、
“シリアル化された値リストの使用法” を参照してください。
4.5.1.1 数値のフェッチ
このセクションでは、NodeReference の以下のメソッドについて説明します。
58 Caché eXTreme での Java の使用法
グローバル配列のデータの取得
•
getInt() — ターゲット・ノードの値をフェッチし、それを int として返します。
•
getLong() — ターゲット・ノードの値をフェッチし、それを long として返します。
•
getDouble() — ターゲット・ノードの値をフェッチし、それを double として返します。
getInt()、getLong()、および getDouble() メソッドは、ノード値が数値であることを前提として、それを適切な Java 変数に
変換することを試みます。ターゲット・ノードが値なしまたは存在しない場合には UndefinedException をスローします。こ
れらのメソッドはすべて、オプションの subscript 引数を取り、ターゲット・ノードのサブノードにアクセスできます (“ター
ゲットのサブノードのアドレス指定” を参照してください)。
重要
フェッチ・メソッドは互換性のないデータ型に対して例外をスローしない
これらのメソッドは、速度に対して最適化されており、型のチェックを行うことはありません。アプリケーショ
ンでは、非数値に対して例外がスローされることに依存しないようにしてください。そのような場合、例外
がスローされてもメソッドは不正確または意味のない値を返すことがよくあります。
数値フェッチ・メソッドは、以下の例で示すとおり、さまざまな型の数値を適切に処理します。
ノード値のフェッチ : getInt()、getLong()、および getDouble() の使用法
nodeRef.set(23);
int intVal = nodeRef.getInt();
// returns 23
long longVal = nodeRef.getLong();
// returns 23
double doubleVal = nodeRef.getDouble();
// returns 23.0
nodeRef.set(10.1234);
doubleVal = nodeRef.getDouble();
// returns 10.1234
// Do not use getInt() or getLong() to fetch double values!
int 値が指定されると、数値メソッドはすべて、意味のある値を返します。getInt() および getLong() メソッドは、
double 値に適用して信頼性の高い結果を得ることはできず、場合によっては例外がスローされます。
4.5.1.2 String および byte[] 値のフェッチ
このセクションでは、NodeReference の以下のメソッドについて説明します。
•
getString() — ターゲット・ノードの値をフェッチし、それを String として返します。
•
getBytes() — ターゲット・ノードの値をフェッチし、それを byte[] として返します。
これらのメソッドはどちらも、オプションの subscript 引数を取り、ターゲット・ノードのサブノードにアクセスできます (“ター
ゲットのサブノードのアドレス指定” を参照してください)。
getString() および getBytes() メソッドは、ノード値が非数値であることを前提としており、適切にノード値を変換すること
を試みます。これらのメソッドはどちらも、ターゲット・ノードが値なしまたは存在しない場合には null を返します。これら
のメソッドは、型のチェックを実行せず、引数で、数値を持つノードが指定されている場合でも通常は例外をスローしませ
ん。
バイナリ・データは、byte の配列として格納し、getBytes() を使用してフェッチできます。以下の例では、バイト配列が作
成され、これが符号なし整数値のリストとして出力されます。便宜上、この例は、文字に対応する byte 値を使用します。
ノード値のフェッチ : getString() および getBytes() の使用法
byte[] testBytes = {'C','a','c','h',((byte)'é')};
nodeRef.set(testBytes);
System.out.print("Bytes fetched as byte[]:");
byte[] outBytes = nodeRef.getBytes();
for (int ii = 0; ii < outBytes.length; ii++) {
System.out.print(" " + ((int)outBytes[ii] & 0xff)); // get byte as unsigned int
}
System.out.println();
// prints: Bytes fetched as byte[]: 67 97 99 104 233
System.out.println("String value of byte array: " + nodeRef.getString());
// prints: String value: Caché
Caché eXTreme での Java の使用法 59
グローバル API の使用法
既定では、127 を超えるバイト値は、負の数として解釈されます。この例では、0xff で各バイトがマスクされ、出
力用の符号なし整数が生成されます。
これは推奨される方法ではありませんが、配列のすべてのバイトが出力可能な文字として解釈できるため、この
例のノード値も文字列として読み取りおよび出力できます。
4.5.1.3 未知のデータ型のノード値のフェッチ
ノードに、データ型 int、long、double、または String の値がある場合、ノード値は Object として返され、適切なデータ型
にキャストできます。NodeReference の以下のメソッドは、Object 値を返します。
•
getObject() — ターゲット・ノードの値をフェッチし、それを Object として返します。オプションの subscript 引数を取
り、ターゲット・ノードのサブノードにアクセスできます (“ターゲットのサブノードのアドレス指定” を参照してくださ
い)。
注釈
Caché データベースでは、String、byte[]、および ValueList の各オブジェクトは、すべて文字列として格納さ
れ、元のデータ型に関する情報は保持されません。instanceOf 演算子によって 3 つのデータ型がすべて
String のインスタンスとして解釈されるため、元の非数値型が未知である場合、アプリケーションでは getObject()
の使用を回避してください。
以下の例は、4 つの異なるデータ型の値を持つノードを作成し、getObject() でそれらをフェッチし、返された各 Object
を適切なデータ型にキャストします。この例では、set() と getObject() の両方が添え字引数を使用して、アクセス先のサ
ブノードを指定します。
ノード値のフェッチ : getObject() の使用法
nodeRef.set(13, 1);
nodeRef.set(-4555666777L, 2);
nodeRef.set(1.234, 3);
nodeRef.set("hello", 4);
//
//
//
//
^MyGlobal(1)
^MyGlobal(2)
^MyGlobal(3)
^MyGlobal(4)
=
=
=
=
13
-4555666777L
1.234
"hello"
for (int subnode = 1; subnode < 5; subnode++) {
Object obj = nodeRef.getObject(subnode);
System.out.print("node ^myGlobal(" + subnode + ") is type ");
if (obj instanceof String) System.out.print("String: \""+(String)obj+"\"");
else if (obj instanceof Integer) System.out.print("Integer: "+((Integer)obj).intValue());
else if (obj instanceof Long) System.out.print("Long: "+((Long)obj).longValue()+"L");
else if (obj instanceof Double) System.out.print("Double: "+((Double)obj).doubleValue());
else System.out.print("unexpected: "+obj.getClass().getName());
System.out.println();
}
set() の呼び出しによって、さまざまなデータ型の 4 つの新しいノードが生成されます。
getObject() メソッドは、各ノード値を Object として返し、instanceOf 演算子を使用して元のデータ型を判別
します。
この例は以下の出力を生成します。
node
node
node
node
^myGlobal(1)
^myGlobal(2)
^myGlobal(3)
^myGlobal(4)
is
is
is
is
type
type
type
type
Integer: 13
Long: -4555666777L
Double: 1.234
String: "hello"
4.5.2 ターゲット・アドレスからの添え字の読み取り
このセクションでは、NodeReference オブジェクトの添え字リストから添え字を読み取り、適切なデータ型 (int、long、
double、または String) の値としてそれを返すメソッドについて説明します。これらのメソッドを使用して、現在のターゲッ
ト・アドレスを出力したり、現在のノード参照を複製したり、それが役立つ可能性がある他の状況で個別の添え字の値に
アクセスできます。
60 Caché eXTreme での Java の使用法
グローバル配列のデータの取得
添え字メソッドはノード値をフェッチするためのメソッド (“ノード値のフェッチ” を参照) に似ていますが、いくつかの重要
な相違点があります。
•
ノード値メソッドとは異なり、添え字メソッドは Caché データベースから永続データをフェッチしません。単に、
NodeReference インスタンスの添え字リスト・プロパティから現在の値を返すのみです。
•
添え字は添え字リストに既に特定の Java データ型として格納されているため、型変換は必要ありません。型固有の
添え字メソッドが、誤ったデータ型の添え字を読み取ろうとすると (getLongSubscript() は int 添え字を読み取ること
ができても)、例外がスローされます。
注釈
型付きの添え字リストはメモリ内にのみ、NodeReference オブジェクトのプロパティとして存在することを覚えて
おくことが大切です。Caché データベースでは、すべての添え字は文字列として正規化され、元のデータ型の
区別は失われます。データベースから (“グローバル配列にわたる反復” の説明に従って) ノード・アドレスを
取得する場合、簡単に添え字の元のデータ型を回復する方法はありません。
特定のデータ型の添え字の読み取り
NodeReference の以下のメソッドは、特定のデータ型の添え字リスト項目を返します。各メソッドは、読み取り対象の添え
字の位置を指定する level 引数を取ります。
•
getIntSubscript() — 指定されたレベルにある int 型の添え字を読み取ります。
•
getLongSubscript() — 指定されたレベルにある long または int 型の添え字を読み取ります。
•
getDoubleSubscript() — 指定されたレベルにある double 型の添え字を読み取ります。
•
getStringSubscript() — 指定されたレベルにある String 型の添え字を読み取ります。
各メソッドが間違ったデータ型の添え字を読み取ろうとした場合、または level 引数がリストの添え字数よりも大きい場合、
各メソッドによって GlobalsException がスローされます。
以下の例は、ノード ^mySubscripts(101, 9876543210L, 3.14, "string value") の各添え字をデータ型に適したメソッドを
使用して読み取ります。返される値を使用して、完全なノード・アドレスが出力されます。
ターゲット・アドレスからの添え字の読み取り : 既知のデータ型の添え字
// nodeRef points to ^mySubscripts(101,9876543210L,3.14,"string value")
System.out.println(
"^mySubscripts("
+ nodeRef.getIntSubscript(1) + ", "
+ nodeRef.getLongSubscript(2) + "L, "
+ String.valueOf(nodeRef.getDoubleSubscript(3)) + ", "
+ "\"" + nodeRef.getStringSubscript(4) + "\")"
);
// prints: ^mySubscripts(101, 9876543210L, 3.14, "string value")
標準 Java String.valueOf() メソッドが使用されて、double 値が正確な表示文字列に変換されます。
すべてのデータ型の添え字の読み取り
以下のメソッドは、すべてのデータ型の添え字となり得る Object を返します。
•
getObjectSubscript() — 指定されたレベルの添え字を読み取り、それを Object として返します。例えば、
getObjectSubscript(3) は、レベル 3 添え字を含むオブジェクトを返します。指定したレベルがリストの添え字
数より大きい場合、GlobalsException がスローされます。
Java instanceof 演算子は、実際のデータ型を判別するために使用して、添え字を int、long、double、または
String として適切にキャストできます。
以下のコードは、前の例と完全に同じ出力を生成しますが、添え字のデータ型を把握しているかどうかに依存しません。
Caché eXTreme での Java の使用法 61
グローバル API の使用法
ターゲット・アドレスからの添え字の読み取り : すべてのデータ型の添え字
Object sub = null;
try {
System.out.print("^" + nodeRef.getName() +"(");
for (int ii=1; ii<=nodeRef.getSubscriptCount(); ii++) {
sub = nodeRef.getObjectSubscript(ii);
if (sub instanceof Integer) System.out.print(sub.toString());
else if (sub instanceof Long) System.out.print(sub.toString() + "L");
else if (sub instanceof Double) System.out.print(String.valueOf((Double)sub));
else System.out.print("\"" + sub.toString() + "\"");
if (ii < nodeRef.getSubscriptCount()) System.out.print(", ");
}
System.out.println(")");
}
catch (GlobalsException e) { System.out.println(e.getMessage()); }
nodeRef のターゲット・アドレスが ^mySubscripts(101,9876543210L,3.14,"string value") である場合、以下のよ
うに出力されます。
^mySubscripts(101, 9876543210L, 3.14, "string value")
アドレス情報は、グローバル名および添え字を返す getName() および getObjectSubscript() によって取得され
ます (getName() の詳細は “グローバル名へのアクセス” を参照してください)。
instanceof 演算子を使用すると、添え字のデータ型を特定し、各添え字を適切な形式 (String は引用符で
囲み、Long の後には L) で出力できます。出力は出力専用であるため、sub を特定のデータ型にキャストする
必要はありません。sub.toString() の呼び出しによって、実際のデータ型に関係なく出力可能な文字列が
返されます。
重複ノード参照の作成
以下の例は、NodeReference の既存のインスタンスのターゲット・アドレスを読み取り、そのアドレスを新しいインスタンス
にコピーします。この手法は、現在のターゲット・アドレスのレコードが変更される可能性がある操作を実行する前にその
レコードを保持する場合に便利です。
ターゲット・アドレスからの添え字の読み取り : 重複ノード参照の作成
try {
NodeReference newNode = myConn.createNodeReference(nodeRef.getName());
if (nodeRef.getSubscriptCount()>0) {
for (int ii=1; ii<=nodeRef.getSubscriptCount(); ii++) {
Object subscr = nodeRef.getObjectSubscript(ii);
if (subscr instanceof Integer) { newNode.appendSubscript((Integer)subscr); }
else if (subscr instanceof Long) { newNode.appendSubscript((Long)subscr); }
else if (subscr instanceof Double) { newNode.appendSubscript((Double)subscr); }
else { newNode.appendSubscript((String)subscr); }
}
}
}
catch (GlobalsException e) { System.out.println(e.getMessage()); }
createNodeReference() メソッドは新しいノード参照オブジェクトを作成し、getName() メソッド (“グローバル名へ
のアクセス” で説明) を使用して nodeRef からグローバル名を読み取ります。
getObjectSubscript() メソッドは、添え字を読み取るために使用します。返される各添え字は instanceof 演
算子で評価され、appendSubscript() に渡されるときに適切にキャストできます。
4.6 シリアル化された値リストの使用法
ValueList クラスは、任意の数の要素を格納できるシリアル化されたリストをカプセル化します。各要素は、サポートされ
ているデータ型 (int、long、double、String、byte[]、または入れ子の ValueList) のいずれでもかまいません。データベー
スでは、任意のサイズの ValueList が単一のノードに、Caché $LIST 形式を使用するバイナリ文字列としてエンコードさ
62 Caché eXTreme での Java の使用法
シリアル化された値リストの使用法
れて格納されます。この形式は Java アプリケーションに対して透過的ですが、ValueList を含むノードは、$LIST 形式を
サポートする Caché ObjectScript または任意の Caché 言語バインディングにより $LIST として解釈できます。
このセクションでは、以下の項目について説明します。
•
ValueList の作成、格納、およびフェッチ — ValueList を作成および破棄するメソッド、リスト要素を追加または削除
するメソッド、およびデータベースからリストをフェッチするメソッドの使用法について説明します。
•
ValueList 要素の読み取り — リスト要素を選択し、適切なデータ型の変数として返すことを可能にする ValueList メ
ソッドについて説明します。
4.6.1 ValueList の作成、格納、およびフェッチ
ValueList のインスタンスは、以下のメソッドによって作成され、フェッチされます。
•
Connection.createList() — 空の ValueList オブジェクトを返します。リスト・バッファの初期バイト・サイズを指定する
ことでメモリ割り当てを最適化できる、オプションの int bufferSize 引数を取ります。データベースへの接続がない場
合は、GlobalsException をスローします。
•
NodeReference.getList() — データベースからターゲット・ノードの値をフェッチし、それを ValueList オブジェクトとし
て返します (データベースからノード値をフェッチするメソッドの一般的な説明は、“ノード値のフェッチ” を参照して
ください)。オプションの添え字引数を取ることができます。
以下の ValueList メソッドを使用して、インスタンスを生成および破棄します。
•
append() — サポートされている型 (int、long、double、String、byte[]、または入れ子の ValueList) の 1 つ以上の値
を追加します。
•
clear() — リストをクリアして、それに含まれる要素の数を 0 にします。
•
close() — オブジェクトを破棄し、その基盤となるネイティブ・コード・リソースを解放し、メモリ・リークを回避します。
リストの内容を変更できる方法は、append() および clear() メソッドのみです。単一の要素を削除したり、リストの途中に新
しい要素を挿入したり、既存の要素の値を変更するメソッドはありません。
以下の例では、ValueList が作成され、データ型 Integer、Long、Double、String、および byte[] の要素が入力されま
す。このリストは、ルート・ノード ^myListNode に格納されます。この例では、その後、リストがクリアされてそれに新しい
データが入力され、古いリストがフェッチされて新しい ValueList が古いリストの入れ子の要素として追加されます。
ValueList の作成、格納、およびフェッチ
// Create a list, append elements of different types, and store it in ^myListNode
ValueList myList = myConn.createList();
myList.append(13, -4555666777L, 1.234,
new String("hello"),
new String("Hi!").getBytes());
// convert a String to byte[] and append
nodeRef = myConn.createNodeReference("myListNode");
nodeRef.set(myList);
// Delete all elements from myList re-use it to create a different list
myList.clear();
// delete all elements from the list
myList.append(new String("world"), new Integer(7), new Double(3.1),new Long(9876543210L));
// Fetch the old list, then store the new list as a nested element in the old list
ValueList myNewList = nodeRef.getList();
// fetch previously created list
myNewList.append(myList);
// append the new list object as a single element
nodeRef.set(myNewList);
myList.close();
myNewList.close();
Connection.createList() メソッドは、myNewList という名前の ValueList の空のインスタンスを作成します。
append() の呼び出しによって、異なる型の 5 つの要素が追加され、set() が呼び出されて、ノード ^myListNode
にリストが格納されます。
Caché eXTreme での Java の使用法 63
グローバル API の使用法
clear() の呼び出しによって、myList インスタンスから既存の要素がすべて削除されるため、それを再利用でき
るようになり、append() の呼び出しによってリストに 4 つの新しい要素が追加されます。
NodeReference.getList() メソッドは、^myListNode に格納されているリストをフェッチし、それを myNewList とい
う ValueList の新しいインスタンスに割り当てます。myList オブジェクトは、6 番目の項目として myNewList に
追加され、更新されたリストは、再び永続ノード ^myListNode に格納されます。
この更新処理完了後、ValueList の両方のインスタンスは、close() メソッドの呼び出しによって破棄されます。
このセクションで後述する例は、^myListNode に格納されている ValueList をフェッチして読み取ります。
重要
常に close() を呼び出してメモリ・リークを回避
ValueList のインスタンスが範囲外になるか再使用される前に、これらのインスタンスで必ず close() を呼
び出すことが重要です。それらを閉じないと、深刻なメモリ・リークが発生することがあります。それは、
Java ガーベッジ・コレクションでは、基盤となる JNI ネイティブ・コードによって割り当てられたリソースを
解放できないためです。
4.6.2 ValueList 要素の読み取り
ValueList クラスは、既知のデータ型の要素値を、目的のデータ型の変数として返すメソッドを提供します。
数値要素の読み取り
以下のデータ型固有のメソッドを使用して、ValueList オブジェクトから数値要素を読み取ります。
•
getNextDouble() — リストから次の要素を double として返します。
•
getNextInt() — リストから次の要素を int として返します。
•
getNextLong() — リストから次の要素を long として返します。
リスト要素が null の場合、すべての数値メソッドが 0 を返します。
非数値要素の読み取り
以下のデータ型固有のメソッドを使用して、ValueList オブジェクトから非数値要素を読み取ります。
•
getNextString() — リストから次の要素を String として返します。
•
getNextBytes() — リストから次の要素を byte の配列として返します。
•
getNextList() — リストから次の要素を ValueList として返します。オプションの ValueList reuseList 引数を指定する
と、返されるリストが ValueList の新しいインスタンスに配置されるのではなく、指定した変数に割り当てられます。要
素が有効な ValueList でない場合、GlobalsException をスローします。
リスト要素が null の場合、これらのすべてのメソッドが null を返します。3 つのすべての非数値型 (String、byte[]、お
よび ValueList) は、データベースに文字列としてすべて格納されるため、getNextString() または getNextBytes() が誤っ
た非数値データ型に適用されても例外はスローされません。
既知のデータ型の ValueList 要素の読み取り
以下の例では、前の例で作成されたリストがノード ^myListNode からフェッチされ、リストの最初の 5 つの要素が読み出
され、出力されます。それらの 5 つの要素は int、long、double、String、および byte[] で、この順序であることがわかっ
ているため、データ型固有のメソッドを使用してそれらを読み取ることができます。
64 Caché eXTreme での Java の使用法
シリアル化された値リストの使用法
ValueList 要素の読み取り : int、long、double、String、および byte[] の読み取り
// Fetch the list from the database
nodeRef = myConn.createNodeReference("myListNode");
ValueList outList = nodeRef.getList();
// fetch list from node ^myListNode
// Read and print out each element in the list
System.out.println("
int value: " + outList.getNextInt());
System.out.println(" long value: " + outList.getNextLong());
System.out.println("double value: " + outList.getNextDouble());
System.out.println("String value: \"" + outList.getNextString() + "\"");
byte[] listBytes = outList.getNextBytes();
System.out.println("byte[] value: {" + listBytes[0]+","+listBytes[1]+","+listBytes[2]+"}");
NodeReference getList() メソッドを使用して、ノード ^myListNode から ValueList をフェッチします。
データ型固有のメソッドである getNextInt()、getNextLong()、getNextDouble()、getNextString() および
getNextBytes() は、それぞれ固有のデータ型として現在のリスト要素を読み取り、その後にカーソルをリストの次
の要素に進めます。
この例は以下の出力を生成します。
int
long
double
String
byte[]
value:
value:
value:
value:
value:
13
-4555666777
1.234
"hello"
{72,105,33}
リスト・カーソルの制御
ValueList を作成すると、それには、リストの最初の要素を指すリスト・カーソルが含まれます。読み取りメソッドの 1 つを
呼び出すごとに、現在の要素が返され、カーソルが次の要素に進みます。最後の要素が読み取られた後、新しい要素
が追加されるか resetToFirst() メソッドが呼び出されるまでカーソルは有効な要素を指しません。
以下のメソッドを使用して、カーソル位置を制御することもできます。
•
ValueList.length() — リストの要素数を返します。
•
ValueList.skipNext() — 値を取得せずに、リスト要素の指定数を過ぎたところまでカーソルを進めます。
•
ValueList.resetToFirst() — カーソルをリストの先頭にリセットします。
入れ子の ValueList の読み取り
前の例の終わりでは、カーソルはリストの最後の要素である入れ子の ValueList を指しています。次の例は、getNextList()
を使用して、入れ子のリストを返し、カーソルが新しいリストの最後の要素に移動され、その最後の要素が出力されます。
ValueList 要素の読み取り : 入れ子の ValueList の読み取り
// Reuse the ValueList object to get the nested ValueList
outList.getNextList(outList);
// re-use list object to store the nested list
outList.skipNext(outList.length()-1); // move cursor to last element in the new list
System.out.println("\nNested ValueList: last element is Long value " + outList.getNextLong());
getNextList() メソッドが呼び出されて、入れ子のリストを取得します。メイン・リストは必要なくなったため、それを
入れ子のリストの格納場所として指定することで outList オブジェクトを再利用します。outList の既存の内容
が、入れ子のリストによって置換されます。
コードで skipNext() および length() が使用されて、カーソルが新しいリストの最後の要素に移動され、その要素
の値が出力されて、以下の出力が生成されます。
Nested ValueList: last element is long value 9876543210
未知のデータ型の ValueList 要素の読み取り
以下のメソッドは、オブジェクトとして 1 つ以上のリスト要素を返します。
Caché eXTreme での Java の使用法 65
グローバル API の使用法
•
getAll() — リストからすべての要素を Object の配列として返します。このメソッドの呼び出し後は、リスト・カーソルは
リストの最後の要素の後に配置されます。
•
getNextObject() — リストから次の要素を Object として返します。
既定では、これらのメソッドのどちらも各オブジェクトを Integer、Long、Double、または String のインスタンスとして返しま
す。それらは、オプションの returnBytes パラメータが true に設定されている場合、byte[] のインスタンスとして文字列
を返します。
以下の例は、リストの各要素を Object として取得し、instanceof を使用してそのデータ型を特定し、その要素の型と
値を出力します。
ValueList 要素の読み取り : 未知のデータ型の要素の読み取り
System.out.println("Value in nested list:");
outList.resetToFirst();
for (int ii = 0; ii < outList.length(); ii++) {
Object item = outList.getNextObject();
if (item instanceof String)
System.out.println(" String: \""+(String)item+"\"");
else if (item instanceof Integer)
System.out.println("Integer: "+((Integer)item).intValue());
else if (item instanceof Long)
System.out.println("
Long: "+((Long)item).longValue()+"L");
else if (item instanceof Double)
System.out.println(" Double: "+((Double)item).doubleValue());
}
resetToFirst() メソッドはカーソルをリストの最初の項目の直前へ動かします。
getNextObject() メソッドは現在の項目を Object として返し、カーソルを次の項目へ進めます。
この例は、以下の出力を生成します。
Value in
String:
Integer:
Double:
Long:
nested list:
"world"
7
3.1
9876543210L
4.7 複数のグローバル配列へのアクセス
この章のほとんどの例は、1 つのネームスペースの 1 つのグローバル配列に対してのみ動作します。これらの例では、
ネームスペースは接続が作成されるときに指定され、グローバル名はノード参照が作成されるときに定義されます。この
セクションでは、アプリケーションが、ノード参照によってアクセスされるグローバル配列を指定し、指定されたネームス
ペースですべてのグローバル配列名のリストを参照し、接続によってアクセスされるネームスペースを変更できるようにす
るメソッドについて説明します。以下の項目について説明します。
•
グローバル名へのアクセス — NodeReference のインスタンスがどのグローバル配列にアクセスするのかを変更する
方法について説明します。
•
グローバル配列のディレクトリの使用法 — GlobalsDirectory クラスを使用して、指定されたネームスペースですべて
のグローバル配列名のリストを参照する方法について説明します。
•
ネームスペースへのアクセス — 接続のネームスペース・プロパティの読み取りおよび変更方法について説明します。
4.7.1 グローバル名へのアクセス
setName() および getName() メソッドは、次のようにノード参照のグローバル名プロパティにアクセスする方法を提供しま
す。
66 Caché eXTreme での Java の使用法
複数のグローバル配列へのアクセス
•
setName() — ノード参照のグローバル名プロパティを設定または変更し、NodeReference の 1 つのインスタンスで
現在のネームスペースの任意のグローバル配列を作成するか、またはその配列にアクセスできるようにします。グ
ローバル名は、特定のルールに従う必要がある String です (“グローバル配列の名前付け規約” を参照してくだ
さい)。
•
getName() — 現在のグローバル名を含む String を返します。
グローバル名プロパティにおける変更は、添え字リスト・プロパティには影響しません。現在の添え字リストが変更される
まで、ノード参照はこのリストの使用を続行します (“ターゲット・アドレスの設定” を参照)。以下の例は、NodeReference
の 1 つのインスタンスを使用して、2 つのグローバル配列を作成します。最初の配列を作成した後、ノード参照オブジェ
クト nodeRef の添え字リストには、添え字 "a" が含まれます。2 番目の配列が作成されるときにグローバル名およびノー
ド値が変更されても、添え字リストは変更されません。
グローバル名へのアクセス : 既存の添え字を持つ配列の新規作成
nodeRef = myConn.createNodeReference("myGlobal");
nodeRef.appendSubscript("a");
nodeRef.set("new node"); // create ^myGlobal("a")
nodeRef.setName("mySecondGlobal");
nodeRef.set("second node"); // create ^mySecondGlobal("a")
ノード参照オブジェクト NodeRef は、作成されたときはルート・ノード ^myGlobal を指しています。添え字が追加
され、set() が呼び出されて永続ノード ^myGlobal("a") を含む新しいグローバル配列が作成されます。
setName() を呼び出すと、配列名が ^mySecondGlobal に変更されますが、NodeRef の添え字リストは変更され
ません。したがって、set() の次の呼び出しによって、永続ノード ^mySecondGlobal("a") を含む 2 番目のグロー
バル配列が作成されます。
同じグローバル配列の異なる部分にアクセスする NodeReference の複数のインスタンスを作成すると便利な場合があり
ます。以下の例では、getName() メソッドを使用して、2 つの異なるインスタンスに同じグローバル名を指定します。
グローバル名へのアクセス : 2 つのノード参照オブジェクトを使用して同じグローバル配列にアクセス
NodeReference firstNodeRef = myConn.createNodeReference("myGlobal");
NodeReference secondNodeRef = myConn.createNodeReference(firstNodeRef.getName());
firstNodeRef.set("level zero"); // create ^myGlobal
firstNodeRef.appendSubscript("a");
firstNodeRef.set("level one"); // create ^myGlobal("a")
System.out.println("firstNodeRef=\"" + firstNodeRef.getString()
+ "\", secondNodeRef=\"" + secondNodeRef.getString() + "\"");
// Prints: firstNodeRef="level one", secondNodeRef="level zero"
createNodeReference() の最初の呼び出しによって、グローバル名 "myGlobal" が firstNodeRef に割り当てら
れます。secondNodeRef オブジェクトが作成されるとき、getName() が使用されて、firstNodeRef と同じグローバ
ル名が割り当てられます。
firstNodeRef オブジェクトが使用されて、2 つの永続ノードを含むグローバル配列が作成されます。2 番目のノー
ドが作成された後、firstNodeRef は、^myGlobal("a") を指します。secondNodeRef のアドレスは、変更されなかっ
たため、それはルート・ノード ^myGlobal を指したままです。
4.7.2 グローバル配列のディレクトリの使用法
このセクションでは、GlobalsDirectory クラスのメソッドを使用して、指定されたネームスペースですべてのグローバル配
列名のリストを参照する方法について説明します。GlobalsDirectory のインスタンスが Connection.createGlobalsDirectory()
によって作成されます。createGlobalsDirectory() が呼び出されたときに、データベースへの接続がない場合、
GlobalsException がスローされます。
以下の GlobalsDirectory メソッドについて説明します。
•
nextGlobalName() — 照合の昇順で次のグローバル名を取得します。
Caché eXTreme での Java の使用法 67
グローバル API の使用法
•
previousGlobalName() — 照合の降順で次のグローバル名を取得します。
•
refresh() — ディレクトリを更新し、オブジェクト作成または最新の更新後のすべての追加または削除を反映します。
•
close() — オブジェクトが破棄される際のリソース・リークを回避するために、オブジェクトの基本となるリソースを解放
します。
重要
常に close() を呼び出してメモリ・リークを回避
GlobalsDirectory のインスタンスが範囲外になるか再使用される前に、これらのインスタンスで必ず close()
を呼び出すことが重要です。それらを閉じないと、深刻なメモリ・リークが発生することがあります。それ
は、Java ガーベッジ・コレクションでは、基盤となる JNI ネイティブ・コードによって割り当てられたリソー
スを解放できないためです。
nextGlobalName() と previousGlobalName() の両方とも、検索の開始場所を指定するオプションの String 引数を取るこ
とができます。文字列が指定されない場合、検索は、ディレクトリ・リストの最初からまたは最後に検出されたグローバル
名から開始されます。両方のメソッドとも、グローバル配列名がこれ以上見つからない場合、空の文字列を返します。こ
の反復手法は、グローバル配列のノードに対する反復に使用するメソッドについて前述したものと同じです (“開始ポイ
ントと反復処理の順序の制御” を参照してください)。
ディレクトリ・リストの参照
このセクションには、GlobalsDirectory を使用する 2 つの例が用意されています。両方の例ともに、ディレクトリ・リストを
スキャンし、"myArray" で始まる任意のグローバル名を出力します。最初の例は、テスト・データを作成し、ネームスペー
スのコンテンツを降順で読み取ります。2 番目の例は、同じネームスペース内のグローバル配列の追加および削除を行
い、変更されたネームスペースのコンテンツを昇順で読み取ります。これらの例は、以下の結合された出力を生成しま
す。
List in descending order after creating ^myArray1 and ^myArray2
^myArray2
^myArray1
List in ascending order after killing ^myArray1, adding ^myArray3, and refreshing
^myArray2
^myArray3
注釈
管理ポータルは、ネームスペースにグローバル配列の現在のリストを表示でき、また配列に各ノードの値を表
示できます。[システム・エクスプローラ] > [グローバル] に移動して、左側に表示されているリストからネームス
ペースを選択します。
以下の例は、照合の降順でディレクトリ・リスト全体を読み取り、"myArray" で始まるすべてのグローバル名を出力しま
す。
グローバル配列のディレクトリの使用法 : リストを作成し、降順で参照
nodeRef.setName("myArray1");
nodeRef.set("");
nodeRef.setName("myArray2");
nodeRef.set("");
System.out.println("List in descending order after creating ^myArray1 and ^myArray2");
GlobalsDirectory globDir = myConn.createGlobalsDirectory();
String globname = "n"; // Start above 'myArray' and descend.
while (!globname.equals("")) {
if (globname.startsWith("myArray")) System.out.println(" ^" + globname);
globname = globDir.previousGlobalName();
};
2 つのグローバル配列、^myArray1 と ^myArray2 が現在のネームスペースに作成されます。set() によって
新しいノードが作成される前に、NodeReference.setName() メソッド (前に “グローバル名へのアクセス” で説
明) が、各グローバル名を指定します。
Connection.createGlobalsDirectory() メソッドを使用して、GlobalsDirectory オブジェクト globDir を作成します。
照合順で最初の可能な項目の直前にカーソルを配置することから始めます。
68 Caché eXTreme での Java の使用法
複数のグローバル配列へのアクセス
previousGlobalName() の最初の呼び出しによって、カーソルが "n" (照合順で "myArray" より後) に配置さ
れます。ループで、previousGlobalName() のそれぞれの呼び出しによって、次のグローバル名が降順で返され
ます。標準 Java startsWith() メソッドを使用して、必ず "myArray" で始まるグローバル名のみが出力されるよ
うにします。
前の例の処理が完了した後、以下の例は、User ネームスペースのコンテンツを変更してからこれを再読み取りします。
^myArray1 が削除され、^myArray3 が作成され、ディレクトリ・リストが更新され、"myArray" で始まる名前がリストの
先頭から昇順で出力されます。
グローバル配列のディレクトリの使用法 : リストを更新し、昇順で参照
nodeRef.setName("myArray1");
nodeRef.kill();
nodeRef.setName("myArray3");
nodeRef.set("");
globDir.refresh();
System.out.println("\nList in ascending order after killing " +
"^myArray1, adding ^myArray3, and refreshing");
globname = globDir.nextGlobalName(""); // Start before first name and ascend.
while (!globname.equals("")) {
if (globname.startsWith("myArray")) System.out.println(" ^" + globname);
globname = globDir.nextGlobalName();
};
globDir.close();
グローバル配列 ^myArray1 が削除され、^myArray3 が作成され、refresh() が呼び出されてディレクトリ・リス
トが更新されます。
nextGlobalName() の最初の呼び出しによって、空の文字列 ("") を指定して、照合順で最初の名前の前にカー
ソルが設定されます。ループで、nextGlobalName() のそれぞれの呼び出しによって、次のグローバル名が昇順
で返されます。"myArray" で始まる 2 つのグローバル名が出力されます。
close() の呼び出しによって、globDir が破棄され、関連付けられたすべてのリソースが解放されます。
4.7.3 ネームスペースへのアクセス
Caché ネームスペースは、物理データベースの論理ビューです。インストール済みの Caché インスタンスそれぞれに複
数のネームスペースの定義が含まれています ("Caché システム管理ガイド" の “ネームスペースの構成” を参照)。グ
ローバル API は、GLOBALS_HOME 環境変数 (“すべてのプラットフォームに対して必須の環境変数” を参照) によっ
て指定された Caché インスタンスの使用可能なネームスペースのデータにアクセスできます。ネームスペースが別のマ
シンのデータベースにマップされている場合、そのデータベースにアクセスできます。このような場合、アクセス速度は、
データベースへの物理接続によって制限されます (ローカル・ハードウェアへの直接アクセスではなく ECP を介したアク
セス)。
以下の Connection メソッドを使用して、接続オブジェクトのネームスペース参照を読み取り、変更します。
•
setNamespace() — 基礎となる eXTreme 接続によってアクセスされるネームスペースを設定します。
•
getNamespace() — 現在のネームスペース文字列を返します。
以下の例では、データベースに接続されているかどうかにかかわらず、接続オブジェクト myConn が既に存在している
ことを想定しています。このコードは、接続をテストし、User ネームスペースに接続されていることを確認します。
ネームスペースへのアクセス : ネームスペースへの接続のテスト
if(!myConn.isConnected()) myConn.connect("User","_SYSTEM", "SYS");
else if (!myConn.getNamespace().equals("User")) {
System.out.print("Switching connection from \"" + myConn.getNamespace());
myConn.setNamespace("User");
System.out.println("\" to \"" + myConn.getNamespace() + "\".");
// Prints: Switching connection from "[current namespace]" to "User".
}
Caché eXTreme での Java の使用法 69
グローバル API の使用法
isConnected() の呼び出しによって、myConn がデータベースに接続されているかどうかがチェックされます。接
続されていない場合、connect() が User ネームスペースと関連付けられたデータベースに接続します。それ以
外の場合、GetNamespace() が、現在のネームスペース名を返します。必要に応じて、setNamespace() を呼び
出し、User に切り替えます。
注釈
この呼び出しは、基礎となる eXTreme 接続に対して動作するため、このプロセスの各 Connection 変数は、
User ネームスペースにアクセスするようになります (“グローバル API を他の eXTreme API と共に使用する方
法” の説明のように、これには同じプロセス内で実行されている eXTreme XDO および XEP 接続も含まれま
す)。基礎となる eXTreme 接続の動作方法の説明は、“接続の作成” を参照してください。
4.8 トランザクションとロック
このセクションで説明する項目は以下のとおりです。
•
トランザクションの制御 — トランザクションを処理するための Connection クラスのメソッドの使用法について説明し
ます。
•
ロックの取得および解放 — さまざまなロック・メソッドの使用法について説明します。
•
トランザクションでのロックの使用 — トランザクション内のロックの例を提供します。
4.8.1 トランザクションの制御
Connection クラスには、トランザクションを制御するために以下のメソッドが用意されています。
•
commit() — 1 レベルのトランザクションをコミットします。
•
startTransaction() — トランザクション (入れ子になったトランザクションの場合あり) を開始します。
•
transactionLevel() — 現在のトランザクション・レベル (トランザクション内でない場合は 0) を示す int 値を返します。
•
rollback() — 指定された数のトランザクション・レベルをロールバックするか、数が指定されていない場合、すべての
レベルのトランザクションをロールバックします。
以下の例では、3 レベルの入れ子のトランザクションを開始し、各トランザクション・レベルに異なるノードの値を設定しま
す。3 つのノードはすべて出力され、それらに値があることが証明されます。その後、この例では、2 番目と 3 番目のレ
ベルがロール・バックされ、最初のレベルがコミットされます。3 つのノードはすべて再び出力され、依然として値がある
のは最初のノードのみであることが証明されます。
トランザクションの制御 : 3 レベルの入れ子トランザクションの使用法
NodeReference nodeRef = myConn.createNodeReference("myGlobal");
myConn.startTransaction();
nodeRef.set("firstValue", myConn.transactionLevel());
// transactionLevel() is 1 and ^myGlobal(1) = "firstValue"
myConn.startTransaction();
nodeRef.set("secondValue", myConn.transactionLevel());
// transactionLevel() is 2 and ^myGlobal(2) = "secondValue"
myConn.startTransaction();
nodeRef.set("thirdValue", myConn.transactionLevel());
// transactionLevel() is 3 and ^myGlobal(3) = "thirdValue"
System.out.println("Node values before rollback and commit:");
for (int ii=1;ii<4;ii++) {
System.out.print("^myGlobal(" + ii + ") = ");
if (nodeRef.exists(ii)) System.out.println(nodeRef.getString(ii));
else System.out.println("<valueless>");
}
// prints: Node values before rollback and commit:
70 Caché eXTreme での Java の使用法
トランザクションとロック
//
//
//
^myGlobal(1) = firstValue
^myGlobal(2) = secondValue
^myGlobal(3) = thirdValue
myConn.rollback(2); // roll back 2 levels to transactionLevel 1
myConn.commit(); // transactionLevel() after commit will be 0
System.out.println("Node values after the transaction is committed:");
for (int ii=1;ii<4;ii++) {
System.out.print("^myGlobal(" + ii + ") = ");
if (nodeRef.exists(ii)) System.out.println(nodeRef.getString(ii));
else System.out.println("<valueless>");
}
// prints: Node values after the transaction is committed:
//
^myGlobal(1) = firstValue
//
^myGlobal(2) = <valueless>
//
^myGlobal(3) = <valueless>
4.8.2 ロックの取得および解放
NodeReference の以下のメソッドを使用して、ロックを取得および解放します。どちらのメソッドも lockType 引数を取っ
て、ロックが共有であるか排他であるかを指定します。
•
acquireLock() — lockType、lockMode、およびオプションの subscripts 引数を取り、ノードをロックします。lockMode
引数は、前に保持されたロックを解放するかどうかを指定します。このメソッドは、ロックを取得できない場合、事前に
定義した間隔 (“タイムアウト間隔の制御” を参照) 後にタイムアウトになります。
•
releaseLock() — lockType、releaseMode、およびオプションの subscripts 引数を取り、ノードのロックを解除します。
releaseMode 引数は、ロックをすぐに解放するかトランザクションの最後に解放するかを指定します。
Connection メソッドの close() または releaseAllLocks() (“トランザクションでのロックの使用” を参照) は、現在保持
されているロックをすべて解放します。
以下の引数値を使用できます。
•
•
•
•
lockType — acquireLock() と releaseLock() のどちらも、以下の値を使用して、ロックが共有であるか排他であるかを
指定します。
–
NodeReference.SHARED_LOCK — 共有ロックは、他の呼び出し元がノードの共有ロックを取得することは許可
しますが、どの呼び出し元もそのノードの排他ロックを取得できないようにします。ノード値は、すべての共有ロッ
クが解放されるまで変更できません。
–
NodeReference.EXCLUSIVE_LOCK — 排他ロックは、他の呼び出し元がそのノードのロックを取得できないよう
にし、そのノード値の安全な変更を可能にします。
lockMode — acquireLock() は、以下の値を使用して、前に取得されたロックを解放するかどうかを指定します。
–
NodeReference.LOCK_INCREMENTALLY — 増分ロックは、以前から保持されているロックを解放しません。
–
NodeReference.LOCK_NON_INCREMENTALLY — 増分でないロックは、以前から保持されているロックをすべ
て解放します。
releaseMode — releaseLock() は、以下の値を使用して、ロックを解放するタイミングを指定します。
–
NodeReference.RELEASE_IMMEDIATELY — すぐにロックを解放します。
–
NodeReference.RELEASE_AT_TRANSACTION_END — 現在のトランザクションが終了するまで待ってからロッ
クを解放します。
subscripts — acquireLock() と releaseLock() のどちらも、オプションの添え字引数を取り、ターゲット・ノードのサブ
ノードをロックまたは解放できます (“ターゲットのサブノードのアドレス指定” を参照してください)。
以下の例は、ノード ^myGlobal("a",1) をロックおよび解放します。nodeRef のターゲット・アドレスは ^myGlobal であ
るため、どちらのメソッドも subscript 引数を使用してサブノードを指定します。
Caché eXTreme での Java の使用法 71
グローバル API の使用法
ロックの取得および解放 : ノードのロックと解放
nodeRef.acquireLock(NodeReference.SHARED_LOCK, NodeReference.LOCK_INCREMENTALLY,"a",1);
// perform transaction on locked node here...
nodeRef.releaseLock(NodeReference.SHARED_LOCK, NodeReference.RELEASE_IMMEDIATELY,"a",1);
注釈
管理ポータルを使用して、ロックを検証できます。[システム処理] > [ロック] に移動して、システムでロックされ
ている項目のリストを表示します。
4.8.2.1 タイムアウト間隔の制御
NodeReference オブジェクトは、タイムアウトになり LockException がスローされるまでに acquireLock() メソッドがロック
の取得を待機する時間を指定する内部 timeout 設定を管理します。既定の間隔は 10 秒です。
•
getOption() — option 引数を取り、現在のロック・タイムアウト間隔を秒単位で返します。
•
setOption() — option および value 引数を取り、タイムアウトになるまで acquireLock() がロックを待機する秒数を設
定します。
以下の引数値を使用できます。
•
option — getOption() と setOption() の両方で使用されます。現在、有効な引数値は NodeReference.LOCK_TIMEOUT
のみです。
•
value — setOption() のタイムアウト値を指定する int。任意の int 値を指定できます。また、以下の事前定義された
値も使用できます。
–
NodeReference.DEFAULT_LOCK_TIMEOUT — 既定値は 10 です。
–
NodeReference.NO_LOCK_TIMEOUT — 値は -1 です。これは、呼び出しがタイムアウトにならないことを指定
します (acquireLock() は永久に待機します)。
以下の例は、タイムアウト間隔を読み取り、それが 5 未満である場合は 5 秒に設定します。
ロックの取得および解放 : タイムアウト間隔の制御
if (nodeRef.getOption(NodeReference.LOCK_TIMEOUT)<5) {
nodeRef.setOption(NodeReference.LOCK_TIMEOUT, 5);
}
4.8.3 トランザクションでのロックの使用
このセクションでは、前に説明したメソッドを使用して、トランザクション内での増分ロックについて説明します (“トランザ
クションの制御” および “ロックの取得および解放” を参照してください)。管理ポータルを開き、[ホーム] > [ロック] に
移動することによって、システムのロックされた項目のリストを表示できます。以下のコードの read(pressEnter) の呼び出
しによって、実行が一時停止され、リストが変更されるたびにリストを調べることができます。
以下の Connection メソッドは、現在保持されているロックをすべて解放します。
•
releaseAllLocks() — この接続で現在保持されているロックをすべて解放します。
•
close() — 接続を閉じる前に、すべてのロックおよび他の接続リソースを解放します。
トランザクションでのロックの使用 : 増分ロックの使用法
byte[] pressEnter = new byte[4];
NodeReference nodeRef1 = myConn.createNodeReference("nodeRef1");
nodeRef1.appendSubscript("my-node");
NodeReference nodeRef2 = myConn.createNodeReference("nodeRef2");
nodeRef2.appendSubscript("shared-node");
try {
72 Caché eXTreme での Java の使用法
Caché メソッドの呼び出し
myConn.startTransaction();
// lock ^nodeRef1("my-node") exclusively
nodeRef1.acquireLock(NodeReference.EXCLUSIVE_LOCK, NodeReference.LOCK_INCREMENTALLY);
// lock ^nodeRef2 shared
nodeRef2.acquireLock(NodeReference.SHARED_LOCK, NodeReference.LOCK_INCREMENTALLY);
System.out.println("Exclusive lock on ^nodeRef1(\"my-node\") and shared lock on ^nodeRef2");
System.out.println("Press return to release locks individually");
System.in.read(pressEnter); // Wait for user to press Return
// release ^nodeRef1("my-node") after transaction
nodeRef1.releaseLock(NodeReference.EXCLUSIVE_LOCK, NodeReference.RELEASE_AT_TRANSACTION_END);
// release ^nodeRef2 immediately
nodeRef2.releaseLock(NodeReference.SHARED_LOCK, NodeReference.RELEASE_IMMEDIATELY);
System.out.println("Press return to commit transaction");
System.in.read(pressEnter);
myConn.commit();
}
catch (LockException e) { System.out.println(e.getMessage()); }
catch (java.io.IOException e) { System.out.println(e.getMessage()); }
以下の例は、増分でないロックを示します。
トランザクションでのロックの使用 : 増分でないロックの使用法
// lock ^nodeRef1("my-node") non-incremental
nodeRef1.acquireLock(NodeReference.EXCLUSIVE_LOCK, NodeReference.LOCK_NON_INCREMENTALLY);
System.out.println("Exclusive lock on ^nodeRef1(\"my-node\"), return to lock ^lockRef2
non-incrementally");
System.in.read(pressEnter);
// lock ^nodeRef2 shared non-incremental
nodeRef2.acquireLock(NodeReference.SHARED_LOCK, NodeReference.LOCK_NON_INCREMENTALLY);
System.out.println("Verify that only ^nodeRef2 is now locked, then press return");
System.in.read(pressEnter);
以下の例は、すべての増分ロックの解放を示します。
トランザクションでのロックの使用 : すべての増分ロックを解放するための releaseAllLocks() の使用法
// lock ^nodeRef1("my-node") shared incremental
nodeRef1.acquireLock(NodeReference.SHARED_LOCK, NodeReference.LOCK_INCREMENTALLY);
// lock ^nodeRef2 exclusive incremental
nodeRef2.acquireLock(NodeReference.EXCLUSIVE_LOCK, NodeReference.LOCK_INCREMENTALLY);
System.out.println("Two locks are held (one with lock count 2), return to release both locks");
System.in.read(pressEnter);
myConn.releaseAllLocks();
System.out.println("Verify both locks have been released");
System.in.read(pressEnter);
4.9 Caché メソッドの呼び出し
以下の Connection メソッドは、Caché ObjectScript クラス・メソッドを呼び出します。
•
callClassMethod() — 指定した Caché ObjectScript クラス・メソッドを呼び出します。className および methodName
に対して String 引数を取り、ほかに Caché メソッドに渡される 0 個以上の引数を取ります。String、int、long、また
は double のインスタンスになる Object として Caché メソッド返り値を返します。
•
callBytesClassMethod() — 文字列値が byte[] として返されること以外は callClassMethod() と同一です。
•
callVoidClassMethod() — 指定した Caché ObjectScript void クラス・メソッドを呼び出します。className および
methodName に対して String 引数を取り、ほかに Caché メソッドに渡される 0 個以上の引数を取ります。
Caché eXTreme での Java の使用法 73
グローバル API の使用法
以下の Connection メソッドは Caché 関数およびプロシージャを呼び出します (Caché ObjectScript の使用法 の “ユー
ザ定義コード” を参照してください)。
•
callFunction() — 指定した Caché ObjectScript 関数を呼び出します。functionName および routineName に対して
String 引数を取り、ほかに Caché メソッドに渡される 0 個以上の引数を取ります。String、int、long、または double
のインスタンスになる Object として Caché 関数の返り値を返します。
•
callBytesFunction() — 文字列値が byte[] として返されること以外は callFunction() と同一です。
•
callProcedure() — 指定した Caché ObjectScript プロシージャを呼び出します。procedureName および routineName
に対して String 引数を取り、ほかに Caché メソッドに渡される 0 個以上の引数を取ります。
4.10 グローバル API の要件と規約
このセクションで説明する項目は以下のとおりです。
•
グローバル配列の名前付け規約 — グローバル配列および添え字の名前付けに関するルールについて詳しく説明
します。
•
グローバル API を他の eXTreme API と共に使用する方法 — グローバル API、XEP、および XDO を同じアプリケー
ションで使用する方法について説明します。
•
複数レベルのグローバル配列のノード順序の理解 — 多次元のグローバル配列の構造がこのグローバル配列の検
索順序にどのように影響するかを説明します。
•
スレッド・セーフに関する考慮事項 — マルチスレッドを安全に使用するための最適な方法について説明します。
4.10.1 グローバル配列の名前付け規約
このセクションでは、標準の Caché グローバルの名前付け規約がどのようにグローバル API に適用されるかについて説
明します。同じ規約が Caché ObjectScript でどのように適用されるかに関する詳細は、"Caché グローバルの使用法"
の “グローバルの論理構造” を参照してください。
グローバル名は、以下のルールに従う必要があります。
•
グローバル名には Unicode 文字を使用できません。
•
グローバル名の先頭文字は、文字またはパーセント文字 (%) とします。パーセント文字は、最初の文字とし
てのみ使用でき、ほとんどの場合、回避する必要があります ("Caché プログラミング入門ガイド" の “回避
する必要があるグローバル変数名” を参照)。
•
上記以外のグローバル名には、文字、数字、またはピリオド記号 (.) を使用できます。またピリオド記号は、
グローバル名の最初または最後の文字としては使用できません。
•
グローバル名は、大文字と小文字が区別され、最長 31 文字で構成されます。非常に長いグローバル名を
指定することはできますが、余分な文字は無視されます。
添え字識別子は、以下のルールに従う必要があります。
•
添え字識別子は、int、long、double、または String にできます。
•
数値識別子は、数字が引用符で囲まれていない限り、キャノニック形式に変換されます。例えば、先頭お
よび末尾の 0 は、double 値 00123.10 から削除されます。ただし、同じ数値が引用符付き数値文字列
("00123.10") として指定されている場合、0 は保持され、値は、数字ではなく文字列として照合されます。
74 Caché eXTreme での Java の使用法
グローバル API の要件と規約
•
文字列識別子は、大文字と小文字が区別され、空の文字列 ("") 以外の任意の文字列にできます。空白、
出力不能文字、Unicode 文字など全種類の文字を使用できます。
•
添え字数に固定の制限はありませんが、ノード・アドレス (グローバル名とそのすべての添え字) は、1023
バイトに制限されます。添え字内の Unicode 文字は、2 バイト以上にカウントされます ("Caché グローバル
の使用法" の “添え字の最大長の決定” を参照)。
4.10.2 グローバル API を他の eXTreme API と共に使用する方法
XDO、XEP、および eXTreme JDBC API は、グローバル API と同じアプリケーションで使用でき、オブジェクト・アクセス
および SQL を同じトランザクション・コンテキストの一部にすることができます。すべての eXTreme API には、インストー
ルと構成に関して共通の要件があります (“インストールと構成” を参照)。
これらの API はすべて、同じ基礎となる接続を使用しますが、それぞれの API では、Caché との接続および接続切断
に使用する手法はまちまちです。以下のルールは、同じアプリケーションでこれらの API を複数使用するときに適用さ
れます。
•
接続を開く
既に eXTreme JDBC 接続を開いている場合は、グローバル 接続を明示的に開かないでグローバル API を使用で
きます。グローバル・コードを JDBC 接続に依存しないようにする場合は、JDBC 接続を開く前でも後でも、
Connection.connect() を呼び出して、グローバルに明示的に接続できます。両方の接続で同じネームスペースを指
定する必要があります。そうしないと例外がスローされます。
•
ネームスペースの変更
別の eXTreme API も使用するグローバル・アプリケーションでは、Connection.setNamespace() を呼び出すと、すべ
ての API に対して有効なネームスペースが変更されます。その後の SQL 文または eXTreme API 呼び出しは、新
しいネームスペースに対して動作し、古いネームスペースにのみ存在するリソースを使用しようとすると失敗する場
合があります。eXTreme JDBC 接続は、setNamespace() を呼び出した後は開けません。同じネームスペースがその
接続に指定されている場合でも同様です。
•
接続を閉じる
明示的に開いた接続はすべて、明示的に閉じる必要があります。グローバルと JDBC の接続は Connection.close()
を呼び出して閉じます。XDO 接続は DatabaseConnection.disconnect() を呼び出して閉じます。これらは任意の順
序で呼び出せますが、最後の関数が呼び出されるまでは、基礎となる接続は閉じません (また関連付けられている
リソースは解放されません)。
4.10.3 複数レベルのグローバル配列での照合順
グローバル配列のノードは、順番または階層順に追加する必要はありませんが、グローバル配列は本質的にツリー構造
であるため、永続ノードが追加されるときには必ず階層が自動的に生成されます。例えば、グローバル配列に 3 つの永
続ノード (^myGlobal("a",”23”)、^myGlobal("a"," x")、および ^myGlobal("b")) が含まれているとします。これらの添え字
リストは任意で、これらのノードは任意の順序で配列に追加できます。ただし、この配列のポインタ構造には、最初の 2
つの永続ノードの親と 3 番目の永続ノードの兄弟である 2 つの値なしノード (ルート・ノード ^myGlobal、およびレベル 1
ノード ^myGlobal("a")) も含まれている必要があります。これらのノードは、以下の階層を作成します。
^myGlobal
^myGlobal("a")
^myGlobal("a","23") = value
^myGlobal("a"," x") = value
^myGlobal("b") = value
(valueless root node)
(valueless level 1 node)
(second subscript contains a space character!)
この例で示すように、階層は、ノード・レベルおよび各レベルの添え字の照合順序に基づいています。
物理データベースでは、値が子ノードのいずれかに割り当てられるときに、値なしノード ^myGlobal および ^myGlobal("a")
が自動的に作成されます。値なしノードは、ポインタ構造の一部としてのみ存在し、データには追加スペースは割り当て
Caché eXTreme での Java の使用法 75
グローバル API の使用法
られません。値なしノードから値を読み取ろうとすると例外がスローされますが、それでも値なしノードをグローバルの反
復メソッドで使用し、配列を検索できます。
同じ親の下の子ノードは、添え字ごとに 照合順序 (最初に数値、次に英字文字列) で並べられます。例えば、レベル 1
ノードの以下のリストは照合順になっています。
Caché データベースの照合順序
^myGlobal("-23.1")
^myGlobal("99")
^myGlobal(" ")
^myGlobal(" 22")
^myGlobal("0123")
^myGlobal("11 ")
^myGlobal("23-2")
(subscript is a string containing a numeric value)
(subscript is a string containing only digits)
(subscript is a space character)
(subscript starts with a space)
(subscript contains a leading zero)
(subscript contains a trailing space)
(subscript is a numeric expression, not a value)
最初の 2 つの添え字は数値であるため、すべての英字添え字の前に配置されます。空白文字 (" ") は、このリストの
最初の英字添え字です。照合順序の詳細は、"Caché グローバルの使用法" の “グローバルでのデータのソート” を参
照してください。
4.10.4 スレッド・セーフに関する考慮事項
グローバル API クラスの個別のインスタンスは、スレッドセーフな方法で複数のスレッドで並行して使用できます。グロー
バル API クラスの個々のインスタンスは、スレッドセーフではありません。それらのメソッドのいくつかはメソッド呼び出し
間で維持されるようにそれらの状態を変更するため、1 つのスレッド内のメソッド呼び出しの同じシーケンスで、そのシー
ケンス中に別のスレッドによって同じインスタンスのメソッドが呼び出されたかどうかに応じて、結果が異なることがありま
す。例えば、別のスレッドでの NodeReference.appendSubscript() の呼び出しより、 NodeReference インスタンスによっ
てどのノードが参照されるのかが変更され、それにより NodeReference.set() が呼び出され、意図したものとは異なるノー
ドの値が設定される可能性があります。
単一 Connection インスタンスは、以下の注意事項により複数のスレッドで安全に使用できます。
•
トランザクション・メソッド startTransaction()、commit()、および rollback()、および releaseAllLocks() は、すべてのス
レッドに対して Connection のトランザクションおよびロック状態に影響を与えます。
•
Connection.setNamespace() は、すべてのスレッドに対して現在のネームスペースを変更します。同じアプリケーショ
ン内にアクティブな XEP EventPersister がある場合、その現在のネームスペースも、setNamespace() の呼び出し
によって変更されます。
•
Connection.close() は、すべてのスレッドに対して接続を閉じます。connect() 以外の Connection インスタンスに対
する後続のメソッド呼び出しでは、それらを呼び出す前に connect() を呼び出す必要があることを示す例外がスロー
されます。
76 Caché eXTreme での Java の使用法
5
eXTreme クラスのクイック・リファレンス
この章は、以下の Caché eXTreme API を理解するために最も重要なクラスのクイック・リファレンスです。
•
XEP クイック・リファレンス
com.intersys.xep パッケージには、"eXTreme Event Persistence の使用法" で説明されているパブリック API が含
まれています。
•
XDO クイック・リファレンス
com.intersys.xdo パッケージには、"eXTreme ダイナミック・オブジェクトの使用法" で説明されているパブリック API
が含まれています。
•
グローバル API のクイック・リファレンス
com.intersys.globals パッケージには、"グローバル API の使用法" で説明されているパブリック API が含まれてい
ます。
注釈
これは、これらの API の最終的なリファレンスではありません。最も完全な最新の情報は、
<cache-root>/dev/java/doc/index.html にある "JavaDoc for the InterSystems Java Connectivity API" を参
照してください。
5.1 XEP クイック・リファレンス
このセクションは、XEP API (eXTreme Event Persistence — ネームスペース com.intersys.xep) のリファレンスです。この
API の使用法の詳細は、"eXTreme Event Persistence の使用法" を参照してください。これには、以下のクラスおよびイ
ンタフェースが含まれています。
•
クラス PersisterFactory — EventPersister オブジェクトを作成するために必要なファクトリ・メソッドを提供します。
•
クラス EventPersister — XEP データベース接続をカプセル化します。また、XEP オプションの設定、XEP 接続の確
立または既存の接続オブジェクトの取得、スキーマのインポート、XEP イベント・オブジェクトの作成、サーバ上の
Caché 関数およびメソッドの呼び出し、トランザクションの制御を行うメソッドを提供します。
•
クラス Event — XEP 永続イベントへの参照をカプセル化します。また、イベントの格納または削除、クエリの作成、イ
ンデックス作成の開始または停止を行うメソッドを提供します。
•
クラス EventQuery<> — 更新または削除するためにデータベースから特定のタイプの個別のイベントを取得するク
エリをカプセル化します。
Caché eXTreme での Java の使用法 77
eXTreme クラスのクイック・リファレンス
•
クラス EventQueryIterator<> — Java Iterator のメソッドに類似したメソッドを使用して XEP イベントの取得、更新お
よび削除を行う EventQuery<> の代替手段を提供します。
•
インタフェース InterfaceResolver — フィールドがインタフェースとして宣言された場合、フラット・スキーマのインポー
ト中にフィールドの実際のデータ型を解決します。
•
クラス XEPException — ほとんどの XEP メソッドによってスローされる例外です。
5.1.1 XEP メソッドのリスト
このリファレンスでは、以下の XEP API のクラスおよびメソッドを説明します。
PersisterFactory
•
createPersister() — 新しい EventPersister オブジェクトを作成します。
EventPersister
•
callClassMethod() — Caché クラス・メソッドを呼び出します。
•
callFunction() — Caché 関数を呼び出します。
•
callProcedure() — Caché プロシージャを呼び出します。
•
callVoidClassMethod() — 返り値のない Caché クラス・メソッドを呼び出します。
•
close() — このインスタンスで保持されているすべてのリソースを解放します。
•
commit() — 1 レベルのトランザクションをコミットします。
•
connect() — 指定された引数を使用して Caché に接続します。
•
deleteClass() — Caché クラスを削除します。
•
deleteExtent() — 指定されたエクステントのすべてのオブジェクトを削除します。
•
getConnection() — 基礎となる eXTreme 接続を返します。
•
getEvent() — 指定されたクラス名に対応するイベント・オブジェクトを返します。
•
getInterfaceResolver() — 現在指定されている InterfaceResolver のインスタンスを返します。
•
getJDBCConnection() — JDBC 接続オブジェクトを返します。
•
getTransactionLevel() — 現在のトランザクション・レベル (トランザクション内でない場合は 0) を返します。
•
importSchema() — フラット・スキーマをインポートします。
•
importSchemaFull() — フル・スキーマをインポートします。
•
rollback() — 指定された数のトランザクション・レベルをロールバックするか、レベルが指定されていない場
合、すべてのレベルのトランザクションをロールバックします。
•
setInterfaceResolver() — 使用する InterfaceResolver オブジェクトを指定します。
•
startTransaction() — トランザクション (入れ子になったトランザクションの場合あり) を開始します。
•
close() — このインスタンスで保持されているすべてのリソースを解放します。
•
createQuery() — EventQuery<> インスタンスを作成します。
•
deleteObject() — データベース ID または IdKey を指定されたイベントを削除します。
Event
78 Caché eXTreme での Java の使用法
XEP クイック・リファレンス
•
getObject() — データベース ID または IdKey を指定されたイベントを返します。
•
isEvent() — オブジェクト (またはクラス) が XEP の意味でイベントかどうかを確認します。
•
startIndexing() — 基本クラスのインデックス作成を開始します。
•
stopIndexing() — 基本クラスのインデックス作成を停止します。
•
store() — 指定されたオブジェクトまたはオブジェクトの配列を格納します。
•
updateObject() — データベース ID または IdKey を指定されたイベントを更新します。
•
waitForIndexing() — このクラスの非同期インデックス作成が完了するまで待機します。
EventQuery<>
•
close() — このインスタンスで保持されているすべてのリソースを解放します。
•
deleteCurrent() — getNext() によって最後にフェッチされたイベントを削除します。
•
execute() — この XEP クエリを実行します。
•
getAll() — 結果セット内のすべてのイベントを配列としてフェッチします。
•
getFetchLevel() — 現在のフェッチ・レベルを返します。
•
getIterator() — クエリ結果に対して繰り返し処理を実行するために使用できる EventQueryIterator<> を返
します。
•
getNext() — 結果セット内の次のイベントをフェッチします。
•
setFetchLevel() — 返されるデータの量を制御します。
•
setParameter() — このクエリのパラメータを結合します。
•
updateCurrent() — getNext() によって最後にフェッチされたイベントを更新します。
EventQueryIterator<>
•
hasNext() — クエリ結果セットに他の項目がある場合、true を返します。
•
next() — 結果セット内の次のイベントをフェッチします。
•
remove() — next() によって最後にフェッチされたイベントを削除します。
•
set() — next() によって最後にフェッチされたイベントに新しい値を割り当てます。
InterfaceResolver
•
getImplementationClass() — フィールドがインタフェースとして宣言された場合、このメソッドの実装を使用し
て、スキーマのインポート中に実際のフィールド・タイプを解決できます。
5.1.2 クラス PersisterFactory
クラス com.intersys.xep.PersisterFactory は新しい EventPersister オブジェクトを作成します。
PersisterFactory() コンストラクタ
PersisterFactory の新しいインスタンスを作成します。
PersisterFactory()
Caché eXTreme での Java の使用法 79
eXTreme クラスのクイック・リファレンス
createPersister()
PersisterFactory.createPersister() は EventPersister のインスタンスを返します。
static EventPersister createPersister()
[inline, static]
関連項目 :
EventPersister の作成と接続
5.1.3 クラス EventPersister
クラス com.intersys.xep.EventPersister は、XEP モジュールの主なエントリ・ポイントです。このクラスは、XEP オプショ
ンの設定、XEP 接続の確立、スキーマのインポート、および XEP イベント・オブジェクトの作成を行うために使用できるメ
ソッドを提供します。また、トランザクションを制御するメソッドおよびその他のタスクを実行するメソッドも提供します。
大部分のアプリケーションでは、EventPersister のインスタンスは、PersisterFactory.createPersister() によって作成す
る必要があります。コンストラクタは、クラスを拡張するためにのみ使用してください。
EventPersister() コンストラクタ
EventPersister の新しいインスタンスを作成します。
EventPersister()
callClassMethod()
EventPersister.callClassMethod() — Caché ObjectScript クラス・メソッドを呼び出し、0 個以上の引数を渡し、
メソッドの返り値を String、Integer、Long、または Double のインスタンスとして返します (値を返さないメソッドを
呼び出すには callVoidClassMethod() を使用します)。
Object callClassMethod(String className, String methodName, Object... args)
パラメータ :
•
className — 呼び出されるメソッドが属する Caché クラスの完全修飾名。
•
methodName — Caché クラス・メソッドの名前。
•
args — メソッドに渡す 0 個以上の引数のリスト。
引数は、String、Integer、Long、Double、byte[]、または com.intersys.globals.ByteArrayRegion 型のいず
れかになります。末尾の引数は、省略できます。すべての引数の数よりも少ない数の引数が渡されるか、末
尾の引数に対して null が渡されることでそれらの引数には既定の値が使用されるようになります。非 null
引数が null 引数の右側に渡されると例外がスローされます。
callFunction()
EventPersister.callFunction() は、Caché ObjectScript 関数を呼び出します ("Caché ObjectScript の使用法"
の “ユーザ定義コード” を参照してください)。
Object callFunction(String functionName, String routineName, Object... args)
パラメータ :
•
functionName — 関数の名前。
•
routineName — 関数を含むルーチンの名前。
•
args — 渡される引数。
80 Caché eXTreme での Java の使用法
XEP クイック・リファレンス
引数は、String、Integer、Long、Double、byte[]、または com.intersys.globals.ByteArrayRegion 型のいず
れかになります。末尾の引数は、省略できます。すべての引数の数よりも少ない数の引数が渡されるか、末
尾の引数に対して null が渡されることでそれらの引数には既定の値が使用されるようになります。非 null
引数が null 引数の右側に渡されると例外がスローされます。
callProcedure()
EventPersister.callProcedure() は、Caché ObjectScript プロシージャを呼び出します ("Caché ObjectScript の
使用法" の “ユーザ定義コード” を参照してください)。
void callProcedure(String procedureName, String routineName, Object... args)
パラメータ :
•
procedureName — プロシージャの名前。
•
routineName — プロシージャを含むルーチンの名前。
•
args — 渡される引数。
引数は、String、Integer、Long、Double、byte[]、または com.intersys.globals.ByteArrayRegion 型のいず
れかになります。末尾の引数は、省略できます。すべての引数の数よりも少ない数の引数が渡されるか、末
尾の引数に対して null が渡されることでそれらの引数には既定の値が使用されるようになります。非 null
引数が null 引数の右側に渡されると例外がスローされます。
callVoidClassMethod()
EventPersister.callVoidClassMethod() — 返り値のない Caché ObjectScript クラス・メソッドを呼び出し、0 個以
上の引数を渡します。このメソッドは、呼び出し側で返り値を必要としない場合に、任意の Caché クラス・メソッド
(それが通常、値を返すかどうかにかかわらず) を呼び出すために使用できます。値を返すメソッドを呼び出す
には、callClassMethod() を使用します。
void callVoidClassMethod(String className, String methodName, Object... args)
パラメータ :
•
className — 呼び出されるメソッドが属する Caché クラスの完全修飾名。
•
methodName — Caché クラス・メソッドの名前。
•
args — メソッドに渡す 0 個以上の引数のリスト。
•
引数は、String、Integer、Long、Double、byte[]、または com.intersys.globals.ByteArrayRegion 型のいず
れかになります。末尾の引数は、省略できます。すべての引数の数よりも少ない数の引数が渡されるか、末
尾の引数に対して null が渡されることでそれらの引数には既定の値が使用されるようになります。非 null
引数が null 引数の右側に渡されると例外がスローされます。
close()
EventPersister.close() は、このインスタンスで保持されているすべてのリソースを解放します。
void close()
EventPersister のインスタンスが範囲外になる前に、そのインスタンスで必ず close() を呼び出すことが重要で
す。それを閉じないと、深刻なメモリ・リークが発生することがあります。それは、Java ガーベッジ・コレクションで
は、基盤となるネイティブ・コードによって割り当てられたリソースを解放できないためです。
Caché eXTreme での Java の使用法 81
eXTreme クラスのクイック・リファレンス
commit()
EventPersister.commit() は、1 レベルのトランザクションをコミットします。
void commit()
connect()
EventPersister.connect() は、指定されている引数に応じて eXTreme 接続または TCP/IP 接続のいずれかを
使用して Caché に接続します。namespace、username、および password 引数のみが指定されている場合、プ
ロセス内 eXTreme 接続が確立されます。host および port も指定されている場合、TCP/IP 接続が確立されま
す。
void connect(String namespace, String username, String password)
void connect(String host, int port, String namespace, String username, String password)
パラメータ :
•
namespace — アクセス先のネームスペース。
•
username — この接続のユーザ名。
•
password — この接続のパスワード。
•
host — TCP/IP 接続のホスト・アドレス。
•
port — TCP/IP 接続のポート番号。
関連項目 :
EventPersister の作成と接続
deleteClass()
EventPersister.deleteClass() Caché クラス定義を削除します。エクステントに関連付けられたオブジェクトは削
除しません (オブジェクトは複数のエクステントに属することができるため)。また、依存関係 (内部クラス、埋め込
みクラスなど) も削除しません。
void deleteClass(String className)
パラメータ :
•
className — 削除されるクラスの名前。
指定されたクラスが存在しない場合、呼び出しは、通知なしで失敗します (エラーはスローされません)。
関連項目 :
"格納されたイベントへのアクセス" の “テスト・データの削除”
deleteExtent()
EventPersister.deleteExtent() は、Java イベントに関連付けられたエクステント定義を削除しますが、関連付け
られているデータは破棄しません (オブジェクトは、複数のエクステントに属することができるため)。エクステント
の管理の詳細は、"Caché オブジェクトの使用法" の “エクステント” を参照してください。
void deleteExtent(String className)
•
className — エクステントの名前。
このメソッドを、すべてのエクステント・データをエクステント定義と共に破棄する非推奨の Event.deleteExtent()
と混同しないでください。
82 Caché eXTreme での Java の使用法
XEP クイック・リファレンス
関連項目 :
"格納されたイベントへのアクセス" の “テスト・データの削除”
getConnection()
EventPersister.getConnection() — EventPersister eXTreme 接続の基礎となる com.intersys.globals.Connection
のインスタンスを返します。EventPersister が TCP/IP 接続を持っている場合は、例外をスローします。
com.intersys.globals.Connection getConnection()
関連項目 :
EventPersister の作成と接続
getEvent()
EventPersister.getEvent() は、指定されたクラス名に対応する Event オブジェクトを返し、オプションで、使用
するインデックス作成モードを指定します。
Event getEvent(String className)
Event getEvent(String className, int indexMode)
パラメータ :
•
className — 返されるオブジェクトのクラス名。
•
indexMode — 使用するインデックス作成モード。
以下の indexMode オプションを使用できます。
•
Event.INDEX_MODE_ASYNC_ON — 非同期のインデックス作成を可能にします。これは、indexMode パラ
メータが指定されていない場合の既定の設定です。
•
Event.INDEX_MODE_ASYNC_OFF — startIndexing() メソッドが呼び出されない限り、インデックス作成は実
行されません。
•
Event.INDEX_MODE_SYNC — インデックス作成は、エクステントが変更されるたびに実行されます。これは
多数のトランザクションの場合は非効率的になる可能性があります。クラスにユーザ割り当て IdKey がある
場合は、このインデックス・モードを指定する必要があります。
Event の同じインスタンスを使用して、1 つのクラスのすべてのインスタンスを格納または取得できるため、1 つ
のプロセスで getEvent() メソッドを呼び出す必要があるのはクラスごとに 1 回のみです。単一クラスに対する複
数の Event オブジェクトのインスタンス化は避けてください。パフォーマンスに影響を及ぼしかねず、メモリ・リー
クの原因となることがあります。
関連項目 :
イベント・インスタンスの作成と永続イベントの格納、インデックス更新の制御
getInterfaceResolver()
EventPersister.getInterfaceResolver() — importSchema() によって使用されるようになる InterfaceResolver の
現在設定されているインスタンスを返します (“InterfaceResolver の実装” を参照してください)。設定されてい
るインスタンスがない場合、null を返します。
InterfaceResolver getInterfaceResolver()
関連項目 :
setInterfaceResolver()、importSchema()
Caché eXTreme での Java の使用法 83
eXTreme クラスのクイック・リファレンス
getJDBCConnection()
EventPersister.getJDBCConnection() EventPersister 接続の基礎となる JDBC Connection オブジェクトを返
します。
java.sql.Connection getJDBCConnection()
関連項目 :
EventPersister の作成と接続
getTransactionLevel()
EventPersister.getTransactionLevel() は、現在のトランザクション・レベル (トランザクション内でない場合は 0)
を返します。
int getTransactionLevel()
importSchema()
EventPersister.importSchema() シリアル化オブジェクトとしてすべての参照オブジェクトを埋め込むフラット・ス
キーマ (“スキーマ・インポート・モデル” を参照) を作成します。このメソッドは、クラスで宣言された各イベント
のスキーマまたは指定されている .jar ファイル (依存関係を含む) をインポートし、インポートされたイベントのク
ラス名の配列を返します。
String[] importSchema(String classOrJarFileName)
String[] importSchema(String[] classes)
パラメータ :
•
classes — インポートされるクラスの名前を含む配列。
•
classOrJarFileName — クラス名またはインポートされるクラスを含む .jar ファイルの名前。.jar ファイル
が指定される場合、ファイル内のすべてのクラスがインポートされます。
引数がクラス名である場合、対応するクラスおよびすべての依存関係がインポートされます。引数が .jar ファイ
ルである場合、ファイル内のすべてのクラスおよびすべての依存関係がインポートされます。そのようなスキー
マが既に存在していて、それが Java スキーマと同期していると思われる場合、インポートはスキップされます。
スキーマが既に存在しているが、別なものと思われる場合は、データがあるか調べるためのチェックが実行され
ます。データがない場合、新しいスキーマが生成されます。既存のデータがある場合、例外がスローされます。
関連項目 :
スキーマのインポート
importSchemaFull()
EventPersister.importSchemaFull() — ソース・クラスのオブジェクト階層を保持するフル・スキーマ (“スキーマ・
インポート・モデル” を参照) を作成します。このメソッドは、クラスで宣言された各イベントのスキーマまたは指
定されている .jar ファイル (依存関係を含む) をインポートし、インポートされたイベントのクラス名の配列を返し
ます。
String[] importSchemaFull(String classOrJarFileName)
String[] importSchemaFull(String[] classes)
パラメータ :
•
classes — インポートされるクラスの名前を含む配列。
•
classOrJarFileName — クラス名またはインポートされるクラスを含む .jar ファイルの名前。.jar ファイル
が指定される場合、ファイル内のすべてのクラスがインポートされます。
84 Caché eXTreme での Java の使用法
XEP クイック・リファレンス
引数がクラス名である場合、対応するクラスおよびすべての依存関係がインポートされます。引数が .jar ファイ
ルである場合、ファイル内のすべてのクラスおよびすべての依存関係がインポートされます。そのようなスキー
マが既に存在していて、それが Java スキーマと同期していると思われる場合、インポートはスキップされます。
スキーマが既に存在しているが、別なものと思われる場合は、データがあるか調べるためのチェックが実行され
ます。データがない場合、新しいスキーマが生成されます。既存のデータがある場合、例外がスローされます。
関連項目 :
スキーマのインポート
rollback()
EventPersister.rollback() は、指定された数のレベルのトランザクションをロールバックします。ここで、level は
正の整数です。レベルが指定されていない場合、すべてのレベルのトランザクションをロールバックします。
void rollback()
void rollback(int level)
パラメータ :
•
level — ロールバックするレベルの数 (オプション)。
このメソッドは、level が 0 未満の場合何もせず、level が最初のトランザクション・レベルより大きい場合、トラン
ザクション・レベルが 0 に到達するとロールバックを停止します。
setInterfaceResolver()
EventPersister.setInterfaceResolver() — importSchema() によって使用される InterfaceResolver のインスタン
スを設定します (“InterfaceResolver の実装” を参照してください)。この EventPersiser によって作成される
Event のすべてのインスタンスは、指定された InterfaceResolver (このメソッドが呼び出されない場合は既定で
null になる) を共有します。
void setInterfaceResolver(InterfaceResolver interfaceResolver)
パラメータ :
•
interfaceResolver — インタフェースとして宣言されるフィールドの実際のタイプを決定するために
importSchema() によって使用される InterfaceResolver の実装。この引数は、null にすることができます。
関連項目 :
getInterfaceResolver()、importSchema()
startTransaction()
EventPersister.startTransaction() は、トランザクション (入れ子になったトランザクションの場合あり) を開始しま
す。
void startTransaction()
5.1.4 クラス Event
クラス com.intersys.xep.Event は、XEP イベント (イベントの格納、クエリの作成、インデックスの作成他) を処理するメソッ
ドを提供します。これは EventPersister.getEvent() メソッドにより作成されます。
close()
Event.close() は、このインスタンスで保持されているすべてのリソースを解放します。
Caché eXTreme での Java の使用法 85
eXTreme クラスのクイック・リファレンス
void close()
Event のインスタンスが範囲外になる前に、そのインスタンスで必ず close() を呼び出すことが重要です。それ
を閉じないと、深刻なメモリ・リークが発生することがあります。それは、Java ガーベッジ・コレクションでは、基盤
となるネイティブ・コードによって割り当てられたリソースを解放できないためです。
createQuery()
Event.createQuery() は、SQL クエリのテキストを含む String 引数を取り、EventQuery<E> のインスタンスが返
されます。パラメータ E は、親 Event のターゲット・クラスです。
<E> EventQuery<E> createQuery (String sqlText)
パラメータ :
•
sqlText — この SQL クエリのテキスト。
関連項目 :
クエリの作成と実行
deleteObject()
Event.deleteObject() は、データベース・オブジェクト ID または IdKey によって特定されたイベントを削除しま
す。
void deleteObject(long id)
void deleteObject(Object[] idkeys)
パラメータ :
•
id — データベース・オブジェクト ID
•
idkeys — IdKey を構成するオブジェクトの配列 (“IdKey の使用法” を参照してください)。基礎となるク
ラスに IdKey がないか、提供されたキーのいずれかが null であるか無効なタイプである場合は XEPException
がスローされます。
関連項目 :
格納されたイベントへのアクセス
getObject()
Event.getObject() は、データベース・オブジェクト ID または IdKey によって特定されたイベントをフェッチしま
す。指定したオブジェクトが存在しない場合、null を返します。
Object getObject(long id)
Object getObject(Object[] idkeys)
パラメータ :
•
id — データベース・オブジェクト ID
•
idkeys — IdKey を構成するオブジェクトの配列 (“IdKey の使用法” を参照してください)。基礎となるク
ラスに IdKey がないか、提供されたキーのいずれかが null であるか無効なタイプである場合は XEPException
がスローされます。
関連項目 :
格納されたイベントへのアクセス
86 Caché eXTreme での Java の使用法
XEP クイック・リファレンス
isEvent()
Event.isEvent() は、オブジェクト (またはクラス) が XEP の意味でイベントでない場合、XEPException をスロー
します (“インポートされるクラスの要件” を参照してください)。例外メッセージにより、このオブジェクトが XEP
イベントでない理由が説明されます。
static void isEvent(Object objectOrClass)
パラメータ :
•
objectOrClass — テストされるオブジェクト。
startIndexing()
Event.startIndexing() は、ターゲット・クラスのエクステントに対して非同期インデックス作成を開始します。イン
デックス・モードが Event.INDEX_MODE_SYNC である場合は、例外をスローします (“インデックス更新の制御”
を参照してください)。
void startIndexing()
stopIndexing()
Event.stopIndexing() は、エクステントに対する非同期インデックス作成を停止します。Event インスタンスを閉
じるときにインデックスを更新しないようにする場合は、Event.close() を呼び出す前にこのメソッドを呼び出しま
す。
void stopIndexing()
関連項目 :
インデックス更新の制御
store()
Event.store() は、Java オブジェクトまたはオブジェクトの配列を永続イベントとして格納します。ループ内での
配列の渡しと個別オブジェクトの渡しに大きなパフォーマンスの差はありませんが、配列内のすべてのオブジェ
クトは同じ型である必要があります。新しく挿入されたオブジェクトごとに 1 つの long データベース ID を返し、
ID を返せない場合またはイベントが IdKey を使用している場合は 0 を返します。
long store(Object object)
long[] store(Object[] objects)
パラメータ :
•
object — データベースに追加される Java オブジェクト。
•
objects — データベースに追加される Java オブジェクトの配列。すべてのオブジェクトは同じ型である必
要があります。
updateObject()
Event.updateObject() は、データベース ID または IdKey によって特定されたイベントを更新します。
void updateObject(long id, Object object)
void updateObject(Object[] idkeys, Object object)
パラメータ :
•
id — データベース・オブジェクト ID
Caché eXTreme での Java の使用法 87
eXTreme クラスのクイック・リファレンス
•
idkeys — IdKey を構成するオブジェクトの配列 (“IdKey の使用法” を参照してください)。基礎となるク
ラスに IdKey がないか、提供されたキーのいずれかが null であるか無効なタイプである場合は XEPException
がスローされます。
•
object — 指定したイベントを置き換える新しいオブジェクト。
関連項目 :
格納されたイベントへのアクセス
waitForIndexing()
Event.waitForIndexing() は、非同期インデックス作成の完了を待機します。インデックス作成が完了した場合は
true を返し、インデックス作成が完了する前に待機がタイムアウトした場合は false を返します。インデック
ス・モードが Event.INDEX_MODE_SYNC である場合は、例外をスローします。
boolean waitForIndexing(int timeout)
パラメータ :
•
timeout — タイムアウトになるまで待機する秒数 (-1 の場合は永久に待機し、0 の場合は直ちに返しま
す)。
関連項目 :
インデックス更新の制御
5.1.5 クラス EventQuery<>
クラス com.intersys.xep.EventQuery<> は、データベースから個別のイベントを取得、更新および削除するために使用
できます。
close()
EventQuery<>.close() は、このインスタンスで保持されているすべてのリソースを解放します。
void close()
EventQuery<> のインスタンスが範囲外になる前に、そのインスタンスで必ず close() を呼び出すことが重要で
す。それを閉じないと、深刻なメモリ・リークが発生することがあります。それは、Java ガーベッジ・コレクションで
は、基盤となるネイティブ・コードによって割り当てられたリソースを解放できないためです。
deleteCurrent()
EventQuery<>.deleteCurrent() は、getNext() によって最後にフェッチされたイベントを削除します。
void deleteCurrent()
関連項目 :
クエリ・データの処理
execute()
EventQuery<>.execute() は、この EventQuery<> と関連付けられた SQL クエリを実行します。クエリが正常に
実行された場合、この EventQuery<> には、他の EventQuery<> または EventQueryIterator<> メソッドでアク
セスできる結果セットが含まれます。
void execute()
88 Caché eXTreme での Java の使用法
XEP クイック・リファレンス
関連項目 :
クエリの作成と実行
getAll()
EventQuery<>.getAll() は、結果セット内のすべての行を単一の配列として返します。
java.util.List<E> getAll()
これは、指定したクエリに一致するすべてのデータを取得するために使用できる便利なメソッドです。これは、
getNext() の呼び出しと組み合わせることはできません。オブジェクトのリストの保持には高いコストがかかります。
最適なパフォーマンスを得るため、またはその時点で 1 つの要素のみを処理する必要がある場合は、代わりに
getNext() を選択します。
関連項目 :
クエリ・データの処理
getFetchLevel()
EventQuery<>.getFetchLevel() は、現在のフェッチ・レベルを返します (“フェッチ・レベルの定義” を参照して
ください)。
int getFetchLevel()
getIterator()
EventQuery<>.getIterator() は、クエリ結果に対して繰り返し処理を実行するために使用できる
EventQueryIterator<> を返します (“EventQueryIterator<> の使用法” を参照してください)。
EventQueryIterator<E> getIterator()
getNext()
EventQuery<>.getNext() は、引数としてターゲット・クラスのオブジェクトを取り、結果セットの次の項目を返しま
す (引数が null の場合は結果セットの最初の項目を返します)。結果セットにそれ以上項目がない場合は、
null を返します。
E getNext(E obj)
パラメータ :
•
obj — 反復カーソルが現在指しているオブジェクト (または、結果セットの最初の項目を返す場合は null)。
関連項目 :
クエリ・データの処理
setFetchLevel()
EventQuery<>.setFetchLevel() は、フェッチ・レベルを設定することで返されるデータの量を制御します (“フェッ
チ・レベルの定義” を参照してください)。
例えば、フェッチ・レベルを Event.FETCH_LEVEL_DATATYPES_ONLY に設定すると、このクエリによって返さ
れるオブジェクトは、それらのデータ型フィールドのみ設定されるようになり、オブジェクト・タイプ、配列、または
コレクションのフィールドには何も生成されません。このオプションを使用すると、クエリ・パフォーマンスが大幅
に向上します。
void setFetchLevel(int level)
パラメータ :
Caché eXTreme での Java の使用法 89
eXTreme クラスのクイック・リファレンス
•
level — フェッチ・レベル定数 (Event クラスで定義される)。
サポートされるフェッチ・レベルは以下のとおりです。
•
Event.FETCH_LEVEL_ALL — 既定。すべてのフィールドが生成されます。
•
Event.FETCH_LEVEL_DATATYPES_ONLY — データ型フィールドのみが生成されます。
•
Event.FETCH_LEVEL_NO_ARRAY_TYPES — すべての配列がスキップされます。
•
Event.FETCH_LEVEL_NO_OBJECT_TYPES — すべてのオブジェクト・タイプがスキップされます。
•
Event.FETCH_LEVEL_NO_COLLECTIONS — すべてのコレクションがスキップされます。
setParameter()
EventQuery<>.setParameter() は、この EventQuery<> と関連付けられた SQL クエリのパラメータを結合しま
す。
void setParameter(int index, java.lang.Object value)
パラメータ :
•
index — クエリ文内のこのパラメータのインデックス。
•
value — このクエリに使用される値。
関連項目 :
クエリの作成と実行
updateCurrent()
EventQuery<>.updateCurrent() は、getNext() によって最後にフェッチされたイベントを更新します。
void updateCurrent(E obj)
パラメータ :
•
obj — 現在のイベントを置き換える Java オブジェクト。
関連項目 :
クエリ・データの処理
5.1.6 クラス EventQueryIterator<>
クラス com.intersys.xep.EventQueryIterator<> は、XEP イベントの取得、更新および削除を行う代替手段です (同じタ
スクは、EventQuery<> メソッドを直接使用しても実行できます)。
hasNext()
EventQueryIterator<>.hasNext() は、クエリ結果セットに他の項目がある場合、true を返します。
boolean hasNext()
next()
EventQueryIterator<>.next() は、クエリ結果セット内の次のイベントをフェッチします。
E next()
90 Caché eXTreme での Java の使用法
XDO クイック・リファレンス
remove()
EventQueryIterator<>.remove() は、next() によって最後にフェッチされたイベントを削除します。
void remove()
set()
EventQueryIterator<>.set() は、next() によって最後にフェッチされたイベントを置換します。
void set(E obj)
パラメータ :
•
obj — next() によって最後にフェッチされたイベントを置き換えるターゲット・クラスのオブジェクト。 .
5.1.7 インタフェース InterfaceResolver
既定では、インタフェースとして宣言されたフィールドはスキーマ生成の際に無視されます。この動作を変更するには、
InterfaceResolver の実装を importSchema() メソッドへ渡して、インタフェース・タイプを正しい具体的なデータ型で置換
するための情報を提供します。
getImplementationClass()
InterfaceResolver.getImplementationClass() は、インタフェースとして宣言されたフィールドの実際のデータ型
を返します。詳細は、“InterfaceResolver の実装” を参照してください。
Class<?> getImplementationClass (Class declaringClass, String fieldName, Class<?> interfaceClass)
パラメータ :
•
declaringClass — fieldName が interfaceClass として宣言されるクラス。
•
fieldName — インタフェースとして宣言された declaringClass のフィールド名。
•
interfaceClass — 解決されるインタフェース。
5.1.8 クラス XEPException
クラス com.intersys.xep.XEPException は、Event、EventPersister、および EventQuery<> のほとんどのメソッドによりス
ローされる例外を実装します。このクラスは、java.lang.RuntimeException から継承されます。
Constructors
XEPException (String message)
XEPException (Throwable x, String message)
XEPException (Throwable x)
5.2 XDO クイック・リファレンス
このセクションは、XDO API (eXTreme ダイナミック・オブジェクト — ネームスペース com.intersys.xdo) のリファレンスで
す。この API の使用法の詳細は、"eXTreme ダイナミック・オブジェクトの使用法" を参照してください。これには、以下
のパブリック・クラスおよびパブリック・インタフェースが含まれています。
•
クラス DatabaseConnectionFactory — DatabaseConnection オブジェクトを返すメソッドを提供します。
Caché eXTreme での Java の使用法 91
eXTreme クラスのクイック・リファレンス
•
インタフェース DatabaseConnection — Caché データベースへの物理接続および論理接続をカプセル化します。こ
のクラスは、XDO インスタンスの作成、インデックスの更新、およびトランザクションの制御を行うメソッドを提供しま
す。
•
インタフェース DynamicObject — 指定された永続クラスのオブジェクトへの参照をカプセル化します。このインタ
フェースは、データベース内の永続オブジェクトにアクセスし、これを操作するメソッドを提供します。
•
XDO 例外クラス— XDOException はほとんどの DatabaseConnection メソッドおよび DynamicObject メソッドによっ
てスローされます。XDONullValueException はノード値が NULL のときに、アプリケーションが int、double、または
long を取得しようとするとスローされます。
5.2.1 XDO メソッドのリスト
下記の XDO API のクラス、インタフェースおよびメソッドをこのリファレンスで説明します。
DatabaseConnectionFactory
•
createJNIDatabaseConnection() — DatabaseConnection オブジェクトを返します。
DatabaseConnection
•
buildIndices() — 指定されたクラスのインデックスを再作成します。
•
commit() — 1 レベルのトランザクションをコミットします。
•
connect() — Caché データベースに接続します。
•
createNew() — 指定された永続クラスの空の DynamicObject を作成します。
•
disconnect() — Caché データベースから切断します。
•
getDefaultConcurrencyLevel() — 現在の既定のロック・レベルを返します。
•
openId() — 指定されたクラスの永続オブジェクトのデータのコピーを含む DynamicObject を作成します。
•
rollback() — トランザクションのすべてのレベルをロールバックします。
•
setDefaultConcurrencyLevel() — トランザクション中に既定のロック・レベルを指定します。
•
startTransaction() — トランザクション (入れ子になったトランザクションの場合あり) を開始します。
•
transactionLevel() — 現在のトランザクション・レベル (トランザクション内でない場合は 0) を返します。
DynamicObject
•
cleanup() — オブジェクトが破棄される際のリソース・リークを回避するために、オブジェクトの基本となるリ
ソースを解放します。
•
delete() — ターゲット・オブジェクトをデータベースから削除します。
•
getBigDecimal() — プロパティの値を BigDecimal 変数として返します。
•
getDate() — プロパティの値を Date 変数として返します。
•
getDouble() — プロパティの値を double 変数として返します。
•
getDoubleWrapper() — プロパティの値を Double 変数として返します。
•
getId() — このダイナミック・オブジェクトに対応するデータベース・オブジェクトの ID を返します。
•
getInt() — プロパティの値を int 変数として返します。
•
getIntegerWrapper() — プロパティの値を Integer 変数として返します。
92 Caché eXTreme での Java の使用法
XDO クイック・リファレンス
•
getLong() — プロパティの値を long 変数として返します。
•
getLongWrapper() — プロパティの値を Long 変数として返します。
•
getPropertyNumber() — プロパティ名を与えられ、プロパティのプロパティ番号を示す整数を返します。
•
getString() — プロパティの値を String 変数として返します。
•
getTime() — プロパティの値を Time 変数として返します。
•
getTimestamp() — プロパティの値を Timestamp 変数として返します。
•
insert() — ダイナミック・オブジェクトのデータのコピーを含む新規ターゲット・データベース・オブジェクトを
作成し、接続します。
•
isNull() — openId() によって返された DynamicObject が NULL かどうかをテストします。
•
save() — ダイナミック・オブジェクトのデータを永続データベース・オブジェクトに保存します。
•
set() — ダイナミック・オブジェクトの指定されたプロパティを指定された値に設定します。
•
update() — ターゲット・データベース・オブジェクトのデータを更新します。
5.2.2 クラス DatabaseConnectionFactory
クラス com.intersys.xdo.DatabaseConnectionFactory は、 DatabaseConnection のインスタンスを作成するメソッドを提
供します。使用法に関する詳細は、“eXTreme ダイナミック・オブジェクトの使用法” の “接続と切断” に関するセクショ
ンを参照してください。接続オプションの詳細は、"Caché JavaDoc" (<cache-root>/dev/java/doc/index.html) を参照
してください。
createJNIDatabaseConnection()
DatabaseConnectionFactory.createJNIDatabaseConnection() は DatabaseConnection の新規インスタンスを
返します。
public static com.intersys.internal.lcbjni.LCBJNIDatabaseConnection createJNIDatabaseConnection()
5.2.3 インタフェース DatabaseConnection
インタフェース com.intersys.xdo.DatabaseConnection は、Caché データベースへの物理接続と論理接続を表します。
このクラスは、XDO インスタンスの作成、インデックスの更新、およびトランザクションの制御を行うメソッドを提供します。
buildIndices()
DatabaseConnection.buildIndices() は、指定されたクラスのインデックスを再作成します。このメソッドは、
deferIndices=true で、一連の保存/挿入/削除/更新を実行した後に使用されます。
void buildIndices (String className) throws XDOException
パラメータ :
•
className — インデックスが作成されるエクステントのクラス名。
commit()
DatabaseConnection.commit() は、1 レベルのトランザクションをコミットします。
void commit() throws XDOException
Caché eXTreme での Java の使用法 93
eXTreme クラスのクイック・リファレンス
connect()
DatabaseConnection.connect() は、eXTreme データベース接続を開きます。
void connect(String namespace, String user, String password) throws XDOException
パラメータ :
•
namespace — アクセス先のネームスペース。
•
user — この接続のユーザ名。
•
password — この接続のパスワード。
createNew()
DatabaseConnection.createNew() は、指定された永続クラスの空の DynamicObject を返します。
DynamicObject createNew(String className) throws XDOException
パラメータ :
•
className — 作成されるオブジェクトのクラス名。
disconnect()
DatabaseConnection.disconnect() は、eXTreme データベース接続を切断します。
void disconnect() throws XDOException
getDefaultConcurrencyLevel()
DatabaseConnection.getDefaultConcurrencyLevel() は、現在の既定のロック・レベルを示す int を返します。
int getDefaultConcurrencyLevel() throws XDOException
openId()
DatabaseConnection.openId() は、指定されたクラスの既存のオブジェクトのデータのコピーを含む DynamicObject
を返します。
DynamicObject openId(String className, String id)
throws XDOException
DynamicObject openId(String className, String id, int concurrency, int timeout)
throws XDOException
パラメータ :
•
className — 開かれるオブジェクトのクラス名。
id — 開かれるオブジェクトの ID。
concurrency — このオブジェクトに使用されるロック・レベル。
timeout — このオブジェクトにアクセスするために待機する秒数。
rollback()
DatabaseConnection.rollback() は、トランザクションのすべてのレベルをロールバックします。
void rollback() throws XDOException
94 Caché eXTreme での Java の使用法
XDO クイック・リファレンス
setDefaultConcurrencyLevel()
DatabaseConnection.setDefaultConcurrencyLevel() は、トランザクション中に既定のロック・レベルを指定しま
す。
void setDefaultConcurrencyLevel(int level) throws XDOException
パラメータ :
•
level — 既定のロック・レベルを指定します。
startTransaction()
DatabaseConnection.startTransaction() は、トランザクション (入れ子になったトランザクションの場合あり) を開
始します。
void startTransaction() throws XDOException
transactionLevel()
DatabaseConnection.transactionLevel() は、現在のトランザクション・レベル (トランザクション内でない場合は
0) を示す int を返します。
int transactionLevel() throws XDOException
5.2.4 インタフェース DynamicObject
インタフェース com.intersys.xdo.DynamicObject は、指定された永続クラスと同じプロパティを持つメモリ内オブジェクト
を表します。このクラスは、同じクラスのデータベース・オブジェクトへのポインタを含むことができ、そのオブジェクトのデー
タを更新できます。また、新しいデータベース・オブジェクトを作成するか、またはデータベースから既存のオブジェクトを
削除するメソッドも提供します。
cleanup()
DynamicObject.cleanup() はオブジェクトが破棄される際のメモリ・リークなどの問題を回避するために、オブジェ
クトの基本となるメモリ等のリソースを解放します。
void cleanup()
delete()
DynamicObject.delete() は、ターゲット・オブジェクトをデータベースから削除します。
void delete() throws XDOException
void delete(boolean deferIndices, int timeout) throws XDOException
パラメータ :
•
deferIndices — オブジェクトを削除したときにインデックスを再作成する必要があるかどうかを指定しま
す。
•
timeout — オブジェクトを削除しようとした時にオブジェクトがロックされている場合に待機する秒数。-1
の値は、既定のタイムアウトを使用することを示し、0 は待機しないことを意味します。
このメソッドは、ダイナミック・オブジェクトに含まれているデータには影響しません。呼び出しに成功すると、ダイ
ナミック・オブジェクトはアタッチ解除されますが、依然としてメモリ内に存在し、そのデータはすべて保持されま
す。
Caché eXTreme での Java の使用法 95
eXTreme クラスのクイック・リファレンス
getBigDecimal()
DynamicObject.getBigDecimal() は、指定されたプロパティの値を BigDecimal 変数として返します。
BigDecimal getBigDecimal(int propertyNumber) throws XDOException
BigDecimal getBigDecimal(String propertyName) throws XDOException
パラメータ :
•
propertyNumber — プロパティのプロパティ番号。
•
propertyName — プロパティの名前。
メソッドの引数は、プロパティ名文字列、またはシステムによって割り当てられた番号のいずれでも指定できます
("getPropertyNumber()" を参照)。
getDate()
DynamicObject.getDate() は、指定されたプロパティの値を Date 変数として返します。
Date getDate(int propertyNumber) throws XDOException
Date getDate(String propertyName) throws XDOException
パラメータ :
•
propertyNumber — プロパティのプロパティ番号。
•
propertyName — プロパティの名前。
メソッドの引数は、プロパティ名文字列、またはシステムによって割り当てられた番号のいずれでも指定できます
("getPropertyNumber()" を参照)。
getDouble()
DynamicObject.getDouble() は、指定されたプロパティの値を double 変数として返します。
double getDouble(int propertyNumber) throws XDOException, XDONullValueException
double getDouble(String propertyName) throws XDOException, XDONullValueException
パラメータ :
•
propertyNumber — プロパティのプロパティ番号。
•
propertyName — プロパティの名前。
メソッドの引数は、プロパティ名文字列、またはシステムによって割り当てられた番号のいずれでも指定できます
("getPropertyNumber()" を参照)。
getDoubleWrapper()
DynamicObject.getDoubleWrapper() は、指定されたプロパティの値を Double 変数として返します。
Double getDoubleWrapper(int propertyNumber) throws XDOException
Double getDoubleWrapper(String propertyName) throws XDOException
パラメータ :
•
propertyNumber — プロパティのプロパティ番号。
•
propertyName — プロパティの名前。
メソッドの引数は、プロパティ名文字列、またはシステムによって割り当てられた番号のいずれでも指定できます
("getPropertyNumber()" を参照)。
96 Caché eXTreme での Java の使用法
XDO クイック・リファレンス
getId()
DynamicObject.getId() は、このダイナミック・オブジェクトに参照されるデータベース・オブジェクトの ID を含む
String を返します。
String getId()
このダイナミック・オブジェクトは、openId() によって作成された場合または createNew() によって作成された後
に保存された場合のみ ID を持ちます。
getInt()
DynamicObject.getInt() は、指定されたプロパティの値を int 変数として返します。
int getInt(int propertyNumber) throws XDOException, XDONullValueException
int getInt(String propertyName) throws XDOException, XDONullValueException
パラメータ :
•
propertyNumber — プロパティのプロパティ番号。
•
propertyName — プロパティの名前。
メソッドの引数は、プロパティ名文字列、またはシステムによって割り当てられた番号のいずれでも指定できます
("getPropertyNumber()" を参照)。
getIntegerWrapper()
DynamicObject.getIntegerWrapper() は、指定されたプロパティの値を Integer 変数として返します。
Integer getIntegerWrapper(int propertyNumber) throws XDOException
Integer getIntegerWrapper(String propertyName) throws XDOException
パラメータ :
•
propertyNumber — プロパティのプロパティ番号。
•
propertyName — プロパティの名前。
メソッドの引数は、プロパティ名文字列、またはシステムによって割り当てられた番号のいずれでも指定できます
("getPropertyNumber()" を参照)。
getLong()
DynamicObject.getLong() は、指定されたプロパティの値を long 変数として返します。
long getLong(int propertyNumber) throws XDOException, XDONullValueException
long getLong(String propertyName) throws XDOException, XDONullValueException
パラメータ :
•
propertyNumber — プロパティのプロパティ番号。
•
propertyName — プロパティの名前。
メソッドの引数は、プロパティ名文字列、またはシステムによって割り当てられた番号のいずれでも指定できます
("getPropertyNumber()" を参照)。
getLongWrapper()
DynamicObject.getLongWrapper() は、指定されたプロパティの値を Long 変数として返します。
Caché eXTreme での Java の使用法 97
eXTreme クラスのクイック・リファレンス
Long getLongWrapper(int propertyNumber) throws XDOException
Long getLongWrapper(String propertyName) throws XDOException
パラメータ :
•
propertyNumber — プロパティのプロパティ番号。
•
propertyName — プロパティの名前。
メソッドの引数は、プロパティ名文字列、またはシステムによって割り当てられた番号のいずれでも指定できます
("getPropertyNumber()" を参照)。
getPropertyNumber()
DynamicObject.getPropertyNumber() は、指定された名前を持つプロパティのプロパティ番号を示す整数を返
します。
int getPropertyNumber(String propertyName) throws XDOException
パラメータ :
•
propertyName — プロパティの名前。
同じプロパティが複数回参照される場合は、名前でなく番号でプロパティを指定する方がずっと効率的です。
このメソッドの使用例は、"トランザクションの使用法" を参照してください。
getString()
DynamicObject.getString() は、指定されたプロパティの値を String 変数として返します。
String getString(int propertyNumber) throws XDOException
String getString(String propertyName) throws XDOException
パラメータ :
•
propertyNumber — プロパティのプロパティ番号。
•
propertyName — プロパティの名前。
メソッドの引数は、プロパティ名文字列、またはシステムによって割り当てられた番号のいずれでも指定できます
("getPropertyNumber()" を参照)。
getTime()
DynamicObject.getTime() は、指定されたプロパティの値を Time 変数として返します。
Time getTime(int propertyNumber) throws XDOException
Time getTime(String propertyName) throws XDOException
パラメータ :
•
propertyNumber — プロパティのプロパティ番号。
•
propertyName — プロパティの名前。
メソッドの引数は、プロパティ名文字列、またはシステムによって割り当てられた番号のいずれでも指定できます
("getPropertyNumber()" を参照)。
getTimestamp()
DynamicObject.getTimestamp() は、指定されたプロパティの値を Timestamp 変数として返します。
98 Caché eXTreme での Java の使用法
XDO クイック・リファレンス
Timestamp getTimestamp(int propertyNumber) throws XDOException
Timestamp getTimestamp(String propertyName) throws XDOException
パラメータ :
•
propertyNumber — プロパティのプロパティ番号。
•
propertyName — プロパティの名前。
メソッドの引数は、プロパティ名文字列、またはシステムによって割り当てられた番号のいずれでも指定できます
("getPropertyNumber()" を参照)。
insert()
DynamicObject.insert() は、ダイナミック・オブジェクトのデータのコピーを含む新規ターゲット・データベース・
オブジェクトを作成し、接続します。
void insert() throws XDOException
void insert(boolean deferIndices, int timeout) throws XDOException
パラメータ :
•
deferIndices — オブジェクトを挿入したときにインデックスを再作成する必要があるかどうかを指定しま
す。
•
timeout — 挿入を試みたときにエクステントがロックされている場合、ロックを取得するために待機する秒
数。-1 の値は、既定のタイムアウトを使用することを示し、0 は待機しないことを意味します。
以前にダイナミック・オブジェクトが別のターゲット・オブジェクトに接続されたとしても、新規ターゲット・オブジェ
クトを作成し、接続します。既存のデータベース・オブジェクトと同じ一意のキーを持つオブジェクトを挿入すると
例外がスローされます。
isNull()
DynamicObject.isNull() は、openId() によって返された DynamicObject オブジェクトが NULL (指定された ID
を持つオブジェクトが見つからない場合) かどうかを示すブーリアン値を返します。
boolean isNull()
save()
DynamicObject.save() は、ダイナミック・オブジェクトのデータを永続データベース・オブジェクトに保存します。
void save() throws XDOException
void save(boolean deferIndices, int timeout) throws XDOException
パラメータ :
•
deferIndices — オブジェクトを保存したときにインデックスを再作成する必要があるかどうかを指定しま
す。
•
timeout — 保存を試みたときに、ロックを取得するために待機する秒数。-1 の値は、既定のタイムアウト
を使用することを示し、0 は待機しないことを意味します。
ダイナミック・オブジェクトがアタッチされている場合、ターゲット・オブジェクトは更新されます。アタッチされてい
ない場合、このメソッドは、新規データベース・オブジェクトを挿入してアタッチしようとします。
一意のキーの制約のためこの挿入に失敗した場合、挿入の失敗を引き起こしたデータベース・オブジェクトが
アタッチされて更新されます。
Caché eXTreme での Java の使用法 99
eXTreme クラスのクイック・リファレンス
set()
DynamicObject.set() は、ダイナミック・オブジェクトの指定されたプロパティを指定された値に設定します。
void
void
void
void
void
void
void
void
void
void
void
set
set
set
set
set
set
set
set
set
set
set
(int
(int
(int
(int
(int
(int
(int
(int
(int
(int
(int
propertyNumber,
propertyNumber,
propertyNumber,
propertyNumber,
propertyNumber,
propertyNumber,
propertyNumber,
propertyNumber,
propertyNumber,
propertyNumber,
propertyNumber,
void
void
void
void
void
void
void
void
void
void
void
set
set
set
set
set
set
set
set
set
set
set
(String
(String
(String
(String
(String
(String
(String
(String
(String
(String
(String
propertyName,
propertyName,
propertyName,
propertyName,
propertyName,
propertyName,
propertyName,
propertyName,
propertyName,
propertyName,
propertyName,
Double value) throws XDOException
double value) throws XDOException
int value) throws XDOException
Integer value) throws XDOException
Long value) throws XDOException
long value) throws XDOException
BigDecimal value) throws XDOException
String value) throws XDOException
Date value) throws XDOException
Time value) throws XDOException
Timestamp value) throws XDOException
Double value) throws XDOException
double value) throws XDOException
int value) throws XDOException
Integer value) throws XDOException
Long value) throws XDOException
long value) throws XDOException
BigDecimal value) throws XDOException
String value) throws XDOException
Date value) throws XDOException
Time value) throws XDOException
Timestamp value) throws XDOException
パラメータ :
•
propertyNumber — プロパティのプロパティ番号。
•
propertyName — プロパティの名前。
•
value — オブジェクトに割り当てられる値。
このプロパティは、名前と番号のいずれかで指定できます。このメソッドは、ダイナミック・オブジェクトにのみ作
用します。ダイナミック・オブジェクトが保存されるまで、データベースは変更されません。
update()
DynamicObject.update() は、ターゲット・データベース・オブジェクトのデータを更新します。
void update () throws XDOException
void update (boolean deferIndices, int timeout) throws XDOException
パラメータ :
•
deferIndices — オブジェクトを更新したときにインデックスを再作成する必要があるかどうかを指定しま
す。
•
timeout — オブジェクトを更新しようとした時にオブジェクトがロックされている場合に待機する秒数。-1
の値は、既定のタイムアウトを使用することを示し、0 は待機しないことを意味します。
5.2.5 XDO 例外
以下のクラスは DatabaseConnection および DynamicObject のほとんどのメソッドによりスローされる例外を実装します。
これらのクラスが java.lang.Exception を拡張します。
com.intersys.xdo.XDOException
ほとんどの XDO メソッドによってスローされる例外を実装します。
100 Caché eXTreme での Java の使用法
グローバルのクイック・リファレンス
Constructors
XDOException
XDOException
XDOException
XDOException
(String msg, int code)
(String msg)
(Throwable x, String message)
(Throwable x)
Method
int getErrorCode ()
Constants
XDOException.CACHE_ERNOCLASS = 122
XDOException.CLASS_DOES_NOT_EXIST = 122
XDOException.NO_GLOBAL_NAME = 300
XDOException.UNDEFINED = 0
com.intersys.xdo.XDONullValueException()
DynamicObject メソッドの getInt()、getLong() および getDouble() が NULL のノード値を取得しようとする場合、
それらによりスローされる例外を実装します。
Constructor
XDONullValueException (String msg)
このクラスは XDOException で定義されるメソッドおよび定数を継承します。
5.3 グローバルのクイック・リファレンス
このセクションは、グローバル API (ネームスペース com.intersys.globals) のリファレンスです。この API の使用法の詳
細は、"グローバル API の使用法" を参照してください。これには、以下のパブリック・クラスおよびパブリック・インタフェー
スが含まれています。
ネームスペース com.intersys.globals :
•
クラス ConnectionContext — Connection オブジェクトを返すメソッドを提供します。
•
インタフェース Connection — グローバル・データベース接続をカプセル化し、セッション制御およびトランザクション
処理を行うメソッドを提供します。
•
インタフェース GlobalsDirectory — 現在のネームスペースのグローバル名の参照可能ディレクトリを表します。
•
インタフェース NodeReference — グローバル・ノードへの参照をカプセル化し、ノードにアクセスおよび操作するた
めの数多くのメソッドを提供します。
•
インタフェース ValueList — Caché $LIST オブジェクトの Java 表現をカプセル化します。
•
クラス ByteArrayRegion — いくつかの Connection メソッドで使用され、byte 配列のサブセットを指定します。
•
グローバル例外クラス — ほとんどのグローバル API メソッドによってスローされる例外を実装します。
•
グローバル実装クラス — com.intersys.globals.imp ネームスペースのクラス。グローバル API インタフェースを実装
し、それを特別な目的のために拡張できるようにします。
5.3.1 グローバル API メソッドのリスト
このリファレンスでは、以下のグローバル API のクラスおよびメソッドを説明します。
クラス ConnectionContext
•
getConnection() — Connection オブジェクトを作成します。
Caché eXTreme での Java の使用法 101
eXTreme クラスのクイック・リファレンス
インタフェース Connection
•
callBytesClassMethod() — Caché クラス・メソッドを呼び出します。文字列値が byte[] として返されること以
外は callClassMethod() と同一です。
•
callBytesFunction() — Caché 関数を呼び出します。文字列値が byte[] として返されること以外は
callFunction() と同一です。
•
callClassMethod() — Caché クラス・メソッドを呼び出します。
•
callFunction() — Caché 関数を呼び出します。
•
callProcedure() — Caché プロシージャを呼び出します。
•
callVoidClassMethod() — 返り値のない Caché クラス・メソッドを呼び出します。
•
close() — このインスタンスで保持されているすべてのリソースを解放します。
•
commit() — 1 レベルのトランザクションをコミットします。
•
connect() — 指定された引数を使用して Caché に接続します。
•
createGlobalsDirectory() — 現在のネームスペースのグローバル名の参照可能ディレクトリを作成します。
•
createList() — 空の ValueList オブジェクトを返します。
•
createNodeReference() — NodeReference オブジェクトを返します。オプションで、グローバル名を指定しま
す。
•
getNamespace() — 現在のネームスペース文字列を返します。
•
getProductVersion() 接続されている Caché インスタンスのバージョン番号を返します。
•
isConnected() — このオブジェクトがデータベースに接続されている場合、True を返します。
•
releaseAllLocks() — このセッションで現在保持されているすべてのロックを解放します。
•
rollback() — 指定された数のトランザクション・レベルをロールバックするか、数が指定されていない場合、
すべてのレベルのトランザクションをロールバックします。
•
setNamespace() — 現在のネームスペースを設定します。
•
startTransaction() — トランザクション (入れ子になったトランザクションの場合あり) を開始します。
•
transactionLevel() — 現在のトランザクション・レベル (トランザクション内でない場合は 0) を返します。
インタフェース GlobalsDirectory
•
close() — オブジェクトが破棄される際のリソース・リークを回避するために、オブジェクトの基本となるリソー
スを解放します。
•
nextGlobalName() — 指定された文字列の後の照合順で次のグローバル名を取得します。
•
previousGlobalName() — 指定された文字列の前の照合順で前のグローバル名を取得します。
•
refresh() — ディレクトリを更新し、オブジェクト作成または最新の更新後のすべての追加または削除を反映
します。
インタフェース NodeReference
•
acquireLock() — 指定されたロック引数を使用して現在のノードをロックします。
•
appendSubscript() — 指定された添え字を添え字リストの最後に追加します。
•
close() — オブジェクトが破棄される際のリソース・リークを回避するために、オブジェクトの基本となるリソー
スを解放します。
102 Caché eXTreme での Java の使用法
グローバルのクイック・リファレンス
•
exists() — このノードにデータが含まれている場合、True を返します。
•
getBytes() — このノードの値を byte[] として返します。
•
getDouble() — このノードの値を double として返します。
•
getDoubleSubscript() — 指定された添え字の値を double として返します。
•
getInt() — このノード・オブジェクトの値を int として返します。
•
getIntSubscript() — 指定された添え字の値を int として返します。
•
getList() — このノードの値を ValueList として返します。
•
getLong() — このノードの値を long として返します。
•
getLongSubscript() — 指定された添え字の値を long として返します。
•
getName() — 現在のグローバル名を返します。
•
getObject() — このノードの値を Object として返します。
•
getObjectSubscript() — 指定された添え字の値を Object として返します。
•
getOption() — 現在のロック・タイムアウト設定を返します。
•
getString() — このノードの値を String として返します。
•
getStringSubscript() — 指定された添え字の値を String として返します。
•
getSubscriptCount() — 現在の添え字数を示す int を返します。
•
hasSubnodes() — このノードに下位ノードが含まれている場合、True を返します。
•
increment() — ノード値を指定された数だけインクリメントし、新しい値を long として返します。
•
kill() — ノードおよびすべての下位ノードを削除します。
•
killNode() — ノードを削除しますが、その下位ノードは削除しません。
•
nextSubscript() — 次のノードの添え字を含む String を返します。
•
previousSubscript() — 前のノードの添え字を含む String を返します。
•
releaseLock() — 現在のノードのロックをすぐに解放するか、またはセッションの最後に解放します。
•
set() — ノードの値を指定された値に設定します。
•
setName() — このノード・オブジェクトに参照されるグローバルの名前を設定します。
•
setOption() — タイムアウトになるまで acquireLock() がロックを待機する時間 (秒) を設定します。
•
setSubscript() — 指定された添え字の値を設定します。
•
setSubscriptCount() — 添え字の数を減らします (余分な末尾の添え字を破棄します)。
acquireLock() および releaseLock() で使用される有効な引数のリストについては、“グローバル API の使用法”
の章の “ ロックの取得および解放” も参照してください。SetOption() および GetOption() によって使用される
引数の詳細は、“タイムアウト間隔の制御” を参照してください。
インタフェース ValueList
•
append() — 指定されたデータ型の値をリストに追加します。1 回の呼び出しで複数の値を指定できます。
•
clear() — リストをクリアして、これに含まれる項目の数を 0 にします。
•
close() — オブジェクトが破棄される際のリソース・リークを回避するために、オブジェクトの基本となるリソー
スを解放します。
Caché eXTreme での Java の使用法 103
eXTreme クラスのクイック・リファレンス
•
getAll() — リストからすべての項目を Object の配列として返します。必要に応じて、文字列を byte[] として
返すこともできます。
•
getNextBytes() — リストから次の項目を byte の配列として返します。
•
getNextDouble() — リストから次の項目を double として返します。
•
getNextInt() — リストから次の項目を int として返します。
•
getNextList() — リストから次の項目を ValueList として返します。
•
getNextLong() — リストから次の項目を long として返します。
•
getNextObject() — リストから次の項目を Object として返します。必要に応じて、文字列を byte[] として返
すこともできます。
•
getNextString() — リストから次の項目を String として返します。
•
length() — リストの項目数を返します。
•
resetToFirst() — カーソルをリストの先頭にリセットします。
•
skipNext() — 値を取得せずに、リスト項目の指定数を過ぎたところまでカーソルを進めます。
クラス ByteArrayRegion
•
getLength() — 指定された領域内のバイト数を返します。
•
getOffset() — ソース配列内の領域の開始オフセットを返します。
•
getSourceArray() — 領域を含むソース配列を返します。
•
set() — 領域のすべての属性を定義します。
•
setLength() — 領域に含めるバイト数を設定します。
•
setOffset() — ソース配列内の領域の開始オフセットを設定します。
•
setSourceArray() — 領域を含むソース配列を設定します。
グローバル例外クラス
•
GlobalsException — ほとんどのグローバル API メソッドによりスローされます。
•
LockException — NodeReference メソッドの acquireLock() によりスローされます。
•
UndefinedException — ノードの値を取得するメソッドによりスローされます。
グローバル実装クラス
•
クラス ConnectionImpl — Connection インタフェースを実装します。
•
クラス GlobalsDirectoryImpl — GlobalsDirectory インタフェースを実装します。
•
クラス NodeReferenceImpl — NodeReference インタフェースを実装します。
•
クラス ValueListImpl — ValueList インタフェースを実装します。
5.3.2 クラス ConnectionContext
クラス com.intersys.globals.ConnectionContext は、グローバル API Connection オブジェクトを作成するために必要で
す。使用法に関する詳細は、“グローバル API の使用法” の “接続の作成” のセクションを参照してください。接続オ
プションの詳細は、"Caché JavaDoc" (<cache-root>/dev/java/doc/index.html) を参照してください。
104 Caché eXTreme での Java の使用法
グローバルのクイック・リファレンス
getConnection()
ConnectionContext.getConnection() は、グローバル API Connection のインスタンスを作成します。接続オブ
ジェクトは、Connection.connect() の呼び出しが行われるまで、データベースに接続されません。
static synchronized Connection getConnection()
5.3.3 インタフェース Connection
インタフェース com.intersys.globals.Connection は、グローバル・セッションを表します。グローバル永続データにアクセ
スするには、その前にこれを開始する必要があります。Connection のインスタンスは、クラス ConnectionContext の
getConnection() メソッドの呼び出しによって作成されます。使用法の詳細は、“接続の作成” を参照してください。
callBytesClassMethod()
Connection.callBytesClassMethod() — Caché ObjectScript クラス・メソッドを呼び出し、0 個以上の引数を渡し、
メソッドの返り値を byte[]、Integer、Long、または Double のインスタンスとして返します。
このメソッドは、callClassMethod() と同一ですが、それが文字列値を String ではなく byte[] のインスタンスとし
て返す点が異なります。
Object callBytesClassMethod(String className, String methodName, Object... args)
パラメータ :
•
className — 呼び出されるメソッドが属する Caché クラスの完全修飾名。
•
methodName — Caché クラス・メソッドの名前。
•
args — メソッドに渡す 0 個以上の引数のリスト。
引数は、String、Integer、Long、Double、byte[]、または ByteArrayRegion 型のいずれかになります。末尾
の引数は、省略できます。すべての引数の数よりも少ない数の引数が渡されるか、末尾の引数に対して
null が渡されることでそれらの引数には既定の値が使用されるようになります。非 null 引数が null 引数
の右側に渡されると例外がスローされます。
callBytesFunction()
Connection.callBytesFunction() は、Caché ObjectScript 関数を呼び出します ("Caché ObjectScript の使用
法" の “ユーザ定義コード” を参照してください)。
このメソッドは、callFunction() と同一ですが、それが文字列値を String ではなく byte[] のインスタンスとして返
す点が異なります。
Object callBytesFunction(String functionName, String routineName, Object... args)
パラメータ :
•
functionName — 関数の名前。
•
routineName — 関数を含むルーチンの名前。
•
args — 渡される引数。
引数は、String、Integer、Long、Double、byte[]、または ByteArrayRegion 型のいずれかになります。末尾
の引数は、省略できます。すべての引数の数よりも少ない数の引数が渡されるか、末尾の引数に対して
null が渡されることでそれらの引数には既定の値が使用されるようになります。非 null 引数が null 引数
の右側に渡されると例外がスローされます。
Caché eXTreme での Java の使用法 105
eXTreme クラスのクイック・リファレンス
callClassMethod()
Connection.callClassMethod() — Caché ObjectScript クラス・メソッドを呼び出し、0 個以上の引数を渡し、メソッ
ドの返り値を String、Integer、Long、または Double のインスタンスとして返します (値を返さないメソッドを呼び
出すには callVoidClassMethod() を使用します)。
callBytesClassMethod() メソッドも参照してください。それは、このメソッドと同一ですが、文字列値を String で
はなく byte[] のインスタンスで返す点が異なります。
Object callClassMethod(String className, String methodName, Object... args)
パラメータ :
•
className — 呼び出されるメソッドが属する Caché クラスの完全修飾名。
•
methodName — Caché クラス・メソッドの名前。
•
args — メソッドに渡す 0 個以上の引数のリスト。
引数は、String、Integer、Long、Double、byte[]、または ByteArrayRegion 型のいずれかになります。末尾
の引数は、省略できます。すべての引数の数よりも少ない数の引数が渡されるか、末尾の引数に対して
null が渡されることでそれらの引数には既定の値が使用されるようになります。非 null 引数が null 引数
の右側に渡されると例外がスローされます。
callFunction()
Connection.callFunction() は、Caché ObjectScript 関数を呼び出します ("Caché ObjectScript の使用法" の
“ユーザ定義コード” を参照してください)。
callBytesFunction() メソッドも参照してください。それは、このメソッドと同一ですが、文字列値を String ではな
く byte[] のインスタンスで返す点が異なります。
Object callFunction(String functionName, String routineName, Object... args)
パラメータ :
•
functionName — 関数の名前。
•
routineName — 関数を含むルーチンの名前。
•
args — 渡される引数。
引数は、String、Integer、Long、Double、byte[]、または ByteArrayRegion 型のいずれかになります。末尾
の引数は、省略できます。すべての引数の数よりも少ない数の引数が渡されるか、末尾の引数に対して
null が渡されることでそれらの引数には既定の値が使用されるようになります。非 null 引数が null 引数
の右側に渡されると例外がスローされます。
callProcedure()
Connection.callProcedure() は、Caché ObjectScript プロシージャを呼び出します ("Caché ObjectScript の使
用法" の “ユーザ定義コード” を参照してください)。
void callProcedure(String procedureName, String routineName, Object... args)
パラメータ :
•
procedureName — プロシージャの名前。
•
routineName — プロシージャを含むルーチンの名前。
•
args — 渡される引数。
106 Caché eXTreme での Java の使用法
グローバルのクイック・リファレンス
引数は、String、Integer、Long、Double、byte[]、または ByteArrayRegion 型のいずれかになります。末尾
の引数は、省略できます。すべての引数の数よりも少ない数の引数が渡されるか、末尾の引数に対して
null が渡されることでそれらの引数には既定の値が使用されるようになります。非 null 引数が null 引数
の右側に渡されると例外がスローされます。
callVoidClassMethod()
Connection.callVoidClassMethod() — 返り値のない Caché ObjectScript クラス・メソッドを呼び出し、0 個以上
の引数を渡します。このメソッドは、呼び出し側で返り値を必要としない場合に、任意の Caché クラス・メソッド
(それが通常、値を返すかどうかにかかわらず) を呼び出すために使用できます。値を返すメソッドを呼び出す
には、callClassMethod() を使用します。
void callVoidClassMethod(String className, String methodName, Object... args)
パラメータ :
•
className — 呼び出されるメソッドが属する Caché クラスの完全修飾名。
•
methodName — Caché クラス・メソッドの名前。
•
args — メソッドに渡す 0 個以上の引数のリスト。
•
引数は、String、Integer、Long、Double、byte[]、または ByteArrayRegion 型のいずれかになります。末尾
の引数は、省略できます。すべての引数の数よりも少ない数の引数が渡されるか、末尾の引数に対して
null が渡されることでそれらの引数には既定の値が使用されるようになります。非 null 引数が null 引数の
右側に渡されると例外がスローされます。
close()
Connection.close() は、このインスタンスで保持されているすべてのリソースを解放します。
void close()
Connection のインスタンスが範囲外になる前に、そのインスタンスで必ず close() を呼び出すことが重要です。
それを閉じないと、深刻なメモリ・リークが発生することがあります。それは、Java ガーベッジ・コレクションでは、
基盤となるネイティブ・コードによって割り当てられたリソースを解放できないためです。
commit()
Connection.commit() は、現在のセッションの 1 レベルのトランザクション ("transactionLevel()" を参照) をコミッ
トします。
void commit()
レベルが 1 より大きい場合、現在のトランザクションは、エンクロージング・トランザクションとマージされます。そ
れでもなお、rollback() を呼び出すことによってロールバックできます。トランザクション・レベルが 1 の場合、トラ
ンザクション中に行われた変更は永続的にコミットされます。
connect()
Connection.connect() は、Connection オブジェクトを指定されたデータベースに接続します。オブジェクトが既
に接続されている場合、GlobalsException がスローされます。
void connect()
void connect(String namespace, String user, String password)
パラメータ :
•
namespace — アクセス先のネームスペース。
Caché eXTreme での Java の使用法 107
eXTreme クラスのクイック・リファレンス
•
user — この接続のユーザ名。
•
password — この接続のパスワード。
このメソッドは、GLOBALS_HOME 環境変数を使用して、Caché インスタンスを検出します (“すべてのプラット
フォームに対して必須の環境変数” を参照)。
createGlobalsDirectory()
Connection.createGlobalsDirectory() は、現在のネームスペースのグローバル名の参照可能ディレクトリを作成
し、照合順序で最初のグローバル名の前にカーソルを配置します。
GlobalsDirectory createGlobalsDirectory()
createList()
Connection.createList() は ValueList オブジェクトを返し、必要に応じてバッファ・サイズを指定します。
ValueList createList()
ValueList createList(int bufferSize)
パラメータ :
•
bufferSize — 基礎となるバッファの初期サイズ (バイト単位)。
bufferSize が指定されない場合、ValueList が 1 KB のバッファで作成されます。これを必要に応じて大きくしま
すが、これより小さくはなりません。リストが 1 KB よりも大幅に少なくて済むことがわかっている場合、bufferSize
をより小さく指定するほうがメモリの節約になることがあります。リストが 1 KB を大幅に超えることがわかっている
場合、bufferSize をより大きく指定すると、バッファを増やすための配置転換の繰り返しを回避でき、パフォーマ
ンスが向上する場合があります。
createNodeReference()
Connection.createNodeReference() NodeReference オブジェクトを返し、オプションで参照されるグローバルの
名前を指定します。
NodeReference createNodeReference()
NodeReference createNodeReference(String name)
パラメータ :
•
name — 参照されるグローバルの名前を指定するオプションの String。
name が指定されない場合、グローバル配列を指定するために、ノード参照オブジェクトの setName() メソッドを
呼び出す必要があります (“グローバル名の設定と変更” を参照)。
getNamespace()
Connection.getNamespace() は、現在接続されているネームスペースの名前を返します。このインスタンスが接
続されていないときに呼び出されると GlobalsException をスローします。
String getNamespace()
このインスタンスが接続されていないときに呼び出されると GlobalsException をスローします。
getProductVersion()
Connection.getProductVersion() は、接続されている Caché インスタンスのバージョン番号を返します。
String getProductVersion()
108 Caché eXTreme での Java の使用法
グローバルのクイック・リファレンス
isConnected()
Connection.isConnected() は、このオブジェクトがデータベースに接続されている場合、true を返します。
boolean isConnected()
releaseAllLocks()
Connection.releaseAllLocks() は、この接続で現在保持されているすべてのロックを解放します。
void releaseAllLocks()
関連項目 : トランザクションとロック
rollback()
Connection.rollback() は、levelCount レベルのトランザクションをロールバックするか、levelCount が指定され
ていない場合は、すべてのレベルのトランザクションをロールバックします。
void rollback()
void rollback(int levelCount)
パラメータ :
•
levelCount — ロールバックするレベルの数。
levelCount が最初のトランザクション・レベルより大きい場合、トランザクション・レベルが 0 に到達するとロール
バックは停止します。levelCount が負の数の場合は、何もしません。
関連項目 : トランザクションとロック
setNamespace()
Connection.setNamespace() は、現在のネームスペースを設定します。
void setNamespace(String namespace)
パラメータ :
•
namespace — この接続のネームスペース。
startTransaction()
Connection.startTransaction() は、トランザクション (入れ子になったトランザクションの場合あり) を開始します。
void startTransaction()
関連項目 : トランザクションとロック
transactionLevel()
Connection.transactionLevel() は、現在のトランザクション・レベル (トランザクション内でない場合は 0) を示す
int を返します。
int transactionLevel()
関連項目 : トランザクションとロック
Caché eXTreme での Java の使用法 109
eXTreme クラスのクイック・リファレンス
5.3.4 インタフェース GlobalsDirectory
インタフェース com.intersys.globals.GlobalsDirectory は、現在のネームスペースのグローバルの名前の参照可能ディ
レクトリを表します。グローバル名は、照合の昇順または降順で参照できます。これらの名前を Connection.createNodeReference(String) に渡し、グローバルに対する処理を実行するために使用できる NodeReference のインスタンスを作成で
きます。
GlobalsDirectory のインスタンスは、Connection.createGlobalsDirectory() メソッドを呼び出すことによって、または
GlobalsDirectoryImpl コンストラクタを使用して作成されます。
close()
GlobalsDirectory.close() は、このインスタンスで保持されているすべてのリソースを解放します。
void close()
GlobalsDirectory のインスタンスが範囲外になる前に、そのインスタンスで必ず close() を呼び出すことが重要
です。それを閉じないと、深刻なメモリ・リークが発生することがあります。それは、Java ガーベッジ・コレクション
では、基盤となるネイティブ・コードによって割り当てられたリソースを解放できないためです。
nextGlobalName()
GlobalsDirectory.nextGlobalName() は、指定した名前の後 (グローバル名が指定されていない場合は、現在の
位置の後) の照合順で次のグローバル名を返します。次の名前がない場合は、空の文字列を返します。
String nextGlobalName()
String nextGlobalName(String globalName)
パラメータ :
•
globalName — 開始位置として使用する文字列 (既存のグローバル名を指定する必要はありません)。照
合順で最初のグローバル名を取得するには、空の文字列 ("") を指定します。
previousGlobalName()
GlobalsDirectory.previousGlobalName() は、指定した名前の前 (グローバル名が指定されていない場合は、現
在の位置の前) の照合順で前のグローバル名を返します。前の名前がない場合は、空の文字列を返します。
String previousGlobalName()
String previousGlobalName(String globalName)
パラメータ :
•
globalName — 開始位置として使用する文字列 (既存のグローバル名を指定する必要はありません)。照
合順で最後のグローバル名を取得するには、空の文字列 ("") を指定します。
Refresh()
GlobalsDirectory.refresh() は、グローバル名のリストを更新し、名前を追加または削除して、インスタンスの作成
以降または refresh() の最後の呼び出し以降に行われた変更をすべて反映します。
void refresh()
110 Caché eXTreme での Java の使用法
グローバルのクイック・リファレンス
5.3.5 インタフェース NodeReference
インタフェース com.intersys.globals.NodeReference は、グローバル・ノードへの参照を表します。ノードの名前および
添え字を指定するメソッド、およびノードを操作するメソッド (ノードの値の設定、取得、ならびに削除、ノードの値の状態
の判別、およびノードの値のインクリメントなど) を提供します。
NodeReference のインスタンスは、Connection の createNodeReference() メソッドの呼び出しによって作成されます。使
用法に関する詳細は、“グローバル API の使用法” の章を参照してください。
acquireLock()
NodeReference.acquireLock() は、指定されたロック引数を使用して、オブジェクトをロックします。
void acquireLock(int lockType, int lockMode)
void acquireLock(int lockType, int lockMode, Object... subscripts)
パラメータ :
•
lockType — 以下の値のいずれかを指定します。
–
NodeReference.SHARED_LOCK — 共有ロックは、他の呼び出し元が共有ロックを取得することは許
可しますが、どの呼び出し元も排他ロックを取得できないようにします。ノード値は、すべての共有ロッ
クが解放されるまで変更できません。
–
NodeReference.EXCLUSIVE_LOCK — 排他ロックは、他の呼び出し元がロックを取得できないように
し、ノード値の安全な変更を可能にします。
•
lockMode — 以下の値のいずれかを指定します。
–
NodeReference.LOCK_INCREMENTALLY — 以前から保持されているロックを解放せずに、増分ロッ
クが取得されます。
–
NodeReference.LOCK_NON_INCREMENTALLY — 増分でないロックは、以前から保持されているロッ
クをすべて解放します。
•
subscripts — ノード参照を修飾する 0 個以上のオプションの添え字 (“ターゲットのサブノードのアドレ
ス指定” を参照)。
関連項目 : トランザクションとロック
appendSubscript()
NodeReference.appendSubscript() は、新しい添え字をノード参照オブジェクトの添え字リストの最後に追加しま
す。
void
void
void
void
appendSubscript(int sub)
appendSubscript(long sub)
appendSubscript(double sub)
appendSubscript(String sub)
パラメータ :
•
sub — 指定する添え字は、int、long、double、または String のいずれかです。
例えば、このメソッドは、添え字 "a" を ^myGlobal(1) に追加し、この参照を ^myGlobal(1,"a") に変更できます。
close()
NodeReference.close() は、このインスタンスで保持されているすべてのリソースを解放します。
Caché eXTreme での Java の使用法 111
eXTreme クラスのクイック・リファレンス
void close()
NodeReference のインスタンスが範囲外になる前に、そのインスタンスで必ず close() を呼び出すことが重要で
す。それを閉じないと、深刻なメモリ・リークが発生することがあります。それは、Java ガーベッジ・コレクションで
は、基盤となるネイティブ・コードによって割り当てられたリソースを解放できないためです。
exists()
NodeReference.exists() は、このノードにデータが含まれている場合、True を返します。このノードが値なしま
たは存在しない場合、False を返します。
boolean exists()
boolean exists(Object... subscripts)
パラメータ :
•
subscripts — ノード参照を修飾する 0 個以上のオプションの添え字 (“ターゲットのサブノードのアドレ
ス指定” を参照)。
getBytes()
NodeReference.getInt() は、このノードの値を byte[] として返します。参照されるノードが値なしまたは存在し
ない場合、NULL を返します。
byte[] getBytes()
byte[] getBytes(Object... subscripts)
パラメータ :
•
subscripts — ノード参照を修飾する 0 個以上のオプションの添え字 (“ターゲットのサブノードのアドレ
ス指定” を参照)。
getDouble()
NodeReference.getDouble() は、このノードの値を double として返します。参照されるノードが値なしまたは存
在しない場合、UndefinedException をスローします。ノード値が String になっている可能性がある場合は、こ
のメソッドは使用しないでください。
double getDouble()
double getDouble(Object... subscripts)
パラメータ :
•
subscripts — ノード参照を修飾する 0 個以上のオプションの添え字 (“ターゲットのサブノードのアドレ
ス指定” を参照)。
String 値は、それが数字であったとしても変換されません。このメソッドは文字列を有効な IEEE の double 型と
して解釈しようとし、無意味で予測不可能な値を返します。
getDoubleSubscript()
NodeReference.getDoubleSubscript() は、subscriptPosition によって指定された添え字を評価し、double 値と
して返します。
double getDoubleSubscript(int subscriptPosition)
パラメータ :
•
subscriptPosition — 評価される添え字のレベル番号 (添え字はレベル 1 からカウント・アップします)。
subscriptPosition が現在の添え字の数より大きい場合、GlobalsException エラーがスローされます。
112 Caché eXTreme での Java の使用法
グローバルのクイック・リファレンス
subscriptPosition が現在の添え字の数より大きい場合、GlobalsException がスローされます。
getInt()
NodeReference.getInt() は、このノードの値を int として返します。参照されるノードが値なしまたは存在しない
場合、UndefinedException をスローします。
int getInt()
int getInt(Object... subscripts)
パラメータ :
•
subscripts — ノード参照を修飾する 0 個以上のオプションの添え字 (“ターゲットのサブノードのアドレ
ス指定” を参照)。
ノード値は、元々 double として設定された場合、整数値に切り捨てられます。ノード値が数値でない文字列
(+、-、または数字で始まらない文字列) の場合、0 が返されます。
参照されるノードが値なしまたは存在しない場合、UndefinedException をスローします。
getIntSubscript()
NodeReference.getIntSubscript() は、subscriptPosition によって指定された添え字を評価し、int 値として返し
ます。
int getIntSubscript(int subscriptPosition)
パラメータ :
•
subscriptPosition — 評価される添え字のレベル番号 (添え字はレベル 1 からカウント・アップします)。
subscriptPosition が現在の添え字の数より大きい場合、GlobalsException がスローされます。
getList()
NodeReference.getList() は、このノードの値を ValueList として返します。参照されるノードが値なしまたは存
在しない場合、NULL を返します。
ValueList
ValueList
ValueList
ValueList
getList()
getList(Object... subscripts)
getList(ValueList reuseList)
getList(ValueList reuseList, Object... subscripts)
パラメータ :
•
reuseList — 変更されて返される ValueList のオプションの既存のインスタンス。
•
subscripts — ノード参照を修飾する 0 個以上のオプションの添え字 (“ターゲットのサブノードのアドレ
ス指定” を参照)。
getLong()
NodeReference.getLong() は、このノードの値を long として返します。
long getLong()
long getLong(Object... subscripts)
パラメータ :
•
subscripts — ノード参照を修飾する 0 個以上のオプションの添え字 (“ターゲットのサブノードのアドレ
ス指定” を参照)。
Caché eXTreme での Java の使用法 113
eXTreme クラスのクイック・リファレンス
参照されるノードが値なしまたは存在しない場合、UndefinedException をスローします。
getLongSubscript()
NodeReference.getLongSubscript() は、subscriptPosition によって指定された添え字を評価し、long 値として
返します。
long getLongSubscript(int subscriptPosition)
パラメータ :
•
subscriptPosition — 評価される添え字のレベル番号 (添え字はレベル 1 からカウント・アップします)。
subscriptPosition が現在の添え字の数より大きい場合、GlobalsException がスローされます。
getName()
NodeReference.getName() は、このノードを含むグローバル配列の名前を返します。
String getName()
getObject()
NodeReference.getObject() は、Integer、Long、Double、または String のインスタンスになる Object としてノー
ド値を返します (byte[] および ValueList は String に評価されます)。このノードが値なしの場合、NULL を返し
ます。
Object getObject()
Object getObject(Object... subscripts)
パラメータ :
•
subscripts — ノード参照を修飾する 0 個以上のオプションの添え字 (“ターゲットのサブノードのアドレ
ス指定” を参照)。
getObjectSubscript()
NodeReference.getObjectSubscript() は、Integer、Long、Double、または String のインスタンスになる Object
として subscriptPosition によって指定される添え字を返します。
Object getObjectSubscript(int subscriptPosition)
subscriptPosition がこのノード・レベルより大きい場合、GlobalsException をスローします。
getOption()
NodeReference.getOption() は、 現在のロック・タイムアウト設定を返します ("setOption()" を参照)。
int getOption(int option)
パラメータ :
•
option — NodeReference.LOCK_TIMEOUT に設定する必要があります。将来のリリースには、その他のオ
プションも追加される予定です。
関連項目 : トランザクションとロック
getString()
NodeReference.getString() は、このノードの値を String として返します。参照されるノードが値なしまたは存在
しない場合、NULL を返します。
114 Caché eXTreme での Java の使用法
グローバルのクイック・リファレンス
String getString()
String getString(Object... subscripts)
パラメータ :
•
subscripts — ノード参照を修飾する 0 個以上のオプションの添え字 (“ターゲットのサブノードのアドレ
ス指定” を参照)。
ほぼすべてのグローバル値は文字列としてアクセスできます。ただし、アプリケーションのコンテキストでは文字
列は意味がないか、または紛らわしい場合があります。例えば、ノードが double 値の 19.95 に設定されてい
る場合、このメソッドで返される文字列は、double の内部表現である 19.949999999999999289 になります。
getStringSubscript()
NodeReference.getStringSubscript() は、subscriptPosition によって指定された添え字を評価し、String 値とし
て返します。
String getStringSubscript(int subscriptPosition)
パラメータ :
•
subscriptPosition — 評価される添え字のレベル番号 (添え字はレベル 1 からカウント・アップします)。
subscriptPosition が現在の添え字の数より大きい場合、GlobalsException がスローされます。
getSubscriptCount()
NodeReference.getSubscriptCount() は、現在の添え字数を示す int を返します。
int getSubscriptCount()
例えば、ノード参照が ^myGlobal(1,"a") を指している場合、このメソッドは 2 を返します。
hasSubnodes()
NodeReference.hasSubnodes() は、参照されるノードに下位ノードが含まれている場合、True を返します。
boolean hasSubnodes()
boolean hasSubnodes(Object... subscripts)
パラメータ :
•
subscripts — ノード参照を修飾する 0 個以上のオプションの添え字 (“ターゲットのサブノードのアドレ
ス指定” を参照)。
increment()
NodeReference.increment() は、現在のノードの値を、指定された int 値だけインクリメントまたはデクリメントし、
新しい値を long として返します。インクリメントされたノード値が double の場合、返される値は切り捨てられま
す。これは、ロックフリーかつスレッドセーフなアトミック処理です。
long increment(int number)
long increment(int number, Object... subscripts)
パラメータ :
•
number — ノード値をインクリメントする量を指定します。
•
subscripts — ノード参照を修飾する 0 個以上のオプションの添え字 (“ターゲットのサブノードのアドレ
ス指定” を参照)。
Caché eXTreme での Java の使用法 115
eXTreme クラスのクイック・リファレンス
現在の参照にノードが存在しない場合、値が 0 のノードが作成され、インクリメントされます。
kill()
NodeReference.kill() は、現在のノード参照にあるノードおよびその下位ノードすべてを削除します。
void kill()
void kill(Object... subscripts)
パラメータ :
•
subscripts — ノード参照を修飾する 0 個以上のオプションの添え字 (“ターゲットのサブノードのアドレ
ス指定” を参照)。
このメソッドは、Caché の KILL コマンドに相当します。
killNode()
NodeReference.killNode() は、現在のノード参照にあるノードを削除しますが、その下位ノードは削除しません。
void killNode()
void killNode(Object... subscripts)
パラメータ :
•
subscripts — ノード参照を修飾する 0 個以上のオプションの添え字 (“ターゲットのサブノードのアドレ
ス指定” を参照)。
このメソッドは、Caché の ZKILL コマンドに相当します。
nextSubscript()
NodeReference.nextSubscript() は、現在のレベルの照合順で次のノードの添え字を含む String を返します。
次の添え字がない場合は、空の文字列 ("") を返します。
String nextSubscript()
String nextSubscript(Object... subscripts)
パラメータ :
•
subscripts — ノード参照を修飾する 0 個以上のオプションの添え字 (“ターゲットのサブノードのアドレ
ス指定” を参照)。
previousSubscript()
NodeReference.previousSubscript() は、現在のレベルの照合順で前のノードの添え字を含む String を返しま
す。前の添え字がない場合は、空の文字列 ("") を返します。
String previousSubscript()
String previousSubscript(Object... subscripts)
パラメータ :
•
subscripts — ノード参照を修飾する 0 個以上のオプションの添え字 (“ターゲットのサブノードのアドレ
ス指定” を参照)。
releaseLock()
NodeReference.releaseLock() は、現在のノードのロックを解放します。
void releaseLock(int lockType, int releaseMode)
void releaseLock(int lockType, int releaseMode, Object... subscripts)
116 Caché eXTreme での Java の使用法
グローバルのクイック・リファレンス
パラメータ :
•
lockType — 以下の値のいずれかを指定します。
–
NodeReference.SHARED_LOCK — 共有ロックは、他の呼び出し元が共有ロックを取得することは許
可しますが、どの呼び出し元も排他ロックを取得できないようにします。ノード値は、すべての共有ロッ
クが解放されるまで変更できません。
–
NodeReference.EXCLUSIVE_LOCK — 排他ロックは、他の呼び出し元がロックを取得できないように
し、ノード値の安全な変更を可能にします。
•
releaseMode — 以下の値のいずれかを指定します。
–
NodeReference.RELEASE_IMMEDIATELY — すぐにロックを解放します。
–
NodeReference.RELEASE_AT_TRANSACTION_END — 現在のトランザクションが終了するまで待っ
てからロックを解放します。
•
subscripts — ノード参照を修飾する 0 個以上のオプションの添え字 (“ターゲットのサブノードのアドレ
ス指定” を参照)。
関連項目 : トランザクションとロック、Connection.releaseAllLocks()
set()
NodeReference.set() は、指定された値を参照されるノードに割り当てます。
void
void
void
void
void
void
void
void
void
void
void
void
set(int value)
set(int value, Object... subscripts)
set(long value)
set(long value, Object... subscripts)
set(double value)
set(double value, Object... subscripts)
set(String value)
set(String value, Object... subscripts)
set(byte[] value)
set(byte[] value, Object... subscripts)
set(ValueList value)
set(ValueList value, Object... subscripts)
パラメータ :
•
value — ノードに割り当てられる値。この値は、int、long、double、String、byte[]、または ValueList にでき
ます。
•
subscripts — ノード参照を修飾する 0 個以上のオプションの添え字 (“ターゲットのサブノードのアドレ
ス指定” を参照)。
現在の参照に永続ノードが存在しない場合、新しいノードが作成され、指定された値に設定されます。
setName()
NodeReference.setName() は、このノード・オブジェクトによって参照されるグローバルの名前を指定します。
void setName(String name)
パラメータ :
•
name — 参照されるグローバルの名前。
Caché eXTreme での Java の使用法 117
eXTreme クラスのクイック・リファレンス
setOption()
NodeReference.setOption() タイムアウトになるまで acquireLock() がロックを待機する時間 (秒) を設定します。
将来のリリースには、その他のオプションも追加される予定です。
void setOption(int option, int value)
パラメータ :
•
option — NodeReference.LOCK_TIMEOUT に設定する必要があります。
•
value — タイムアウトになるまで待機する秒数。任意の int 値を指定できます。また、以下の事前定義され
た値も使用できます。
–
NodeReference.DEFAULT_LOCK_TIMEOUT — 既定値は 10 です。
–
NodeReference.NO_LOCK_TIMEOUT — 値は -1 です。これは、呼び出しがタイムアウトにならない
ことを指定します (acquireLock() は永遠に待機します)。
setSubscript()
NodeReference.setSubscript() は、指定された添え字を変更するか、または新しい添え字を追加します。
void
void
void
void
setSubscript(int
setSubscript(int
setSubscript(int
setSubscript(int
subscriptPosition,
subscriptPosition,
subscriptPosition,
subscriptPosition,
double value)
int value)
long value)
String value)
パラメータ :
•
subscriptPosition — 設定される添え字のレベル番号 (添え字はレベル 1 からカウント・アップします)。
•
value — 添え字の値。この添え字は、int、long、double、または String にできます。
例えば、ノード参照が ^myGlobal(1,"a") を指している場合、setSubscript(1,8) を呼び出すと、参照は
^myGlobal(8,"a") に設定されます。
このメソッドは、subscriptPosition が getSubscriptCount()+1 と同じ場合、appendSubscript() と同等です。
例えば、setSubscript(3,"x") を呼び出すと、この参照は ^myGlobal(1,"a","x") に設定されます。
subscriptPosition が 1 未満の場合、1 の値が使用されます。
subscriptPosition が GetSubscriptCount()+1 より大きい場合、GlobalsException をスローします。
setSubscriptCount()
NodeReference.setSubscriptCount() は、num によって指定される添え字以降の添え字すべてを削除して添え
字リストを短縮します。
void setSubscriptCount(int num)
パラメータ :
•
num — 保持する最後の添え字のレベル番号 (添え字はレベル 1 からカウント・アップします)。
例えば、参照が ^myGlobal(1,"a",35) を指している場合、setSubscriptCount(1) を呼び出すと、最初の添
え字を除くすべての添え字が削除され、この参照が ^myGlobal(1) に変更されます。
num が現在の添え字の数より大きい場合、GlobalsException がスローされます。
118 Caché eXTreme での Java の使用法
グローバルのクイック・リファレンス
5.3.6 インタフェース ValueList
インタフェース com.intersys.globals.ValueList は、単純な Caché $LIST オブジェクトの Java 表現をカプセル化します。
以下のデータ型がサポートされます : int、Integer、long、Long、double、Double、String、byte[]、および ValueList の入
れ子にされたインスタンス。使用法の詳細は、“ValueList を使用したノードへの複数の項目の格納” を参照してくださ
い。ValueList オブジェクトは、Connection.createList() メソッドを呼び出すことによって、または ValueListImpl コンストラ
クタを使用することによって作成されます。
append()
ValueList.append() は指定されたデータ型の値をリストに追加します。
void
void
void
void
void
void
void
void
void
append(int value)
append(Integer value)
append(long value)
append(Long value)
append(double value)
append(Double value)
append(String value)
append(byte[] value)
append(ValueList value)
1 回の append() の呼び出しで複数の値を指定できます。
void append(Object... objects)
パラメータ :
•
value — 追加する項目の値。値が許可されているデータ型のいずれかでない場合、例外がスローされま
す。
•
objects — は、1 つ以上の Object インスタンスのリストです。各 Object は、データ型 Integer、Long、
Double、または String として評価される必要があります。これら以外の場合、例外がスローされます。byte[]
および ValueList のインスタンスは、String として評価されるため、有効です。
引数が無効なデータ型である場合、GlobalsException がスローされます。
clear()
ValueList.clear() はリストをクリアして、これに含まれる項目の数を 0 にします。
void clear()
GlobalsException をスローします。
close()
ValueList.close() は、このインスタンスで保持されているすべてのリソースを解放します。
void close()
ValueList のインスタンスが範囲外になる前に、そのインスタンスで必ず close() を呼び出すことが重要です。そ
れを閉じないと、深刻なメモリ・リークが発生することがあります。それは、Java ガーベッジ・コレクションでは、基
盤となるネイティブ・コードによって割り当てられたリソースを解放できないためです。
ValueList のインスタンスがこの後に他のメソッドを呼び出す場合、GlobalsException がスローされます。
Caché eXTreme での Java の使用法 119
eXTreme クラスのクイック・リファレンス
getAll()
ValueList.getAll() は、リストからすべての項目を Object の配列として返し、リストが空の場合は null を返しま
す。返される各 Object は、リスト内の項目の型および値に応じて、Integer、Long、Double、String、または byte[]
のインスタンスです。対応するリスト項目が null の場合、Object は null です。このメソッドは、リスト・カーソルを、
リストの最後の項目の後に配置します。
Object[] getAll()
Object[] getAll(boolean returnBytes)
パラメータ :
•
returnBytes — True の場合、文字列を byte[] として返し、それ以外の場合は String として返します。
GlobalsException をスローします。
getNextBytes()
ValueList.getNextBytes() は、リストから次の項目を byte[] として返します。リスト項目が null の場合、null が
返されます。
byte[] getNextBytes()
カーソルが既にリストの末尾にある場合、GlobalsException をスローします。
getNextDouble()
ValueList.getNextDouble() は、リストから次の項目を double として返します。リスト項目が null の場合、0 が返
されます。
double getNextDouble()
カーソルが既にリストの末尾にある場合、GlobalsException をスローします。
getNextInt()
ValueList.getNextInt() は、リストから次の項目を int として返します。リスト項目が null の場合、0 が返されます。
int getNextInt()
カーソルが既にリストの末尾にある場合、GlobalsException をスローします。
getNextList()
ValueList.getNextList() は、リストから次の項目を ValueList として返します。リスト項目が null の場合、null
が返されます。
ValueList getNextList()
ValueList getNextList(ValueList reuseList)
パラメータ :
•
reuseList — 変更されて返される ValueList のオプションの既存のインスタンス。reuseList に渡された
ValueList は、新しい ValueList インスタンスを作成するのではなく、項目の値を含むように変更され、返さ
れます。リスト項目が null の場合には変更されません。
カーソルが既にリストの末尾にある場合、または、リスト項目が有効な ValueList ではない場合、GlobalsException
をスローします。
120 Caché eXTreme での Java の使用法
グローバルのクイック・リファレンス
getNextLong()
ValueList.getNextLong() は、リストから次の項目を long として返します。リスト項目が null の場合、0 が返され
ます。
long getNextLong()
カーソルが既にリストの末尾にある場合、GlobalsException をスローします。
getNextObject()
ValueList.getNextObject() は、リストから次の項目を Object として返します。返されるオブジェクトの型は、リス
トの項目の型および値、ならびにオプションの returnBytes パラメータの設定に依存します。
リスト項目が NULL の場合、NULL が返されます。すべての整数値は、Integer の範囲内の場合には、Integer
として返され、それ以外の場合には Long として返されます。double 値は、常に Double として返されます。オプ
ションの returnBytes が true と指定されている場合、byte[] と String の両方が byte[] として返されます。こ
れが false または指定されていない場合、両方の型は、String として返されます。
Object getNextObject()
Object getNextObject(boolean returnBytes)
パラメータ :
•
returnBytes — True の場合には、byte[] と String の両方を byte[] として返し、それ以外の場合には、
両方の型を String. として返します。
カーソルが既にリストの末尾にある場合、GlobalsException をスローします。
getNextString()
ValueList.getNextString() は、リストから次の項目を String として返します。リスト項目が null の場合、null が
返されます。
String getNextString()
カーソルが既にリストの末尾にある場合、GlobalsException をスローします。
length()
ValueList.length() は、リストの項目数を返します。
int length()
GlobalsException をスローします。
resetToFirst()
ValueList.resetToFirst() は、カーソルをリストの先頭にリセットします。
void resetToFirst()
GlobalsException をスローします。
skipNext()
ValueList.skipNext() は、値を取得せずに、count で指定されたリスト項目の数を過ぎたところまでカーソルを進
めます。
void skipNext(int count)
Caché eXTreme での Java の使用法 121
eXTreme クラスのクイック・リファレンス
パラメータ :
•
count — スキップさせる項目の数
リスト内で、カーソルの位置より後に残っている項目数が count より少ない場合、GlobalsException をスローし
ます。
5.3.7 クラス ByteArrayRegion
クラス com.intersys.globals.ByteArrayRegion は、バイト配列の領域を指定し、ソース配列、開始オフセット、および領域
の長さをカプセル化します。このクラスは、領域を別の byte[] インスタンスにコピーすることなく、バイト配列領域を、
ObjectScript メソッドおよび関数を呼び出す Connection メソッドに引数として渡す便利で効率的な方法を提供します
(“ Caché メソッドの呼び出し” を参照)。
ByteArrayRegion() コンストラクタ
ByteArrayRegion の新しいインスタンスを作成します。オプションで、ソース配列、オフセット、領域内のバイト数
を指定できます。
ByteArrayRegion()
ByteArrayRegion(byte[] sourceArray, int offset, int length)
パラメータ :
•
sourceArray — 領域を含む配列。
•
offset — sourceArray 内の領域の開始オフセット。
•
length — 領域内のバイト数。
getLength()
ByteArrayRegion.getLength() は、指定された領域内のバイト数を返します。
int getLength()
getOffset()
ByteArrayRegion.getOffset() は、ソース配列内の領域の開始オフセットを返します。
int getOffset()
getSourceArray()
ByteArrayRegion.getSourceArray() は、領域を含むソース配列を返します。
byte[] getSourceArray()
set()
ByteArrayRegion.set() は領域のすべての属性を定義します。
void set(byte[] sourceArray, int offset, int length)
パラメータ :
•
sourceArray — 領域を含む配列。
•
offset — sourceArray 内の領域の開始オフセット。
•
length — 領域内のバイト数。
122 Caché eXTreme での Java の使用法
グローバルのクイック・リファレンス
setLength()
ByteArrayRegion.setLength() は、領域に含めるバイト数を設定します。
void setLength(int length)
パラメータ :
•
length — 領域内のバイト数。
setOffset()
ByteArrayRegion.setOffset()は、ソース配列内の領域の開始オフセットを設定します。
void setOffset(int offset)
パラメータ :
•
offset — 配列内の領域の開始オフセット。
setSourceArray()
ByteArrayRegion.setSourceArray() は、領域を含むソース配列を設定します。
void setSourceArray(byte[] sourceArray)
パラメータ :
•
sourceArray — 領域を含む配列。
5.3.8 グローバル例外クラス
グローバル API は、以下の例外を実装します。
•
GlobalsException — ほとんどのグローバル API メソッドによりスローされます。
•
LockException — NodeReference acquireLock() メソッドによりスローされます。
•
UndefinedException — ノードの値を取得するメソッドによりスローされます。
5.3.8.1 クラス GlobalsException
クラス com.intersys.globals.GlobalsException は、グローバル API のすべてのクラスによってスローされる例外を実装し
ます。このクラスは、java.lang.RuntimeException から継承されます。継承された getMessage() メソッドは、この
GlobalsException がスローされる原因となったユーザまたは内部エラーに関する特定の情報を示す表示可能なテキス
ト・メッセージを返すために使用できます。
コンストラクタ
RuntimeException コンストラクタに対して定義されるパラメータのほかにGlobalsException コンストラクタは、グ
ローバル API 固有のエラーに対するエラー・コード・パラメータを提供します。
GlobalsException(String msg)
GlobalsException(String msg, int code)
GlobalsException(Throwable cause)
GlobalsException(Throwable cause, String msg)
パラメータ :
•
msg — オプションの詳細エラー・メッセージ。
Caché eXTreme での Java の使用法 123
eXTreme クラスのクイック・リファレンス
•
code — GlobalsException メソッド getErrorCode() によって取得できるオプションのエラー・コード。
•
cause — java.lang.Throwable のインスタンス。
メソッド getErrorCode()
一部の特定のグローバル API エラーを区別するために使用できる数値のエラー・コードを返します。エラー・
コード UNDEFINED は、特定のエラー・コードがこの状況に対して定義されていないことを意味します。
int getErrorCode()
以下のエラー・コードが定義されています。
•
GlobalsException.METHOD_CALLED_AFTER_CLOSE
グローバル API オブジェクト・インスタンスで close() メソッドが呼び出された後に、メソッドが呼び出されまし
た。
•
GlobalsException.NOT_CONNECTED
接続されている必要があるメソッドが呼び出されましたが、接続が検出されませんでした。
•
GlobalsException.PARAMETER_OUT_OF_RANGE
パラメータ値が範囲外です。
•
GlobalsException.REQUIRED_PARAMETER_NULL
必須のメソッド・パラメータに NULL が渡されました。
•
GlobalsException.UNDEFINED
この GlobalsException がスローされる原因となったエラーに対して数値のエラー・コードが定義されていま
せん。
5.3.8.2 クラス LockException
クラス com.intersys.globals.LockException は、NodeReference メソッド acquireLock() によってスローされる例外を実装
します。これは、ロックが使用可能になるまでの待ち時間のタイムアウトのために、ロックを取得する要求が失敗した場合
にスローされます。使用法の詳細は、“トランザクションとロック” を参照してください。
コンストラクタ
LockException()
LockException(String msg)
パラメータ :
•
msg — オプションの詳細エラー・メッセージ。
このクラスは GlobalsException で定義されるメソッドおよび定数を継承します。
5.3.8.3 クラス UndefinedException
クラス com.intersys.globals.UndefinedException は、ノードの値を取得するメソッドによりスローされる例外を実装します。
参照されるノードが値なしまたは存在しない場合、例外がスローされます。
コンストラクタ
UndefinedException(String msg)
124 Caché eXTreme での Java の使用法
グローバルのクイック・リファレンス
パラメータ :
•
msg — 詳細エラー・メッセージ。
このクラスは GlobalsException で定義されるメソッドおよび定数を継承します。
5.3.9 グローバル実装クラス
以下のクラスは、主なグローバル API インタフェースの実装です。これらのクラスはすべて、コンストラクタを提供してお
り、特別な目的のために拡張可能です。
•
クラス ConnectionImpl — インタフェース ConnectionImpl の実装。
•
クラス GlobalsDirectoryImpl — インタフェース GlobalsDirectory の実装。
•
クラス NodeReferenceImpl — インタフェース NodeReferenceImpl の実装。
•
クラス ValueListImpl — インタフェース ValueListImpl の実装。
5.3.9.1 クラス ConnectionImpl
クラス com.intersys.globals.imp.ConnectionImpl は、インタフェース Connection の実装です。このクラスを拡張して、グ
ローバル API を使用して実装される API 用に特化された接続タイプを開発します。インタフェースのリストされているメ
ソッドのほかに以下のコンストラクタを提供します。
ConnectionImpl() コンストラクタ
基礎となる接続実装が ConnectionContext によって管理される 1 つの接続インスタンスである ConnectionImpl
の新規インスタンスを作成します。
ConnectionImpl()
5.3.9.2 クラス GlobalsDirectoryImpl
クラス com.intersys.globals.imp.GlobalsDirectoryImpl は、インタフェース GlobalsDirectory の実装です。インタフェース
のリストされているメソッドのほかに以下のコンストラクタを提供します。
GlobalsDirectoryImpl() コンストラクタ
現在のネームスペースにグローバル名のディレクトリを作成し、照合順序で最初のグローバル名の前に配置し
ます。
GlobalsDirectoryImpl()
グローバル・データベースへの Connection が存在しない場合、GlobalsException をスローします。
注釈
メソッド ConnectionImpl.createGlobalsDirectory() は、汎用 GlobalsDirectory インスタンスを作成します。この
API を拡張する開発者は、このメソッドをオーバーライドするか、追加の ConnectionImpl メソッドを提供して、
GlobalsDirectory から派生したクラスのインスタンスを作成できます。または、これらの派生クラスのパブリック・
コンストラクタ (これは GlobalsDirectoryImpl のパブリック・コンストラクタを呼び出します) を公開することもでき
ます。どちらの方法でも、GlobalsDirectoryImpl のインスタンスを作成する前に Connection のインスタンスが既
に接続されている必要があります。接続されていない場合は、GlobalsException がスローされます。
5.3.9.3 クラス NodeReferenceImpl
クラス com.intersys.globals.imp.NodeReferenceImpl は、インタフェース NodeReference の実装です。インタフェースに
リストされているメソッドのほかに以下のコンストラクタを提供します。
Caché eXTreme での Java の使用法 125
eXTreme クラスのクイック・リファレンス
NodeReferenceImpl() コンストラクタ
NodeReference のインスタンスを作成します。
NodeReferenceImpl()
NodeReferenceImpl(String name)
パラメータ :
•
name — オプションで、使用されるグローバル名を指定します。この引数を指定しない場合、後で setName()
を呼び出してグローバル名を設定できます。
グローバル・データベースへの Connection が存在しない場合、GlobalsException をスローします。
5.3.9.4 クラス ValueListImpl
クラス com.intersys.globals.imp.ValueListImpl は、インタフェース ValueList の実装です。インタフェースにリストされてい
るメソッドのほかに以下のコンストラクタを提供します。
ValueListImpl() コンストラクタ
空の ValueListImpl インスタンスを作成し、オプションで初期バッファ・サイズを指定します。
ValueListImpl()
ValueListImpl(int bufferSize)
パラメータ :
•
bufferSize — 基礎となるバッファの初期サイズ (バイト単位)。
bufferSize パラメータでは、リストの基礎となる実装用に使用されるメモリ量をオプションで調整できます。既
定では、ValueList は、1 KB のバッファで作成されます。これを必要に応じて大きくしますが、これより小さくは
なりません。リストが 1 KB よりも大幅に少なくて済むことがわかっている場合、bufferSize をより小さく指定す
るほうがメモリを節約できます。リストが 1 KB を大幅に超えることがわかっている場合、bufferSize をより大き
く指定すると、バッファを増やすための配置転換の繰り返しを回避でき、パフォーマンスを向上できます。
グローバル・データベースへの Connection が確立されていない場合、GlobalsException をスローします。
126 Caché eXTreme での Java の使用法