個人的な思いとしては、GAE/JのDatastoreについて、JDOから入ると間違った理解をしやすい/ハマリやすいと思ってるんで、Low-level APIから入って、それからJDOを使っていくかLow-level APIで行くか、を選択するのが良いと思ってます。GAE/JのJDOを使う時は、まずはlow-level APIから入って、それから「JDOだとこんな事を便利にやってくれるんだ」とプラスαの部分を積んでいく方が良い。JDOから入るとどーしてもRDBのORMだという認識が頭から抜けずにはまる人が多いよぅに思うんですよね。スタンスとしてはJDOを使う事に否定的なわけではなく、学習の順序という話です。 Entitylow-level APIを使うと、JDOのようなPOJOにアノテーション、タイプセーフなpropertyにアクセサ…と言った物は無いです。全てのエンティティをEntityクラスとして扱う必要があります。 コンストラクタ
属性値の設定
属性値の取得
Queryコンストラクタ
フィルタ
ソート
キーのみのクエリ
DatastoreServiceDatastoreへアクセスする為のサービスクラスで、大概の処理はこのDatastoreServiceが担当するんですが案外シンプルです。そんなに機能が無いからですw。他のサービスクラスと同様に、サービスクラス用のファクトリからインスタンスを取得します。
保存するめちゃ簡単です。基本的には Key DatastoreService#put(Entity entity)または List<Key> DatastoreService#put(Iterable<Entity> entities)の2種類のメソッドです。後述しますが、Transaction中で実行したい場合は第一引数にTransactionを与えます。 削除するこれも簡単。void DatastoreService#delete(Keys... keys)が基本形。他に、Iterable<Key>を引数にする事も出来ます。保存と同様に、Transaction中で実行したい場合は第一引数にTransactionを与えます。 Keyを指定して取得する
主キーを指定してEntityを取得します。個人的にはあんまり使った記憶がありませんが、Map<Key, Entity> DatastoreService#get(Iterable<Key> keys)っていうメソッドもあります。 親キーを指定した取得に専用メソッドは無く、後述するQueryクラスを使用する事になります。 Queryオブジェクトでクエリする上の項目で説明したQueryを引数にしてDatastoreService#prepare(Query query)を実行する事でPreparedQueryが取得できるのですが、ここから「何を/どのように取得するか?」といったカンジになります。 重要な点として、1000件以上の結果は返せないという点です。とはいえ1000件以上取得できるJDOも、1000件以上を扱おうとすると遅くて実用的ではない事も多いので、何が何でも1リクエストに対して1000件以上を一気に!…って時は色々工夫が必要になります。工夫した結果、low-level APIにたどり着くのかもしれません。 結果セットの取得メソッド以下のパターンがあります。一番良く使うのはasList()かな?
FetchOptions個人的にはasList()メソッドで必要だから常にoffset(0)を使っている程度で、あまり使いこなせていないので細かい説明ができません、ゴメンナサイ。でも大体名前の通りなんでしょう。
特殊なクエリ
ちなみに、sdk1.2.2での現象で不具合なのか仕様なのかよくわかりませんが、例えば"Kind"というKind内でkind1(ルート), kind2(kind1の子エンティティ)という、同じKind内のEntity同士でEntityGroupを構築した場合、Query("kind", kind1.getKey())でクエリするとkind1, kind2の2件が返されます。なんのこっちゃわかりません(kind2だけが返される事を期待するよね?)。 自動採番のキーを作成する[SDK1.2.5]
自動採番されるKeyは1.2.2まではPUTしなければ取得できませんでしたが、1.2.5からいつでもIDが割り当てられたKeyを取得する事ができます。Transactionの項にサンプルを追加しておきました。 TransactionJDOと似たような使い方が出来ます。 |