Javaアノテーションの利用法
それでは、データベーススキーマへのインデックス、制約、リレーションシップといった、より複雑な制御はどのように管理すればよいでしょうか。まずは、ここまでで解説したJalapeñoの機能をまとめてみましょう。
- SchemaBuilderウィザード
- ObjectManagerクラス
Jalapeñoには、このほかに「com.jalapeno.annotations」という、Javaアノテーションを定義したクラスのパッケージがあります。POJOクラスで定義されたアノテーションは、SchemaBuilderウィザードによって読み込まれます。このパッケージの機能は大きく2つに分かれます。
クラスレベルアノテーション
これを使って、POJOクラスをもとに生成するCachéのデータベーススキーマに、さまざまな機能を追加できます。主なクラスレベルアノテーションは次表の通りです。
アノテーション | 機能 |
@Access | アクセスレベルとアクセスタイプによって、Cachéクラスのマッピングを制限 |
@CacheClass | 主キーの指定やSQLテーブル名などの、データベーススキーマのクラスレベル情報を設定 |
@Index | データベーススキーマ内のインデックスを指定 |
@Embeddable | 生成されたデータベーススキーマが、シリアルか埋め込み可能かを指定 |
@ClassParameter | データベーススキーマのクラスレベルパラメータの指定 |
フィールドレベルアノテーション
リレーションシップ(依存関係)の定義などは、フィールドレベルアノテーションによって行います。主なフィールドレベルアノテーションは次表の通りです。
アノテーション | 機能 |
@ID | POJOプロパティがデータベースIDを表すことを指定 |
@CachePropert | 対応するCachéプロパティ名やプロパティタイプ、およびSQL名を指定 |
@Collection | フェッチ方法と、Cachéコレクションのタイプなどを指定 |
@Relationship | 対応するCachéクラスにリレーションシップを定義 |
それでは、アノテーションの利用例として、@Indexを使ったインデックス指定を実際に行ってみましょう。この例題では、次の2つのPOJOクラスを使います。Javaのパッケージ名は「contacts」としています。
package contacts; import java.util.ArrayList; import java.util.List; public class Contact { private Address primaryAddress; private String name; private String contactType; private List <PhoneNumber>phoneNumbers; //getters and setters follow ... }
package contacts; public class PhoneNumber { private String phoneNumberType; private Contact owner; private String number; //getters and setters follow ... }
この2つのPOJOクラスに、@Accessと@Indexアノテーションを使ってインデックスを定義しましょう。まず1番目の「Contact.java」ですが、Cachéのデータベーススキーマに対するインデックスを次のように指定します。
- com.jalapeno.annotationsをインポート
- @Accessアノテーションを使って、Cachéデータベーススキーマにフィールドに対応するプロパティを生成
- インデックス名は「NameIndex」とし、Cachéスキーマの
name
プロパティに定義 - このインデックスは一意ではなく、主キーとはしない
次の「Contact.java」コードは、@indexを使ってインデックスを定義した例です。
package contacts; import com.jalapeno.annotations.*; ……(1) import java.util.ArrayList; import java.util.List; @Access(type = AccessType.FIELD, level = AccessLevel.PRIVATE) ……(2) @Index(name = "NameIndex", propertyNames = { "name" }, ……(3) isUnique = false, isPrimaryKey = false) ……(4) public class Contact { ...
つづいて「PhoneNumber.java」も同じように修正しましょう。
package contacts; import com.jalapeno.annotations.*; @Access(type = AccessType.FIELD, level = AccessLevel.PRIVATE) @Index(name = "NumberIndex", propertyNames = { "number" }, isPrimaryKey = true) public class PhoneNumber { ...
PhoneNumber
クラスでは、Cachéスキーマのnumber
プロパティに主キーとしてNumberIndexを定義しました。そのほかのアノテーションの使い方など、その詳細については、Cachéキューブの「ドキュメント」にある、「Caché言語バインディング」-「CachéでのJalapeñoの使用法」を参照してください。
SchemaBuilderを使ったデータベーススキーマの変更
ここまでで、Jalapeñoを使えば、Cachéを意識することなくPOJOクラスの永続性を管理したプログラミングが可能なことがわかったかと思います。それでは、前回作成したbasic.Contact
クラスを修正して、データベーススキーマを変更してみましょう。
Javaクラスの変更とJalapeño SchemaBuilder
ここでは簡単な例として、basic.Contactに国名を入れてみましょう。
package basic; public class Contact { public String name; public String contactType; public String country; }
クラス定義を修正して、前回同様にSchemaBuilderを起動し設定します。前回は[Attempt to merge with existing Cache' classes]のチェックは付けないことになっていましたが、既存のデータベーススキーマを変更する際はこのチェックを付けてください。それでは、データベーススキーマが変更されたことを、Cachéシステム管理ポータルで確認しましょう。basic.Contactテーブルのカラムに「country」が追加されています。
データベーススキーマの生成と変更におけるSchemaBuilderの優位性
上記のように、クラス変更後にSchemaBuilderウィザードを使えば、簡単にデータベーススキーマが変更されることがわかったかと思いますが、実運用している環境では、データベースの詳細な検証はいずれにせよ必要です。実運用しているシステムでは、Javaアノテーションを使って細かな管理をしているはずです。そうした環境で、データベーススキーマを変更し、テストなしで稼働することはまずありえません。
しかし、Jalapeñoは、リレーショナルデータベースならばスキーマ変更後に必ず必要となるO/Rマッピングのやり直しをしなくて済みます。Jalapeñoは、Javaイントロスペクションを使用してPOJOクラス定義を分析し、対応するデータベーススキーマを生成します。このスキーマには、継承、コレクション、複雑なデータ型、リレーションシップなどのオブジェクトの特性を組み込むことや、インデックスや制約などのデータベースの特性を組み込むこともできます。これらの特性はすべて、標準的なJavaアノテーションを使用してデータベーススキーマに追加可能で、XMLマッピングドキュメントは必要ありません。Javaによる開発の工数削減(特にテーブル設計に関する工程)と、テーブル変更に伴う作業の大幅な削減ということから、コストパフォーマンスに優れたデータベースであると言えるでしょう。
まとめ
前回、今回の2回で、JalapeñoによるJavaアプリケーション開発について解説しました。そのすべてを解説することはかないませんが、概略は掴んでいただけたかと思います。さらに詳しくお知りになりたい方は、Cachéキューブの「ドキュメント」を参照してください。
次回からは、Cachéによる.NETアプリケーション開発について、前半・後半の2回に分けて解説します。