Objectify-appengineを利用したGAE Datastoreの利用

Objectifyとは?

Objectify-appengine(以後、Objectify)は、GAEのDatastoreにアクセスするサードパーティのライブラリです。Datatstoreのアクセスには、JPAやJDOなどが公式にサポートされていますが、このライブラリをあえて利用する利点は、

    • GWTのEntityとしてDTOを用意する必要がない

という点に他なりません。本ラボでは、GWTを全面的に採用していますが、GAEやHibernateとの連携を試みる際にこの点がネックになっていました。本ライブラリを利用することで、DTOをつくる手間がなくなりますので、開発効率の改善が期待できます。

ライブラリのダウンロードとクラスパスへの追加

    1. objectify-appengineよりライブラリをダウンロードしてください。
    2. ダウンロード後は展開して、objectify-3.*jarをクラスパスに登録してください。(クラスパスの登録方法、Eclipse
    3. javax.persistanceのアノテーションを利用しますので、ejb3-persistence.jar ファイルを入手してクラスパスに登録してください。
    4. 本ゼミ生はPC内から探すか、本ラボの内部サイトから取ってきてください。

gwt.xmlファイルの記述

GWTで利用する場合は、以下の記述を追記してください。

<inherits name="com.googlecode.objectify.Objectify" />

をクラスパスに記述してください。

プログラミング記述方法とDAOを利用したテクニック

Objectifyでは、下記の2つのファイルが必要です。

    • Entityクラス(データクラス)
    • DAOクラス

正確に言えば、2つめのDAOクラスの作成は必須ではありませんが、これを作成することでプログラムの作成が容易になります。以下の各クラスの記述方法を書いていきます。

データストアのテーブル(Kind)のデータ構造を定義しよう

まずは、自分が作成しようとするデータストアの構造を定義しておく必要があります。とりあえず以下の例ではデータストアに

    • id
    • name
    • color

という3つのプロパティを格納するCarというテーブル(Kind)を作成&利用することを想定して話を進めてます。

Entityクラス記述方法

データを格納するためのみに存在するクラスです。記述はシンプルになります。

    • idには@Idを追記
    • getter/setterはなくても良い書いてください。変数はprivateとし、getXX, setXXのメソッドを用意してください。NetbeansやEclipseではフィールドのカプセル化を利用することで自動的にメソッドが生成されます。
import javax.persistence.Id;
import javax.persistence.Transient;
public class Car
{

@Id Long id;

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

なお、GWTでも利用する場合は、Entityクラスは clientパッケージ内に作成してください。

Objectifyプログラミングの基本

まず、Objectifyの基本を理解しましょう。Objectifyでは、作成したEntityクラスを利用してデータアクセス(CRUD)をしていきます。基本的に次のような流れになります。

    • Entityクラスの登録
    • Objectifyサービスの開始
    • CRUDの記述

2つめまでのコードは次のようになります

ObjectifyService.register(Car.class);//Entityクラスの登録

Objectify ofy = ObjectifyService.begin(); //サービスのインスタンスを生成

CRUD(Create,Read,Update,Delete)の記述

登録も修正もputで行います。

Car car = new Car();
car.name="skyline"
car.color=200;
//登録。修正
ofy.put(car);
//削除の場合
ofy.delete(car);

【id による検索】

Car fetched1 = ofy.get(new Key<Car>(Car.class, porsche.id));
Car fetched2 = ofy.get(Car.class, porsche.id); 

【Queryによる検索】

id以外でも検索は可能です。以下において、Queryクラスは、com.googlecode.objectify.Queryとなります(importして下さい)。

//結果が1つの場合
Car car = ofy.query(Car.class).filter("name", "skyline").get();
//結果が複数ある場合
Query<Car> q = ofy.query(Car.class).filter("color >", 100);
for (Car car: q) {
    System.out.println(car.toString());
}

なお、この検索結果をGWTクライアントに直接送り返すときは、下記のようにListクラスに変換してから送り直すようにしてください。

Query<Car> q = ofy.query(Car.class).filter("color >", 100);
List list = q.list();
return list;

DAOの作成(推奨)

ObjectifyのEntityクラスについては明示的に登録をしないといけません。しかし、クラスの登録を二重にしてしまうとエラーとなってしまいます。よって、以下のようにDAOBaseクラスを継承したDAOを作成するのが推奨されています。DAOクラスとは、テーブル(Kind)に対する操作記述をまとめて書いていくクラスです。

    • Objectifyが用意しているDAOBaseクラスを継承
    • ObjectifyのCRUDのメソッドをラップするメソッドを作成

がポイントです。

import com.googlecode.objectify.util.DAOBase;

//Carクラスをimportする必要がある場合があります。

public class CarDAO extends DAOBase {

Objectify ofy ;

static {

ObjectifyService.register(Car.class);

}

CarDAO(){

ofy = ObjectifyService.begin();

}


public void add(Car car){ //ラッピングしたメソッド

ofy.put(car);


}

}

DAOは必ずserverパッケージ以降に置いてください

DAOを利用する例

このDAOのインスタンスを生成し、各種メソッドを呼び出すことになります。

Car car = new Car();

car.setName("skyline");

car.setColor(200);


CarDAO cardao = new CarDAO();

cardao.add(car);