2021年3月16日火曜日

Google App Engine(GAE) で Datastoreを Javaから使う

目次へ



Datastore は、スケーラビリティが高い NoSQL データベースです。GAEでも、MySQLのようなRDBを使うことはできますが、CloudFirestoreのDatastoreモードというデータベースの 使用が推奨されています。
Datastoreは、GAEのデフォルトのデータベースとして登場しました。その後、Cloud Datastoreという名前でGCPのプロダクトの一つとして提供され、GAE以外からでも利用できるようになりました。 さらに、Cloud FirestoreのDatastoreモードがCloud Datastoreの最新バージョンになりました。将来的には、既存のすべてのCloud Datastoreが、FirestoreのDatastoreモードに 自動的にアップグレードされる予定のようです。

DatastoreとRDBの用語は以下のように異なります。
RDB Datastore
カインド
レコード(列) エンティティ
フィールド(項目) プロパティ


DatastoreをJavaから操作する方法はいくつかあるようですが、ここでは、Datastore APIを使う方法を示します。パッケージは以下です。


import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.Filter;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;         

DatastoreService取得

まずは、DatastoreServiceを取得し、そのメソッドを使い、挿入、削除、更新などを行うことになります。

DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();            

挿入

Datastoreでは、データを登録するためのCREATE TABLEなどは不要です。カインド(RDBの表名)を指定し、Entity のインスタンスを作り、必要なプロパティ(RDBのフィールド名)ごとに値を指定し、DatasoreServiceのputメソッドで挿入します。この時、longの値のキーが自動で追加されます。

Entity entity = new Entity("カインド名");
entity.setProperty("プロパティ名","bbbb");
datastore.put(entity);

削除

削除をするには、キーを指定してDatasoreServiceのdeleteメソッドを呼びます。引数は、可変個引数なので、いくつでも指定できます。また、Iterableを引数に渡すこともできます。
Google Cloud PlatformのDatastoreのエンティティを確認すると、登録されているエンティティのキーと、プロパティを見ることができますので、そのキーのIDを指定して削除したのが以下の例です。

Key key = KeyFactory.createKey("カインド名", 5071211717459968L);
datastore.delete(key);

キーについて

キーを、エンティティから取得するのは、以下のようになります。エンティティを取得するのは、下の項目を見てください。

datastore.delete(key);
long keyID = key.getID();

キーを指定してEntityを取得

キーを指定してエンティティを取得するのは以下の通りです。getメソッドは、EntityNotFoundExceptionをスローするため、try catchが必要になります。

Enriry entity = null;
Key key = KeyFactory.createKey("カインド名",5632499082330112L);	//Kind,ID
try {
	entity = datastore.get(key);
} catch (EntityNotFoundException e) {
	e.printStackTrace();
}
entity.getProperty("プロパティ名");  //プロパティの値を取得
entity.getKey().getID();             //キーのIDを取得

更新

挿入と同様、put(Entityのインスタンス)を実行した時、Entityのインスタンスが既に存在するキーをもっていれば新規挿入ではなく更新となります。

Enriry entity = null;
Key key = KeyFactory.createKey("カインド名",5632499082330112L);	//Kind,ID
try {
	entity = datastore.get(key);
} catch (EntityNotFoundException e) {
	e.printStackTrace();
}
entity.setProperty("プロパティ名","abc");
datastore.put(entity);

すべてを選択

あるカインドからすべてのエンティティを取得するには、Queryを使います。
下の2行目について説明します。
datastore.prepare(query)でPreparedQueryが返ります。
そのクラスのasList()で問い合わせたものをリストとして返してくれます。
また、asListの引数にはFetchOptionsオブジェクトを渡しますが、これは、リミットやオフセットなどを記述するためのクラスであり、FetchOptions.Builderクラスのメソッドでそのインスタンスを作成することができます。
withDefaultsメソッドは、デフォルトのFetchOptions.Builderクラスを作成しますので、それをasListに渡し、すべてのエンティティを取得します。

Query query = new Query("カインド名");
List<Entity> results = datastore.prepare(query).asList(FetchOptions.Builder.withDefaults());
for(Entity e : results) {
	String s = e.getProperty("a");
}

Orderの指定

あるプロパティでソートしてエンティティを取得するためには、addSortメソッドを使います。

Query q = new Query("カインド名").addSort("プロパティ名", SortDirection.ASCENDING);

条件の指定

Filterクラスで条件を書くことができます。下の条件はtoiというプロパティが1と等しいものだけを取得するFilterです。
FilterOperator.EQUAL はenumでEQUAL、GREATER_THAN、GREATER_THAN_OR_EQUAL、IN、LESS_THAN、LESS_THAN_OR_EQUAL、NOT_EQUALがあります。

Filter f = new Query.FilterPredicate("toi", FilterOperator.EQUAL, 1);
Query q = new Query("カインド名").setFilter(f);
にほんブログ村 IT技術ブログ IT技術メモへ
にほんブログ村