§Ebean ORM を使う
§Ebean の設定
Play 2.0 には Ebean ORM が同梱されています。有効にするには以下の行を conf/application.conf
に追加します。
ebean.default="models.*"
ここでは default
データソースを使用する default
Ebean サーバを定義していて、これは適切に設定する必要があります。 Ebean サーバは必要な分だけ作ることができ、また各サーバにマップされるクラスを明確に定義する事も出来ます。
ebean.orders="models.Order,models.OrderItem"
ebean.customers="models.Customer,models.Address"
この例では、2 つの Ebean サーバへのアクセスが設定されています。各サーバはそれぞれ異なるデータベースを使用しています。
(上記した) それぞれの ebean.
設定行は、Ebean が登録することに関心を持つ あらゆる クラス (例えば @Entity
/Model
クラス, @Embeddable
, カスタマイズした ScalarType
と CompoundType
, BeanPersistController
, BeanPersistListener
, BeanFinder
, ServerConfigStartup
, その他) とマッピングすることができます。
根底にある Ebean サーバの設定をカスタマイズするために、conf/ebean.properties
を追加するか、サーバが初期化される前に Ebean の ServerConfig
をプログラムから操作するために ServerConfigStartup
のインスタンスを作成することができます。
例えば、シーケンスのギャップを最小限にするためにシーケンスバッチサイズを減らすと言う、かなり一般的な問題は、以下のようなクラスによって、とてもシンプルに解決することができます。
package models;
import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebean.event.ServerConfigStartup;
public class MyServerConfigStartup implements ServerConfigStartup {
@Override
public void onStart(ServerConfig serverConfig) {
serverConfig.setDatabaseSequenceBatchSize(1);
}
}
Ebean は <entity-mappings>
を設定するために (もし存在すれば) conf/orm.xml
ファイルを活用することにも気を付けてください。
Ebean の詳細の情報については、 Ebean ドキュメント をご覧下さい。
§play.db.ebean.Model のスーパークラスを使う
Play 2.0 は Ebean モデルクラス向けの便利なスーパークラスを定義しています。Play 2.0 でマップされた典型的な Ebean クラスは以下のようになります。
package models;
import java.util.*;
import javax.persistence.*;
import play.db.ebean.*;
import play.data.format.*;
import play.data.validation.*;
@Entity
public class Task extends Model {
@Id
@Constraints.Min(10)
public Long id;
@Constraints.Required
public String name;
public boolean done;
@Formats.DateTime(pattern="dd/MM/yyyy")
public Date dueDate = new Date();
public static Finder<Long,Task> find = new Finder<Long,Task>(
Long.class, Task.class
);
}
実行時 に getter/setter を必要とするライブラリ (ORM、データバインダ、JSON バインダ、等) との互換性を保つため、Play はこれらを自動生成するように設計されてきました。 もしユーザが作成した getter/setter が Model で見つかった場合、Play は競合を避けるために getter/setter を生成しません。
警告:
(1) Ebean のクラス拡張はコンパイルの 後 に行われるので、**コンパイル時に Bbean が生成する getter/setter を利用できることを期待しないでください。** これらのメソッドを直接コーディングしたい場合は、getter/setter を自分で明示的に追加するか、例えばこれらを別のサブプロジェクトに配置するなどして、モデルクラスがプロジェクトの残りのクラスよりも前にコンパイルされることを保証してください。
(2) Ebean の (遅延評価を可能にする) フィールドに直接アクセスする拡張は、 Java クラスにのみ適用され、Scala には適用されません。このため、(Play 2 の標準テンプレートを含む) Scala ソースファイルからのフィールド直接アクセスは遅延評価を実行せず、その結果、エンティティのフィールドは往々にして空 (未設定) になります。フィールドが設定されていることを保証するには、(a) getter/setter を手動で作成してフィールドアクセスの替わりに呼び出すか、(b) フィールドにアクセスする 前 にエンティティが完全に設定されていることを保証してください。
ご覧のように、 find
static フィールドが追加されました。これは識別子が Long
である Task
型のエンティティに対する Finder
を定義します。このヘルパーフィールドはモデルのクエリーを簡素化するために使われます。
// Find all tasks
List<Task> tasks = Task.find.all();
// Find a task by ID
Task anyTask = Task.find.byId(34L);
// Delete a task by ID
Task.find.ref(34L).delete();
// More complex task query
List<Task> tasks = find.where()
.ilike("name", "%coco%")
.orderBy("dueDate asc")
.findPagingList(25)
.getPage(1);
§トランザクション管理されたアクション
デフォルトでは Ebean はトランザクションを使用しません。しかし、Ebean から提供された全てのトランザクションヘルパーを使うことができます。例えば:
:: Rob Bygrave -
上の記述は正確ではありません。 Ebean は暗黙的なトランザクションを使用します。トランザクションの境界を引く方法は 3 つあります。 @Transactional、TxRunnable() または beginTransaction() と commitTransaction() です。
例と解説は http://www.avaje.org/ebean/introtrans.html をご覧下さい。
:: - end note
// run in Transactional scope...
Ebean.execute(new TxRunnable() {
public void run() {
// code running in "REQUIRED" transactional scope
// ... as "REQUIRED" is the default TxType
System.out.println(Ebean.currentTransaction());
// find stuff...
User user = Ebean.find(User.class, 1);
...
// save and delete stuff...
Ebean.save(user);
Ebean.delete(order);
...
}
});
アクションメソッドに @play.db.ebean.Transactional
アノテーションを付けることで、メソッドにトランザクションを自動的に管理する Action
を組み合わせる事も出来ます。
@Transactional
public static Result save() {
...
}
次ページ: JPA の統合