マッピングの方法
オブジェクトとレコードをどのように対応づけるか(マップするか)は複数の方法があるようだが、ここでは一つのやり方だけを示す。具合の悪い場合は別のやり方を探すこと。
AClassMapping
レコードにマップするクラスには、@AClassMappingアノテーションをつけるべきである。
@AClassMapping(mappingMode="modify", tableName="user") public class User { int id; String name; public int getId() { return id; } public void setId(int value) { id = value; } public String getName() { return name; } public void setName(String value) { name = value; } }
tableNameでマップするテーブル名を指定する。これを指定しないと、ORM側は自動的にテーブル名を推測しようとするがうまくいかない場合があるため、常に指定した方がよい。 mappingModeは"modify"か"manual"のいずれかで、デフォルトは"modify"であるため上の例は冗長である。
- modify:基本的にはオートマッピングを行うが、特にマッピングを指定されている場合はそれに従う。
- manual:全くオートマッピングを行わない。すべてのマッピング指定が必要。ただし、フィールドがプライマリキーであるかの判断はORMが勝手に行う。
下は、オートマッピングを全くしない場合の例。テーブル名を指定し、Getter,Setterにそれぞれフィールド名を指定している。databaseGenerated=trueはデータベース側で自動生成される値を示す(オートナンバーなど)。
@AClassMapping(mappingMode="manual", tableName="persons") public class Employee { @AGetterMapping(column="ID", databaseGenerated=true) public long employeeIdentification() {...} @ASetterMapping(column="ID") public void setEmployeeIdentitification(long id) {...} }
※基本的に一つのフィールドについてのGetterメソッド(レコード書き込み時にそのフィールド値をオブジェクトから取得するために用いる)とSetterメソッド(レコードからの読込み時にフィールド値をオブジェクトに設定するために用いる)の二つのメソッドが必要になる。
AGetterMapping
Getterは、ORMがレコード書き込み時にそのフィールド値をオブジェクトから取得するため、あるいはプライマリキーでの検索等を行う際にその値を取得するために用いられる。
オートマッピング時には特に@AGetterMappingアノテーションはなくてもよい。ORMが適当に判断してくれるが、オートマッピングでない場合あるいはオートマッピングでは困る場合は@AGetterMappingアノテーションを用いる。
@AGetterMappingアノテーションは以下のような形式である。
@AGetterMapping(columnName="field", columnType="number", includesInWrites=true, databaseGenerated=false) public int getSomething() { }
- columnName:フィールド名を指定する
- columnType:"number", "string", "date", "binary"のいずれかを指定する。例えば、Java上ではbooleanとして扱いたいが、データベース上ではそのような型が無い場合に"number"としておくと、ORMが勝手に変換する。
- includesInWrites:何らかの理由で、レコード上のこのフィールド値の書き込みを行いたくない場合にfalseとしておく。デフォルトはtrue。
- databaseGenerated:オートナンバーなどデータベースが勝手に生成する値についてはtrueを指定する。
ASetterMapping
SetterはORMがレコードフィールドから読み出した値をオブジェクトに設定するために用いられる。
Getterと同様にオートマッピング時で特に指定しなくても誤解の無い場合には@ASetterMappingを指定する必要はない。
@ASetterMapping(columnName="field", columnType="number") public void setSomething(int value) { }
考察
上述したように、レコードへのフィールド書き込み値を取得するためにはGetter、フィールドからの読込み値をオブジェクトに設定するためにはSetterメソッドが必要になる。 以下のようにオブジェクト自体にメンバーがあっても、それを読み書きに指定することはできない。
public class User {
- public String name;
}
特にSetterメソッドについては、フィールドから読込みのみならず、プログラム上でも値の指定に用いられるため、更新時には自動的に「プログラム上で変更されたもののみ」を書き戻すということをやって欲しいものだが、現在の仕組みではそのようなことは困難であろう(Hibernateはこれをやっているが)。