Cloud Datastore を Java から使う

Java 用の Bookshelf のチュートリアルのこのパートでは、構造化データを Google Cloud Datastore 内に作成する方法を説明します。また、作成したデータを読み取る、更新する、削除する方法も説明します。

このページは複数ページからなるチュートリアルの一部です。説明の最初から設定手順を確認するには、Java Bookshelf アプリに移動してください。

設定の構成

この Bookshelf チュートリアルのすべてのパートの構成情報は、pom.xml に保持されます。チュートリアルのこのパートでは、構成情報を追加する必要はありません。唯一の要件は bookshelf.storageType プロパティの値を datastore に設定することで、これはすでに設定されています。

ローカルマシンでのアプリの実行

アプリをローカルで実行するには:

  1. getting-started-java/bookshelf/2-structured-data ディレクトリで次のコマンドを入力し、ローカル ウェブサーバーを起動します。

    mvn -Plocal clean jetty:run-exploded -DprojectID=[YOUR-PROJECT-ID]
  2. ウェブブラウザで http://localhost:8080 に移動します。

これで、アプリのウェブページを閲覧し、書籍の追加、編集、削除を行えるようになります。

App Engine フレキシブル環境へのアプリのデプロイ

  1. 次のコマンドを入力してアプリをデプロイします。

    mvn appengine:deploy -DprojectID=YOUR-PROJECT-ID
    
  2. ウェブブラウザで、次のアドレスを入力します。[YOUR_PROJECT_ID] は実際のプロジェクト ID で置き換えます。

    https://[YOUR_PROJECT_ID].appspot-preview.com
    

アプリを更新する場合は、最初にデプロイしたときと同じコマンドを使って、更新バージョンをデプロイできます。デプロイを行うと、アプリの新しいバージョンが作成され、それがデフォルトのバージョンに設定されます。古いバージョンはそのまま残り、関連付けられた VM インスタンスも同様に残ります。すべてのアプリ バージョンと VM インスタンスが課金対象のリソースとなるのでご注意ください。

アプリのデフォルト以外のバージョンを削除することで、コストを削減できます。

アプリのバージョンを削除する手順は次のとおりです。

  1. GCP Console の [App Engine のバージョン] ページに移動します。

    [バージョン] ページに移動

  2. 削除したい、デフォルト以外のアプリのバージョンの横にあるチェックボックスをクリックします。
  3. ページ上部にある [削除] ボタンをクリックし、アプリのバージョンを削除します。

課金対象のリソースをクリーンアップする方法の詳細については、このチュートリアルの最後のステップにあるクリーンアップ セクションを参照してください。

アプリケーションの構造

次の図は、アプリケーションを構成するコンポーネントと、それらの接続関係を示しています。

Bookshelf App のデプロイと構造

コードを理解する

このセクションでは、アプリケーションのコードとその動作を、順を追って説明します。

Cloud Datastore の操作

このアプリは承認済みの Datastore サービス オブジェクトを使用して Cloud Datastore を操作します。これは重量級のオブジェクトで、Datastore API へのアクセスに使用するトークンの認証情報の交換などがそこですでに行われています。このアプリは "Book" という種類の KeyFactory オブジェクトも作成します。書籍は、このアプリが格納する唯一のデータの種類です。ただし、一般に格納できるデータの種類の数に制限はありません。Cloud Datastore は幅広い種類のデータタイプをサポートしています。

private Datastore datastore;
private KeyFactory keyFactory;

public DatastoreDao() {
  datastore = DatastoreOptions.getDefaultInstance().getService(); // Authorized Datastore service
  keyFactory = datastore.newKeyFactory().setKind("Book2");      // Is used for creating keys later
}

書籍を作成する

このアプリでは、書籍を保存するために Cloud Datastore に 1 つのエンティティが格納されます。エンティティは 1 つのキーと 1 つのコレクション(名前と値のペアの集合)を持ちます。createBook メソッドが IncompleteKey 状態で開始されます。データストアにエンティティが追加されるときに、この値が設定されます。このコードは、set メソッドを繰り返し呼び出すことにより、Builder デザイン パターンに従ってエンティティをビルドします。

@Override
public Long createBook(Book book) {
  IncompleteKey key = keyFactory.newKey();          // Key will be assigned once written
  FullEntity<IncompleteKey> incBookEntity = Entity.newBuilder(key)  // Create the Entity
      .set(Book.AUTHOR, book.getAuthor())           // Add Property ("author", book.getAuthor())
      .set(Book.DESCRIPTION, book.getDescription())
      .set(Book.PUBLISHED_DATE, book.getPublishedDate())
      .set(Book.TITLE, book.getTitle())
      .build();
  Entity bookEntity = datastore.add(incBookEntity); // Save the Entity
  return bookEntity.getKey().getId();                     // The ID of the Key
}

Cloud Datastore から読み出す

readBook メソッドは、書籍の ID を引数に取り、それをキーに変換します。その後、キーは get メソッドに渡され、そこから Entity オブジェクトが返されます。

@Override
public Book readBook(Long bookId) {
  Entity bookEntity = datastore.get(keyFactory.newKey(bookId)); // Load an Entity for Key(id)
  return entityToBook(bookEntity);
}

entityToBook メソッドは、Cloud Datastore から取得したエンティティを Book オブジェクトに変換します。この変換ではタイプごとに get メソッドが使われます。これは set と同様に、プロパティ名として String を受け入れます。

public Book entityToBook(Entity entity) {
  return new Book.Builder()                                     // Convert to Book form
      .author(entity.getString(Book.AUTHOR))
      .description(entity.getString(Book.DESCRIPTION))
      .id(entity.getKey().getId())
      .publishedDate(entity.getString(Book.PUBLISHED_DATE))
      .title(entity.getString(Book.TITLE))
      .build();
}

書籍を更新する

更新を行うには、Entity を指定して update メソッドを呼び出す必要があります。

@Override
public void updateBook(Book book) {
  Key key = keyFactory.newKey(book.getId());  // From a book, create a Key
  Entity entity = Entity.newBuilder(key)         // Convert Book to an Entity
      .set(Book.AUTHOR, book.getAuthor())
      .set(Book.DESCRIPTION, book.getDescription())
      .set(Book.PUBLISHED_DATE, book.getPublishedDate())
      .set(Book.TITLE, book.getTitle())
      .build();
  datastore.update(entity);                   // Update the Entity
}

Datastore で削除を行うには、Key を指定して delete メソッドを呼び出す必要があります。

書籍を削除する

@Override
public void deleteBook(Long bookId) {
  Key key = keyFactory.newKey(bookId);        // Create the Key
  datastore.delete(key);                      // Delete the Entity
}

書籍をリストする

listBooks メソッドは、書籍のリスト(1 回に 10 冊分)を、URL セーフな Cursor とともに返します。

@Override
public Result<Book> listBooks(String startCursorString) {
  Cursor startCursor = null;
  if (startCursorString != null && !startCursorString.equals("")) {
    startCursor = Cursor.fromUrlSafe(startCursorString);    // Where we left off
  }
  Query<Entity> query = Query.newEntityQueryBuilder()       // Build the Query
      .setKind("Book2")                                     // We only care about Books
      .setLimit(10)                                         // Only show 10 at a time
      .setStartCursor(startCursor)                          // Where we left off
      .setOrderBy(OrderBy.asc(Book.TITLE))                  // Use default Index "title"
      .build();
  QueryResults<Entity> resultList = datastore.run(query);   // Run the query
  List<Book> resultBooks = entitiesToBooks(resultList);     // Retrieve and convert Entities
  Cursor cursor = resultList.getCursorAfter();              // Where to start next time
  if (cursor != null && resultBooks.size() == 10) {         // Are we paging? Save Cursor
    String cursorString = cursor.toUrlSafe();               // Cursors are WebSafe
    return new Result<>(resultBooks, cursorString);
  } else {
    return new Result<>(resultBooks);
  }
}

インデックスを作成する

Datastore ではデフォルトでプロパティごとにインデックスが作成されますが、この動作を変更することもできます。クエリによってはインデックス内の複数のプロパティを使わないと実行できないものがあります。たとえば、上記のユーザー別クエリやタイトル順クエリがそれに該当します。アプリで必要とされるインデックスは Datastore エミュレータが教えてくれます。

これらのインデックスを実際に作成してみましょう。

gcloud datastore create-indexes index.yaml
このページは役立ちましたか?評価をお願いいたします。