Integrating Cosmos DB with OData (Part 3) をJavaでやってみたら

以下のようなエントリが投稿されていたので、Javaでやったらどうなるか試してみる。Cosmos DBとはいえ、Azure Table互換を使っているので、利用するAPIの実体はTable API。

Integrating Cosmos DB with OData (Part 3)
https://devblogs.microsoft.com/odata/integrating-cosmos-db-with-odata-part-3/

オリジナルのエントリに従い、Table APIを使うCosmos DBを用意する。

[確認と作成]をクリックして内容を確認し、[作成]をクリックしてインスタンスを作成。

データエクスプローラーでTableを作成し、データを追加する。スループットは400のままでよい。

Table APIでは、PartitionKey、RowKey、Timestampは自動生成される。Name、ScoreというフィールドをTableに追加し、値を設定しておく。

値を追加した結果。

この先は接続文字列を取得して、Hello Worldのようなアプリケーションを作る。ここまではオリジナルと同じ。

今回はStorage Table互換APIを使うため、以下の依存関係を追加する。

<!-- Microsoft Azure Storage Client SDK. 執筆時の最新 8.6.0 を使う -->
<dependency>
    <groupId>com.microsoft.azure</groupId>
    <artifactId>azure-storage</artifactId>
    <version>8.6.0</version>
</dependency>

コードを書いていく。エンティティクラスを作成する。これはTableServiceEntityを拡張したもの。

import com.microsoft.azure.storage.table.TableServiceEntity;

public class Student extends TableServiceEntity {
    String Name;
    Integer Score;

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        this.Name = name;
    }

    public Integer getScore() {
        return Score;
    }

    public void setScore(Integer score) {
        this.Score = score;
    }
}

続いて、CloudTableClientを作成し、参照するTable(今回はstudents)を取得。

final String CONNECTION_STRING="Your Connection String";

CloudTableClient cloudTableClient = CloudStorageAccount.parse(CONNECTION_STRING).createCloudTableClient();
CloudTable table = cloudTableClient.getTableReference("students");

TableQuery<Student> tableQuery = TableQuery.from(Student.class);

TableQuery、つまりselect文を作成する。複数の条件句(where句)はTableQuery#combineFilters() を使って結合する。以下のコードに入っているtake()で、結果セットの先頭から何件取得するかを指定できる。

String filter1 =
        TableQuery.generateFilterCondition("Score", QueryComparisons.GREATER_THAN, 150);
String filter2 =
        TableQuery.generateFilterCondition("Name", QueryComparisons.EQUAL, "Hassan");

tableQuery = TableQuery.from(Student.class)
        .where(TableQuery.combineFilters(filter1, TableQuery.Operators.AND, filter2))
        .take(3);
ResultContinuation token = new ResultContinuation();
token.setContinuationType(ResultContinuationType.TABLE);
table.executeSegmented(tableQuery, token)
        .getResults()
        .forEach(i-> System.out.printf("PartitionKey [%s] Name [%s] Score [%d]\n", i.getPartitionKey(), i.getName(), i.getScore()));

上記コードを実行すると、以下の結果が得られる。

PartitionKey [1] Name [Hassan] Score [155]

ほぼ原文のC#での場合と同じように出来るが、Java APIの場合、OrderByに相当するものがない。そのため、Javaの場合はStream APIなどを使ってFilteringするしかなさそう(あとはStored procedureを使う、ぐらい)。JavaではOrderByを使わないと割り切ったのかはよくわからないが、ちょっとどうかなー、と思う。

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Google フォト

Google アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中