複数のEntityをまとめて保存する


Google App Engineでは、データストアと呼ばれるデータベースを用いてデータの保存を行うことができます。
Low Level APIでGAEのデータストアにアクセスする」では、カインド(テーブルのようなもの)にエンティティーという単位(レコードのようなもの)でデータストアにデータを保存する方法について解説しています。
また、エンティティー生成の際には、ユニークなキーを割り振る必要があることも解説しました。

今回はこの応用で、複数のエンティティーをまとめて保存する方法について解説します。
上記記事にて、DatastoreServiceクラスのputメソッドを用いてエンティティーを一つだけ保存していますが、
複数のエンティティーを保存する場合、一つ一つputメソッドを用いて保存するよりも、まとめて保存する方が高速に処理を行うことができます。

それでは続きで詳細を見て行きます。

エンティティーを生成する

まずは保存を行うためのエンティティーを生成します。今回は8個のエンティティーを用意しますが、少し数が多いのでループを使って一斉に作りたいです。
ループを使用してエンティティーを複数生成したい場合、エンティティー毎に一意に指定する必要のある「キー」の生成をどのように行うかが問題になってきますが、KeyRangeクラス用いることで解決することができます。

以下のソースコードを見て下さい。

BatchPutServlet.java

public class BatchPutServlet  extends HttpServlet{
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
	throws IOException {
		DatastoreService dss = DatastoreServiceFactory.getDatastoreService();

		String[] name = {"seit","nakajima","katsuo","hanazono","nobita","shizuka","tarou","hanako"};
		String[] age = {"25","12","12","12","10","10","20","20"};
		String[] gender = {"man","man","man","woman","man","woman","man","woman"};

		ArrayList entities = new ArrayList();

		// Keyを連番で自動採番
		KeyRange keyRange = dss.allocateIds("BatchPut", 8);
		Iterator iterator = keyRange.iterator();

		int i = 0;
		while(iterator.hasNext()){
			Entity entity = new Entity(iterator.next());
			entity.setProperty("name", name[i]);
			entity.setProperty("age", age[i]);
			entity.setProperty("gender", gender[i]);
			entities.add(entity);
			i++;
		}
	}
}

6〜8行目で今回データストアに保存したい文字列を定義しています。
13行目でKeyRangeクラスのインスタンスkeyRangeを生成しています。
インスタンスの生成には DatastoreServiceクラスのallocateIdsメソッドを用います。allocateIdsメソッドの各引数はそれぞれ以下の表のようになっています。
[table “233” not found /]

今回は第2引数に8を指定していますので、ユニークなキーを8個生成することができ、データストアに保存した際にエンティティー毎に自動で割り振られるidが連番になります。
14行目で、keyRangeからキーを一つずつ取り出すためにイテレーターを取得しています。

17行目から24行目のwhileループ内で、エンティティーの生成とデータのセットを行っています。
18行目で、イテレーターから一つずつ取り出したキーを使用してエンティティーを生成しています。19〜22行目で保存するデータをsetPropertyメソッドを用いてエンティティーにセットしています。
23行目で、生成したエンティティーをputメソッドで毎回保存せず、一旦ArrayListのインスタンスに保存しておきます。
次の節でエンティティーの保存を行います。

データストアに保存する

それでは次に、生成したエティティーをデータストアに保存します。
今回は8個のエンティティーを一度にまとめて保存します。とは言っても、使用するメソッドはエンティティーを一つだけ保存する際に用いたDatastoreServiceクラスのputメソッドです。
今回は以下に示すputメソッドのオーバーロードを用います。

put(java.lang.Iterable entities)

使用例は以下になります。

BatchPutServlet.java

		ArrayList entities = new ArrayList();
(...省略)
		// Entityをまとめてput
		List keys = dss.put(entities);

DatastoreServiceクラスの引数に、エンティティーを格納したArrayListクラスのインスタンスを指定します。こうすることで、複数のエンティティーを一度のputメソッドで全て保存することが可能です。
エンティティー毎にputメソッドを用いて保存するより高速に保存処理を行う事が出来ます。
また、putメソッドは返り値として保存したエンティティーのキーを返しますが、今回のように複数のエンティティーを引数に指定した場合は、それぞれのエンティティーに指定したキーを全て返してくれます。
これをListクラスのインスタンスに保存しておくことで、後々データの取得を行う際などにキーを利用することができます。

以上、エンティティーをまとめてデータストアに保存する方法でした。