2011年6月25日土曜日

Objectify-appengineでGAEデータストアを操作する

GWTプログラミングにおいては、GWT-RPCを利用することはしばしばあります。この場合、サーバークライアント間でのデータのやりとりは、
シリアライズ可能なPureなデータクラスを用意する
のが前提になります。ここで、データベースを絡めてくると厄介な問題がおきます。例えば、GAEのDatastoreを利用する場合、DatastoreとのやりとりはJPAやJDOのフレームワークを使いますが、この場合のEntityクラスには、それら特有の記述(アノテーション)が必要となります。このEntityクラスは、GWTで利用可能なシリアライズ化されず、GWT-RPCでは受けつけられません。よって、PureデータクラスをDTOとして中身の入れ替え作業が必要になります。その手間は面倒です。

objectify-appengineというライブラリ
この問題を解決する方法として、objectify-appengineと呼ばれるGAEのデータストアに対応したライブラリがあります。これを利用することで、GWTーRPCで利用したデータクラスをそのままデータストアに渡すことができます。本ラボでは現在まだ試行中ですが、JDOと同じような感覚で利用できるのがポイントです。

ライブラリの準備
まず、公式サイトからライブラリを入手して下さい。最近、3.0のバージョンが出たようです。3.0でどう変わったのかはちょっと不明です。ライブラリにパスを通したあと、GWTの設定ファイルに以下の記述を追記して下さい。
<inherits name="com.googlecode.objectify.Objectify" />
javax.persistanceのアノテーションを利用しますので、
ejb3-persistance.jar 
をクラスパスに記述してください。

Entityクラスの記述方法
下記に示すとおり、記述はシンプルになります。

  • idには@Idを追記
  • getter/setterはなくても良い(書いておいたほうがいいでしょう)
  • @Transient String doNotPersistがいるらしい(調査中、不要かも)

import javax.persistence.Id; 
import javax.persistence.Transient;

public class Car
{
     @Id Long id;
    String vin;
    int color;
    @Transient String doNotPersist;

    public Car() {}
    
    public Car(String vin, int color)
    {
        this.vin = vin;
        this.color = color;
    }
}


以下にとりあえず基本的な記述の仕方を載せます。

クラスの登録
ここはJDOなどとちょっと違うところです。ObjectifyはどのクラスがEntityクラスに相当するのか、コードで明示的に記述する必要があります。
ObjectifyService.register(Car.class);//該当するクラスを登録
Objectify ofy = ObjectifyService.begin(); //サービスのインスタンスを生成
データの追加・修正
ofy.put(car);
削除
ofy.delete(car);

検索
//IDによる検索
Car fetched1 = ofy.get(new Key(Car.class, porsche.id));
Car fetched2 = ofy.get(Car.class, porsche.id); 


//クエリによる検索(結果が1つの場合)
Car car = ofy.query(Car.class).filter("vin", "123456789").get();

//クエリによる検索(結果が複数ある場合)
Query q = ofy.query(Car.class).filter("vin >", "123456789");
for (Car car: q) {
    System.out.println(car.toString());
}
リファレンスをみてみるといろいろ強力な処理ができるようで、GAEのデータストアを利用する際のフレームワークの候補として挙げてみて良いと思います。

0 件のコメント:

コメントを投稿