ラベル Objectify の投稿を表示しています。 すべての投稿を表示
ラベル Objectify の投稿を表示しています。 すべての投稿を表示

2011-12-27

GWT: Objectifyで得た検索結果をGWT-RPCへ直接送る方法

御存知の通り、GWT-RPCでは送受信するクラスに制約があります。Objectifyで検索をした場合、結果に複数の結果を受け取るときは、QueryクラスやIterableインタフェースで受け取ることになります。この結果をGWT-RPCを利用して直接クライアント側に返す時には、Iterableインタフェース等は送信できないのでようなので、下記のようにリストに変換してから返すことになります。
Query ql = cdao.ofy.query(XXXX.class).filter("key", Key);
List list = ql.list();
return list;


2011-12-16

ObjectifyでRelationShipを利用する

GAEのDataStoreはKVSのデータベースですので、RDBのようなリレーションがないと言われていますが、実際にはRelationshipという所有関係を定義することができます。Objectifyでは比較的容易に設定することができます。

サンプルの設定状況
サンプルプログラムの設定状況は下記の通りになります
  • ユーザを表現するPersonクラス
  • 車を表現するCarクラス
  • Carクラスはユーザ(Person)の情報を持つ
このことを頭にいれて以下を読んでください。

Entityクラスの記述方法
@Parentのアノテーションをつけるのがポイントです。
public class Car
{
    @Id Long id;
    @Parent public Key owner;
    String color;
}

public class Person
{
    @Id Long id;
    String name;
    int grade;
}
リレーションの登録
Keyを割り当てるのがポイントです。
//Personデータを登録し、そのKey情報を得る
Person p = new Person();
p.name="bob"; 
Key pKey = ofy.put(p);

//入手したKey情報を割り当てる
Car car = new Car();
car.id=(long)1002;
car.owner=pKey;
car.color="blue";
リレーションを利用した検索
色が青色の車のユーザを検索する方法は下記のようになります。
Car car = ofy.query(Car.class).filter("color", "blue").get();
Person p = ofy.get(car.owner);
ID情報をベタに管理するよりも簡単に検索することができますね。

2011-09-22

Objectify+GWT RequestFactory?


本ラボでは、GAEのデータストア用に、Objectify-appengine のライブラリを利用していますが、Google I/O2011にて、Objectifyの話題が出てたようです。
Highly Productive GWT: Rapid Development with App Engine, Objectify, RequestFactory, and gwt-platform
この内容と同じサンプルコードが
Using GWT RequestFactory with Objectify(TurboManage)
にも載ってます。

今さら感がありますが、GWT RequestFactory というのは初耳。どうやらGWT2.1くらいから出てきてるのかな?GWT-RPCの代替になるものらしく、完全に乗り遅れ感が、、、、

ラボでの開発効率をどんどん上げていきたい今日この頃なので、Rapidなフレームワークであるならばどんどん使っていきたいもの。今後調査します。

2011-07-30

DAOBaseクラスでObjectify-appengineを使いやすくする

Objectify-appengineでは、
ObjectifyService.registerメソッドを記述して、Entityを登録する
という手順が必要となります。これはちょっと面倒なんですが、もっと厄介なのは
同じクラスを登録するとエラーが発生する
という仕様になっている点です。クラスの情報はスタティックな領域に記録されているので、registerメソッドで同じものを登録しないように気を付けなければなりません。その解は、公式サイトのBestPracticeに書いてあります。DAOBaseクラスを使えと、、、
public class DAO extends DAOBase
{
    static {
        ObjectifyService.register(ここに利用するEntityを記述);
     }

  //DAOとしてデータベース周りのラッパーメソッドを以下に書いていけば良い
}
基本的に上述のようなDAOクラスを継承したクラスを作っておけば、あとは下記のように呼び出せばOK。
DAO dao = new DAO();
dao.ofy().find(........);
dao.ofy().put(......);

ただこのようにfindやputを呼び出すよりも、実際は、DAOクラスに関連するラッパーメソッドを実装して呼び出すようにするのがいいですね。

2011-06-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のデータストアを利用する際のフレームワークの候補として挙げてみて良いと思います。