クイックスタート: Java SDK と Azure Cosmos DB で Table 用 API アプリを構築する

適用対象: Table

このクイック スタートでは、Java アプリケーションから Azure Cosmos DB Tables API にアクセスする方法について説明します。 Azure Cosmos DB Tables API はスキーマレス データ ストアであり、これによりアプリケーションは構造化された NoSQL データをクラウドに格納できます。 データはスキーマレス デザインで格納されるので、新しい属性を持つオブジェクトがテーブルに追加されると、新しいプロパティ (列) がテーブルに自動的に追加されます。

Java アプリケーションは、azure-data-tables クライアント ライブラリを使用して Azure Cosmos DB Tables API にアクセスできます。

前提条件

サンプル アプリケーションは Spring Boot 2.6.4 で記述されています。Visual Studio Code、または IntelliJ IDEA を IDE として使用できます。

Azure サブスクリプションをお持ちでない場合は、開始する前に無料アカウントを作成してください。

サンプル アプリケーション

このチュートリアルのサンプル アプリケーションは、リポジトリ (https://github.com/Azure-Samples/msdocs-azure-data-tables-sdk-java) からクローンまたはダウンロードできます。 サンプル リポジトリには、スターターと完成したアプリの両方が含まれています。

git clone https://github.com/Azure-Samples/msdocs-azure-data-tables-sdk-java

サンプル アプリケーションでは、気象データを例に Tables API の機能を説明しています。 気象観測を表すオブジェクトの格納と取得には Table 用 API が使用されます。これには、Tables API のスキーマレス機能を示すために追加のプロパティを持つオブジェクトを格納する操作が含まれます。

Table API を使用して Azure Cosmos DB テーブルへ格納されたデータを示す、完成したアプリケーションのスクリーンショット。

1 - Azure Cosmos DB アカウントを作成する

まず、自分のアプリケーションで使用するテーブルが組み込まれる Azure Cosmos DB Tables API アカウントを作成します。 これを行うには、Azure portal、Azure CLI、または Azure PowerShell を使用します。

Azure portal にサインインし、これらの手順に従って Azure Cosmos DB アカウントを作成します。

手順 Screenshot
Azure portal で次の操作を行います。
  1. Azure portal の上部の検索バーに「Azure Cosmos DB」と入力します。
  2. 検索バーの下に表示されるメニューの [サービス] で、「Azure Cosmos DB」とラベル付けされた項目を選択します。
上部のツール バーにある検索ボックスを使用して、Azure で Azure Cosmos DB アカウントを検索する方法を示すスクリーンショット。
[Azure Cosmos DB] ページで、[+作成] を選択します。 Azure の Azure Cosmos DB アカウントのページでの [作成] ボタンの場所を示すスクリーンショット。
[API オプションの選択] ページで、[Azure テーブル] オプションを選択します。 [Azure テーブル] オプションが選択すべき正しいオプションとして示されているスクリーンショット。
[Azure Cosmos DB アカウントの作成] - [Azure テーブル] ページで、フォームに次のように入力します。
  1. [リソース グループ] の下にある [新規作成] リンクを選択して、rg-msdocs-tables-sdk-demo という名前のストレージ アカウントの新しいリソース グループを作成します。
  2. ストレージ アカウントに、cosmos-msdocs-tables-sdk-demo-XYZ の名前を付けます。ここで XYZ は一意のアカウント名を作成するための任意のランダムな 3 文字です。 Azure Cosmos DB アカウント名の長さは 3 - 44 文字で、小文字、数字、またはハイフン (-) 文字のみを使用できます。
  3. ストレージ アカウントのリージョンを選択します。
  4. [標準] のパフォーマンスを選択します。
  5. [容量モード] で、この例の [プロビジョニングされたスループット] を選択します。
  6. この例の [Free レベル割引の適用][適用] を選択します。
  7. 画面の下部にある [確認と作成] ボタンを選択し、概要画面で [作成] を選択して、Azure Cosmos DB アカウントを作成します。 このプロセスには数分かかることがあります。
Azure Cosmos DB アカウント作成ページのフィールドへの入力方法を示すスクリーンショット。

2 - テーブルを作成する

次に、アプリケーションで使用するテーブルを Azure Cosmos DB アカウント内に作成する必要があります。 従来のデータベースとは異なり、指定する必要があるのはテーブルの名前のみであり、テーブルのプロパティ (列) は指定する必要はありません。 データがテーブルに読み込まれると、必要に応じてプロパティ (列) が自動的に作成されます。

Azure portal で次の手順を実行して、Azure Cosmos DB アカウント内にテーブルを作成します。

手順 Screenshot
次の Azure portal で、Azure Cosmos DB アカウントの概要ページに移動します。 Azure Cosmos DB アカウントの概要ページに移動するには、上部の検索バーに Azure Cosmos DB アカウントの名前 (cosmos-msdocs-tables-sdk-demo-XYZ) を入力し、リソース見出しの下を確認します。ご自分の Azure Cosmos DB アカウントの名前を選択して概要ページに移動します。 上部のツール バーにある検索ボックスを使用して、Azure Cosmos DB アカウントを検索する方法を示すスクリーンショット。
[概要] ページで、[+テーブルの追加] を選択します。 [新しいテーブル] ダイアログがページの右側からスライドアウトします。 [テーブルの追加] ボタンの位置を示すスクリーンショット。
[新しいテーブル] ダイアログで、次のようにフォームに記入します。
  1. テーブル ID として「WeatherData」という名前を入力します。 これがテーブルの名前になります。
  2. この例では "テーブル スループット (自動スケール) " の下で [手動] を選択します。
  3. 推定 RU/秒で既定値の 400 を使用します。
  4. [OK] ボタンを選択してテーブルを作成します。
[新しいテーブル] ダイアログ ボックスで Azure Cosmos DB テーブルの情報の入力方法を示すスクリーンショット。

3 - Azure Cosmos DB 接続文字列を取得する

Azure Cosmos DB 内のテーブルにアクセスするには、アプリに CosmosDB Storage アカウントのテーブル接続文字列が必要です。 この接続文字列は、Azure portal、Azure CLI、または Azure PowerShell を使用して取得できます。

手順 Screenshot
Azure Cosmos DB アカウント ページの左側にある [設定] ヘッダーの下で [接続文字列] という名前のメニュー項目を見つけて選択します。 ストレージ アカウントの接続文字列を取得できるページが表示されます。 Azure Cosmos DB ページの接続文字列リンクの位置を示すスクリーンショット。
[プライマリ接続文字列] の値をコピーして、アプリケーションで使用します。 選択してアプリケーションで使用する接続文字列を示すスクリーンショット。

Azure Cosmos DB アカウントの接続文字列はアプリのシークレットと見なされ、他のアプリのシークレットやパスワードと同様に保護する必要があります。 この例では POM を使用して、開発中に接続文字列を保管し、アプリケーションで使用できるようにします。

<profiles>
    <profile>
        <id>local</id>
        <properties>
            <azure.tables.connection.string>
                <![CDATA[YOUR-DATA-TABLES-SERVICE-CONNECTION-STRING]]>
            </azure.tables.connection.string>
            <azure.tables.tableName>WeatherData</azure.tables.tableName>
        </properties>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
</profiles>

4 - azure-data-tables パッケージを含める

Java アプリケーションから Azure Cosmos DB Tables API にアクセスするには、azure-data-tables パッケージを含めます。

<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-data-tables</artifactId>
    <version>12.2.1</version>
</dependency>

5 - TableServiceConfig.java に Table クライアントを構成する

Azure SDK は、クライアント オブジェクトを使用して Azure と通信し、Azure に対してさまざまな操作を実行します。 TableClient オブジェクトは、Azure Cosmos DB Tables API と通信するために使用されるオブジェクトです。

通常、アプリケーションではテーブルごとに 1 つの TableClient オブジェクトが作成され、アプリケーション全体で使用されます。 Spring コンテナーで管理し、これを実現するシングルトンとして TableClient オブジェクト Bean をメソッドで生成することを示すことをお勧めします。

アプリケーションの TableServiceConfig.java ファイルで、次のコード スニペットと一致するように tableClientConfiguration() メソッドを編集します。

@Configuration
public class TableServiceConfiguration {

    private static String TABLE_NAME;

    private static String CONNECTION_STRING;

    @Value("${azure.tables.connection.string}")
    public void setConnectionStringStatic(String connectionString) {
        TableServiceConfiguration.CONNECTION_STRING = connectionString;
    }

    @Value("${azure.tables.tableName}")
    public void setTableNameStatic(String tableName) {
        TableServiceConfiguration.TABLE_NAME = tableName;
    }

    @Bean
    public TableClient tableClientConfiguration() {
        return new TableClientBuilder()
                .connectionString(CONNECTION_STRING)
                .tableName(TABLE_NAME)
                .buildClient();
    }
    
}

また、次の using ステートメントを TableServiceConfig.java ファイルの先頭に追加する必要もあります。

import com.azure.data.tables.TableClient;
import com.azure.data.tables.TableClientBuilder;

6 - Azure Cosmos DB テーブル操作を実装する

サンプル アプリケーションの Azure Cosmos DB テーブル操作はすべて、Services ディレクトリにあるクラス TablesServiceImpl に実装されます。 com.azure.data.tables SDK パッケージをインポートする必要があります。

import com.azure.data.tables.TableClient;
import com.azure.data.tables.models.ListEntitiesOptions;
import com.azure.data.tables.models.TableEntity;
import com.azure.data.tables.models.TableTransactionAction;
import com.azure.data.tables.models.TableTransactionActionType;

TableServiceImpl クラスの先頭に、TableClient オブジェクトのメンバー変数と、TableClient オブジェクトをクラスに挿入するためのコンストラクターを追加します。

@Autowired
private TableClient tableClient;

テーブルから行を取得する

TableClient クラスに含まれている listEntities メソッドにより、テーブルから行を選択できるようになります。 この例では、このメソッドにパラメーターが渡されないため、テーブルからすべての行が選択されます。

このメソッドは、返されるモデル クラス データを指定する TableEntity 型のジェネリック パラメーターも取ります。 このケースでは、組み込みの TableEntity クラスが使用されます。つまり、listEntities メソッドは結果として PagedIterable<TableEntity> コレクションを返します。

public List<WeatherDataModel> retrieveAllEntities() {
    List<WeatherDataModel> modelList = tableClient.listEntities().stream()
        .map(WeatherDataUtils::mapTableEntityToWeatherDataModel)
        .collect(Collectors.toList());
    return Collections.unmodifiableList(WeatherDataUtils.filledValue(modelList));
}

com.azure.data.tables.models パッケージで定義されている TableEntity クラスには、テーブルのパーティション キーと行キーの値のプロパティが含まれています。 この 2 つの値により、テーブル内の行の一意のキーが形成されます。 このサンプル アプリケーションでは、観測所 (市町村) の名前がパーティション キーに格納され、観測日時が行キーに格納されます。 その他のプロパティ (温度、湿度、風速) はすべて、TableEntity オブジェクトのディクショナリに格納されます。

一般的に、TableEntity オブジェクトは各自で定義するオブジェクトにマップします。 サンプル アプリケーションでは、この目的で Models ディレクトリに WeatherDataModel クラスが定義されます。 このクラスには観測所名と観測日のプロパティが含まれており、これらのプロパティにパーティション キーと行キーがマップされます。これにより、これらの値についてよりわかりやすいプロパティ名が提供されます。 そして、オブジェクトのその他のプロパティをすべて格納するため、ディクショナリが使用されます。 これはテーブル ストレージを使用する場合の一般的なパターンです。行には任意の数のプロパティを追加でき、モデル オブジェクトでそれらをすべて取り込む必要があるためです。 このクラスには、クラスのプロパティをリストするメソッドも含まれています。

public class WeatherDataModel {

    public WeatherDataModel(String stationName, String observationDate, OffsetDateTime timestamp, String etag) {
        this.stationName = stationName;
        this.observationDate = observationDate;
        this.timestamp = timestamp;
        this.etag = etag;
    }

    private String stationName;

    private String observationDate;

    private OffsetDateTime timestamp;

    private String etag;

    private Map<String, Object> propertyMap = new HashMap<String, Object>();

    public String getStationName() {
        return stationName;
    }

    public void setStationName(String stationName) {
        this.stationName = stationName;
    }

    public String getObservationDate() {
        return observationDate;
    }

    public void setObservationDate(String observationDate) {
        this.observationDate = observationDate;
    }

    public OffsetDateTime getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(OffsetDateTime timestamp) {
        this.timestamp = timestamp;
    }

    public String getEtag() {
        return etag;
    }

    public void setEtag(String etag) {
        this.etag = etag;
    }

    public Map<String, Object> getPropertyMap() {
        return propertyMap;
    }

    public void setPropertyMap(Map<String, Object> propertyMap) {
        this.propertyMap = propertyMap;
    }
}

mapTableEntityToWeatherDataModel メソッドは、TableEntity オブジェクトを WeatherDataModel オブジェクトにマップするために使用されます。 mapTableEntityToWeatherDataModel メソッドは、PartitionKeyRowKeyTimestamp、および Etag の各プロパティを直接マップし、properties.keySet を使用して TableEntity オブジェクト内の他のプロパティを反復処理し、これらのプロパティのうち、既に直接マップされているプロパティを除くすべてを WeatherDataModel オブジェクトにマップします。

次のコード ブロックと一致するように mapTableEntityToWeatherDataModel メソッドのコードを編集します。

public static WeatherDataModel mapTableEntityToWeatherDataModel(TableEntity entity) {
    WeatherDataModel observation = new WeatherDataModel(
        entity.getPartitionKey(), entity.getRowKey(),
        entity.getTimestamp(), entity.getETag());
    rearrangeEntityProperties(observation.getPropertyMap(), entity.getProperties());
    return observation;
}

private static void rearrangeEntityProperties(Map<String, Object> target, Map<String, Object> source) {
    Constants.DEFAULT_LIST_OF_KEYS.forEach(key -> {
        if (source.containsKey(key)) {
            target.put(key, source.get(key));
        }
    });
    source.keySet().forEach(key -> {
        if (Constants.DEFAULT_LIST_OF_KEYS.parallelStream().noneMatch(defaultKey -> defaultKey.equals(key))
        && Constants.EXCLUDE_TABLE_ENTITY_KEYS.parallelStream().noneMatch(defaultKey -> defaultKey.equals(key))) {
            target.put(key, source.get(key));
        }
    });
}

テーブルから返された行をフィルター処理する

テーブルから返された行をフィルター処理するには、OData スタイルのフィルター文字列を listEntities メソッドに渡します。 たとえば、2021 年 7 月 1 日午前 0 時から 2021 年 7 月 2 日午前 0 時 (午前 0 時を含む) までの Chicago の気象記録をすべて取得するには、次のフィルター文字列を渡します。

PartitionKey eq 'Chicago' and RowKey ge '2021-07-01 12:00 AM' and RowKey le '2021-07-02 12:00 AM'

すべての OData フィルター演算子については、OData Web サイトの Filter System Query Option に関するセクションで確認できます。

このサンプル アプリケーションでは、FilterResultsInputModel オブジェクトは、ユーザーが指定したフィルター条件をすべて取り込むように設計されています。

public class FilterResultsInputModel implements Serializable {

    private String partitionKey;

    private String rowKeyDateStart;

    private String rowKeyTimeStart;

    private String rowKeyDateEnd;

    private String rowKeyTimeEnd;

    private Double minTemperature;

    private Double maxTemperature;

    private Double minPrecipitation;

    private Double maxPrecipitation;

    public String getPartitionKey() {
        return partitionKey;
    }

    public void setPartitionKey(String partitionKey) {
        this.partitionKey = partitionKey;
    }

    public String getRowKeyDateStart() {
        return rowKeyDateStart;
    }

    public void setRowKeyDateStart(String rowKeyDateStart) {
        this.rowKeyDateStart = rowKeyDateStart;
    }

    public String getRowKeyTimeStart() {
        return rowKeyTimeStart;
    }

    public void setRowKeyTimeStart(String rowKeyTimeStart) {
        this.rowKeyTimeStart = rowKeyTimeStart;
    }

    public String getRowKeyDateEnd() {
        return rowKeyDateEnd;
    }

    public void setRowKeyDateEnd(String rowKeyDateEnd) {
        this.rowKeyDateEnd = rowKeyDateEnd;
    }

    public String getRowKeyTimeEnd() {
        return rowKeyTimeEnd;
    }

    public void setRowKeyTimeEnd(String rowKeyTimeEnd) {
        this.rowKeyTimeEnd = rowKeyTimeEnd;
    }

    public Double getMinTemperature() {
        return minTemperature;
    }

    public void setMinTemperature(Double minTemperature) {
        this.minTemperature = minTemperature;
    }

    public Double getMaxTemperature() {
        return maxTemperature;
    }

    public void setMaxTemperature(Double maxTemperature) {
        this.maxTemperature = maxTemperature;
    }

    public Double getMinPrecipitation() {
        return minPrecipitation;
    }

    public void setMinPrecipitation(Double minPrecipitation) {
        this.minPrecipitation = minPrecipitation;
    }

    public Double getMaxPrecipitation() {
        return maxPrecipitation;
    }

    public void setMaxPrecipitation(Double maxPrecipitation) {
        this.maxPrecipitation = maxPrecipitation;
    }
}

このオブジェクトが TableServiceImpl クラスの retrieveEntitiesByFilter メソッドに渡されると、null 以外のプロパティ値ごとにフィルター文字列が作成されます。 次に、"and" 句を使用してすべての値を結合することで、結合フィルター文字列が作成されます。 この結合フィルター文字列は TableClient オブジェクトの listEntities メソッドに渡され、フィルター文字列に一致する行だけが返されます。 同様のメソッドをコード内で使用して、各自のアプリケーションで必要に応じて適切なフィルター文字列を作成できます。

public List<WeatherDataModel> retrieveEntitiesByFilter(FilterResultsInputModel model) {

    List<String> filters = new ArrayList<>();

    if (!StringUtils.isEmptyOrWhitespace(model.getPartitionKey())) {
        filters.add(String.format("PartitionKey eq '%s'", model.getPartitionKey()));
    }
    if (!StringUtils.isEmptyOrWhitespace(model.getRowKeyDateStart())
            && !StringUtils.isEmptyOrWhitespace(model.getRowKeyTimeStart())) {
        filters.add(String.format("RowKey ge '%s %s'", model.getRowKeyDateStart(), model.getRowKeyTimeStart()));
    }
    if (!StringUtils.isEmptyOrWhitespace(model.getRowKeyDateEnd())
            && !StringUtils.isEmptyOrWhitespace(model.getRowKeyTimeEnd())) {
        filters.add(String.format("RowKey le '%s %s'", model.getRowKeyDateEnd(), model.getRowKeyTimeEnd()));
    }
    if (model.getMinTemperature() != null) {
        filters.add(String.format("Temperature ge %f", model.getMinTemperature()));
    }
    if (model.getMaxTemperature() != null) {
        filters.add(String.format("Temperature le %f", model.getMaxTemperature()));
    }
    if (model.getMinPrecipitation() != null) {
        filters.add(String.format("Precipitation ge %f", model.getMinPrecipitation()));
    }
    if (model.getMaxPrecipitation() != null) {
        filters.add(String.format("Precipitation le %f", model.getMaxPrecipitation()));
    }

    List<WeatherDataModel> modelList = tableClient.listEntities(new ListEntitiesOptions()
        .setFilter(String.join(" and ", filters)), null, null).stream()
        .map(WeatherDataUtils::mapTableEntityToWeatherDataModel)
        .collect(Collectors.toList());
    return Collections.unmodifiableList(WeatherDataUtils.filledValue(modelList));
}

TableEntity オブジェクトを使用してデータを挿入する

テーブルにデータを追加する最も簡単な方法は TableEntity オブジェクトを使用する方法です。 この例では、データが入力モデル オブジェクトから TableEntity オブジェクトにマップされます。 入力オブジェクトで観測所名と観測日時を表すプロパティは、PartitionKey および RowKey プロパティにそれぞれマップされ、これらによりテーブル内の行の一意のキーが形成されます。 その後、入力モデル オブジェクトの追加プロパティが TableClient オブジェクトのディクショナリ プロパティにマップされます。 最後に TableClient オブジェクトの createEntity メソッドを使用して、テーブルにデータが挿入されます。

サンプル アプリケーションの insertEntity クラスを変更して、次のコードを含めます。

public void insertEntity(WeatherInputModel model) {
    tableClient.createEntity(WeatherDataUtils.createTableEntity(model));
}

TableEntity オブジェクトを使用してデータをアップサートする

テーブルに既に存在するパーティション キーと行キーの組み合わせでそのテーブルに行を挿入しようとすると、エラーが発生します。 このため多くの場合、テーブルに行を追加するときには insertEntity メソッドの代わりに upsertEntity を使用することが推奨されます。 指定されたパーティション キーと行キーの組み合わせがテーブルに既に存在する場合は、upsertEntity メソッドにより既存の行が更新されます。 それ以外の場合は行がテーブルに追加されます。

public void upsertEntity(WeatherInputModel model) {
    tableClient.upsertEntity(WeatherDataUtils.createTableEntity(model));
}

可変プロパティを使用してデータを挿入またはアップサートする

Azure Cosmos DB Tables API を使用する利点の 1 つは、テーブルに読み込まれるオブジェクトに新しいプロパティが含まれている場合、それらのプロパティがテーブルに自動的に追加され、値が Azure Cosmos DB に格納されることです。 従来のデータベースのように、ALTER TABLE などの DDL ステートメントを実行して列を追加する必要はありません。

このモデルを使用すると、時間の経過とともに取り込む必要があるデータを追加または変更する可能性のあるデータ ソースを扱う場合や、異なる入力によりアプリケーションに異なるデータを提供する場合に、アプリケーションに柔軟性が加わります。 サンプル アプリケーションでは、基本的な気象データの他にいくつかの追加の値も送信する観測所をシミュレートできます。 このような新しいプロパティを持つオブジェクトが初めてテーブルに格納されるときに、対応するプロパティ (列) がテーブルに自動的に追加されます。

サンプル アプリケーションでは、オブジェクトのあらゆるプロパティに対応できるように、内部ディクショナリをに基づいて ExpandableWeatherObject クラスが作成されています。 このクラスは、オブジェクトに任意のプロパティ セットが含まれている必要がある場合の一般的なパターンを表します。

public class ExpandableWeatherObject {

    private String stationName;

    private String observationDate;

    private Map<String, Object> propertyMap = new HashMap<String, Object>();

    public String getStationName() {
        return stationName;
    }

    public void setStationName(String stationName) {
        this.stationName = stationName;
    }

    public String getObservationDate() {
        return observationDate;
    }

    public void setObservationDate(String observationDate) {
        this.observationDate = observationDate;
    }

    public Map<String, Object> getPropertyMap() {
        return propertyMap;
    }

    public void setPropertyMap(Map<String, Object> propertyMap) {
        this.propertyMap = propertyMap;
    }

    public boolean containsProperty(String key) {
        return this.propertyMap.containsKey(key);
    }

    public Object getPropertyValue(String key) {
        return containsProperty(key) ? this.propertyMap.get(key) : null;
    }

    public void putProperty(String key, Object value) {
        this.propertyMap.put(key, value);
    }

    public List<String> getPropertyKeys() {
        List<String> list = Collections.synchronizedList(new ArrayList<String>());
        Iterator<String> iterators = this.propertyMap.keySet().iterator();
        while (iterators.hasNext()) {
            list.add(iterators.next());
        }
        return Collections.unmodifiableList(list);
    }

    public Integer getPropertyCount() {
        return this.propertyMap.size();
    }
}

Table 用 API を使用してこのようなオブジェクトを挿入またはアップサートするには、展開可能なオブジェクトのプロパティをTableEntity オブジェクトにマップし、必要に応じてTableClient オブジェクトの createEntity または upsertEntity メソッドを使用します。

public void insertExpandableEntity(ExpandableWeatherObject model) {
    tableClient.createEntity(WeatherDataUtils.createTableEntity(model));
}

public void upsertExpandableEntity(ExpandableWeatherObject model) {
    tableClient.upsertEntity(WeatherDataUtils.createTableEntity(model));
}

エンティティを更新する

エンティティを更新するには、TableClient オブジェクトの updateEntity メソッドを呼び出します。 Tables API を使用して格納されるエンティティ (行) には任意のプロパティ セットが含まれている可能性があるため、多くの場合、前述の ExpandableWeatherObject と同様にディクショナリ オブジェクトに基づいて更新オブジェクトを作成すると便利です。 ここで唯一異なる点は、更新中の同時実行制御に使用される etag プロパティを追加することです。

public class UpdateWeatherObject {

    private String stationName;

    private String observationDate;

    private String etag;

    private Map<String, Object> propertyMap = new HashMap<String, Object>();

    public String getStationName() {
        return stationName;
    }

    public void setStationName(String stationName) {
        this.stationName = stationName;
    }

    public String getObservationDate() {
        return observationDate;
    }

    public void setObservationDate(String observationDate) {
        this.observationDate = observationDate;
    }

    public String getEtag() {
        return etag;
    }

    public void setEtag(String etag) {
        this.etag = etag;
    }

    public Map<String, Object> getPropertyMap() {
        return propertyMap;
    }

    public void setPropertyMap(Map<String, Object> propertyMap) {
        this.propertyMap = propertyMap;
    }
}

サンプル アプリケーションでは、このオブジェクトは TableServiceImpl クラスの updateEntity メソッドに渡されます。 このメソッドは、最初に TableClientgetEntity メソッドを使用して Tables API から既存のエンティティを読み込みます。 その後、そのエンティティ オブジェクトを更新し、updateEntity メソッドを使用して更新内容をデータベースに保存します。 updateEntity メソッドがオブジェクトの現在の Etag を取得して、オブジェクトが最初に読み込まれてから変更されていないことを確認する方法に注目してください。 それに関係なくエンティティを更新する必要がある場合は、etag の値を updateEntity メソッドに渡します。

public void updateEntity(UpdateWeatherObject model) {
    TableEntity tableEntity = tableClient.getEntity(model.getStationName(), model.getObservationDate());
    Map<String, Object> propertiesMap = model.getPropertyMap();
    propertiesMap.keySet().forEach(key -> tableEntity.getProperties().put(key, propertiesMap.get(key)));
    tableClient.updateEntity(tableEntity);
}

エンティティを削除する

テーブルからエンティティを削除するには、TableClient オブジェクトの deleteEntity メソッドを呼び出します。その際に、このオブジェクトのパーティション キーと行キーを指定します。

public void deleteEntity(WeatherInputModel model) {
    tableClient.deleteEntity(model.getStationName(),
            WeatherDataUtils.formatRowKey(model.getObservationDate(), model.getObservationTime()));
}

7 - コードを実行する

サンプル アプリケーションを実行して、Azure Cosmos DB Tables API を操作します。 アプリケーションを初めて実行する場合にはテーブルが空であるため、データがありません。 アプリケーションの上部にあるいずれかのボタンを使用して、テーブルにデータを追加します。

Table API を使用して Azure Cosmos DB にデータを挿入するためのボタンの位置を示すアプリケーションのスクリーンショット。

[Insert using Table Entity](テーブル エンティティを使用して挿入) ボタンを選択すると、TableEntity オブジェクトを使用して新しい行を挿入またはアップサートできるダイアログが開きます。

TableEntity オブジェクトを使用してデータを挿入するために使用されるダイアログ ボックスを示すアプリケーションのスクリーンショット。

[Insert using Expandable Data] (展開可能なデータを使用して挿入) ボタンを選択すると、カスタム プロパティを持つオブジェクトを挿入できるダイアログが表示され、Azure Cosmos DB Tables API によって必要に応じてプロパティ (列) がテーブルに自動的に追加される方法が示されます。 [カスタム フィールドの追加] ボタンを使用して、1 つ以上の新しいプロパティを追加し、この機能を示します。

カスタム フィールドのあるオブジェクトを使用してデータを挿入するために使用されるダイアログ ボックスを示すアプリケーションのスクリーンショット。

[サンプル データを挿入] ボタンを使用して、一部のサンプル データを Azure Cosmos DB テーブルに読み込みます。

サンプル データ挿入ボタンの位置を示すアプリケーションのスクリーンショット。

上部のメニューの [Filter Results](結果のフィルター処理) 項目を選択すると、[Filter Results](結果のフィルター処理) ページが表示されます。 フィルター句を作成して Azure Cosmos DB Tables API に渡す方法を示すため、このページでフィルター条件を入力します。

結果のフィルター処理ページが表示され、そのページへの移動に使用するメニュー項目が強調表示されているアプリケーションのスクリーンショット。

リソースをクリーンアップする

サンプル アプリケーションの使用が完了したら、この記事に関連するすべての Azure リソースを Azure アカウントから削除する必要があります。 このためには、リソース グループを削除します。

Azure portal を使用してリソース グループを削除するには、次の手順を実行します。

手順 Screenshot
リソース グループに進むには、検索バーにリソース グループの名前を入力します。 次に [リソース グループ] タブで、リソース グループの名前を選択します。 リソース グループを検索する方法を示すスクリーンショット。
リソース グループ ページの上部のツール バーから [リソース グループの削除] を選択します。 [リソース グループの削除] ボタンの位置を示すスクリーンショット。
リソース グループの削除を確認するダイアログが画面の右側に表示されます。
  1. テキスト ボックスにリソース グループの名前を完全に入力し、指示に従って削除を確認します。
  2. ページ下部の [削除] ボタンを選択します。
リソース グループを削除するための確認ダイアログを示すスクリーンショット。

次のステップ

このクイック スタートでは、Azure Cosmos DB アカウントを作成し、データ エクスプローラーを使用してテーブルを作成し、アプリを実行する方法を説明しました。 これで、Table 用 API を使用してデータに対してクエリを実行できるようになりました。