Objectify-appengineを利用したGAE Datastoreの利用
Objectifyとは?
Objectify-appengine(以後、Objectify)は、GAEのDatastoreにアクセスするサードパーティのライブラリです。Datatstoreのアクセスには、JPAやJDOなどが公式にサポートされていますが、このライブラリをあえて利用する利点は、
- GWTのEntityとしてDTOを用意する必要がない
という点に他なりません。本ラボでは、GWTを全面的に採用していますが、GAEやHibernateとの連携を試みる際にこの点がネックになっていました。本ライブラリを利用することで、DTOをつくる手間がなくなりますので、開発効率の改善が期待できます。
ライブラリのダウンロードとクラスパスへの追加
- objectify-appengineよりライブラリをダウンロードしてください。
- ダウンロード後は展開して、objectify-3.*jarをクラスパスに登録してください。(クラスパスの登録方法、Eclipse)
- javax.persistanceのアノテーションを利用しますので、ejb3-persistence.jar ファイルを入手してクラスパスに登録してください。
- 本ゼミ生は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);