Partilhar via


Guia de início rápido: criar uma API para o aplicativo Table com o Java SDK e o Azure Cosmos DB

APLICA-SE A: Tabela

Este guia de início rápido mostra como acessar a API de Tabelas do Azure Cosmos DB a partir de um aplicativo Java. A API de Tabelas do Azure Cosmos DB é um armazenamento de dados sem esquema que permite que os aplicativos armazenem dados NoSQL estruturados na nuvem. Como os dados são armazenados em um design sem esquema, novas propriedades (colunas) são adicionadas automaticamente à tabela quando um objeto com um novo atributo é adicionado à tabela.

Os aplicativos Java podem acessar a API de Tabelas do Azure Cosmos DB usando a biblioteca de cliente azure-data-tables .

Pré-requisitos

O aplicativo de exemplo é escrito em Spring Boot 2.6.4, Você pode usar o Visual Studio Code ou IntelliJ IDEA como um IDE.

Se não tiver uma subscrição do Azure, crie uma conta gratuita antes de começar.

Aplicação de exemplo

O aplicativo de exemplo para este tutorial pode ser clonado ou baixado do repositório https://github.com/Azure-Samples/msdocs-azure-data-tables-sdk-java. Tanto um aplicativo inicial quanto um aplicativo concluído são incluídos no repositório de exemplo.

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

O aplicativo de exemplo usa dados meteorológicos como exemplo para demonstrar os recursos da API de tabelas. Os objetos que representam observações meteorológicas são armazenados e recuperados usando a API para Tabela, incluindo o armazenamento de objetos com propriedades adicionais para demonstrar os recursos sem esquema da API Tabelas.

Uma captura de tela do aplicativo concluído mostrando dados armazenados em uma tabela do Azure Cosmos DB usando a API de Tabela.

1 - Criar uma conta do Azure Cosmos DB

Primeiro, você precisa criar uma conta da API de Tabelas do Azure Cosmos DB que conterá a(s) tabela(s) usada(s) em seu aplicativo. Isso pode ser feito usando o portal do Azure, a CLI do Azure ou o Azure PowerShell.

Entre no portal do Azure e siga estas etapas para criar uma conta do Azure Cosmos DB.

Instruções Captura de ecrã
No portal do Azure:
  1. Na barra de pesquisa na parte superior do portal do Azure, digite "Azure Cosmos DB".
  2. No menu que aparece abaixo da barra de pesquisa, em Serviços, selecione o item rotulado Azure Cosmos DB.
Uma captura de tela mostrando como usar a caixa de pesquisa na barra de ferramentas superior para localizar contas do Azure Cosmos DB no Azure.
Na página do Azure Cosmos DB, selecione +Criar. Uma captura de tela mostrando o local do botão Criar na página Contas do Azure Cosmos DB no Azure.
Na página de opção Selecionar API, escolha a opção Tabela do Azure. Uma captura de tela mostrando a opção Tabela do Azure como a opção correta a ser selecionada.
Na página Criar Conta do Azure Cosmos DB - Tabela do Azure, preencha o formulário da seguinte forma.
  1. Crie um novo grupo de recursos para a conta de armazenamento nomeada rg-msdocs-tables-sdk-demo selecionando o link Criar novo em Grupo de recursos.
  2. Dê à sua conta de armazenamento um nome de onde XYZ são quaisquer três caracteres aleatórios para criar um nome de cosmos-msdocs-tables-sdk-demo-XYZ conta exclusivo. Os nomes de conta do Azure Cosmos DB devem ter entre 3 e 44 caracteres e podem conter apenas letras minúsculas, números ou o caractere hífen (-).
  3. Selecione a região para a sua conta de armazenamento.
  4. Selecione Desempenho padrão .
  5. Selecione Taxa de transferência provisionada para este exemplo em Modo de capacidade.
  6. Selecione Aplicar em Aplicar desconto de nível gratuito para este exemplo.
  7. Selecione o botão Rever + criar na parte inferior do ecrã e, em seguida, selecione "Criar" no ecrã de resumo para criar a sua conta do Azure Cosmos DB. Este processo pode demorar vários minutos.
Uma captura de tela mostrando como preencher os campos na página de criação de Conta do Azure Cosmos DB.

2 - Criar uma tabela

Em seguida, você precisa criar uma tabela em sua conta do Azure Cosmos DB para seu aplicativo usar. Ao contrário de um banco de dados tradicional, você só precisa especificar o nome da tabela, não as propriedades (colunas) na tabela. À medida que os dados são carregados na tabela, as propriedades (colunas) serão criadas automaticamente conforme necessário.

No portal do Azure, conclua as etapas a seguir para criar uma tabela dentro de sua conta do Azure Cosmos DB.

Instruções Captura de ecrã
No portal do Azure, navegue até a página de visão geral da conta do Azure Cosmos DB. Você pode navegar até a página de visão geral da sua conta do Azure Cosmos DB digitando o nome (cosmos-msdocs-tables-sdk-demo-XYZ) da sua conta do Azure Cosmos DB na barra de pesquisa superior e procurando sob o título de recursos. Selecione o nome da sua conta do Azure Cosmos DB para ir para a página de visão geral. Uma captura de tela mostrando como usar a caixa de pesquisa na barra de ferramentas superior para localizar sua conta do Azure Cosmos DB.
Na página de visão geral, selecione +Adicionar tabela. A caixa de diálogo Nova Tabela deslizará para fora do lado direito da página. Uma captura de tela mostrando o local do botão Adicionar tabela.
Na caixa de diálogo Nova tabela, preencha o formulário da seguinte forma.
  1. Insira o nome WeatherData para a ID da tabela. Este é o nome da tabela.
  2. Selecione Manual em Taxa de transferência de tabela (escala automática) para este exemplo.
  3. Use o valor padrão de 400 abaixo do seu RU/s estimado.
  4. Selecione o botão OK para criar a tabela.
Uma captura de tela mostrando como Nova Tabela caixa de diálogo para uma tabela do Azure Cosmos DB.

3 - Obter a cadeia de conexão do Azure Cosmos DB

Para acessar sua(s) tabela(s) no Azure Cosmos DB, seu aplicativo precisará da cadeia de conexão de tabela para a conta de Armazenamento do CosmosDB. A cadeia de conexão pode ser recuperada usando o portal do Azure, a CLI do Azure ou o Azure PowerShell.

Instruções Captura de ecrã
No lado esquerdo da página da conta do Azure Cosmos DB, localize o item de menu chamado Cadeia de Conexão sob o cabeçalho Configurações e selecione-o. Você será levado para uma página onde poderá recuperar a cadeia de conexão da conta de armazenamento. Uma captura de tela mostrando o local do link de cadeias de conexão na página do Azure Cosmos DB.
Copie o valor PRIMARY CONNECTION STRING para usar em seu aplicativo. Uma captura de tela mostrando qual cadeia de conexão selecionar e usar em seu aplicativo.

A cadeia de conexão para sua conta do Azure Cosmos DB é considerada um segredo de aplicativo e deve ser protegida como qualquer outro segredo ou senha de aplicativo. Este exemplo usa o POM para armazenar a cadeia de conexão durante o desenvolvimento e disponibilizá-la para o aplicativo.

<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 - Incluir o pacote azure-data-tables

Para acessar a API de Tabelas do Azure Cosmos DB a partir de um aplicativo Java, inclua o pacote azure-data-tables .

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

5 - Configure o cliente Table no TableServiceConfig.java

O SDK do Azure se comunica com o Azure usando objetos de cliente para executar operações diferentes no Azure. O objeto TableClient é o objeto usado para se comunicar com a API de Tabelas do Azure Cosmos DB.

Um aplicativo normalmente criará um único objeto TableClient por tabela para ser usado em todo o aplicativo. É recomendável indicar que um método produz um bean de objeto TableClient para ser gerenciado pelo contêiner Spring e como um singleton para fazer isso.

TableServiceConfig.java No arquivo do aplicativo, edite o tableClientConfiguration() método para corresponder ao seguinte trecho de código:

@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();
    }
    
}

Você também precisará adicionar a seguinte instrução using na parte superior do TableServiceConfig.java arquivo.

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

6 - Implementar operações de tabela do Azure Cosmos DB

Todas as operações de tabela do Azure Cosmos DB para o aplicativo de exemplo são implementadas na TablesServiceImpl classe localizada no diretório Serviços . Você precisará importar o com.azure.data.tables pacote 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;

No início da TableServiceImpl classe, adicione uma variável de membro para o objeto TableClient e um construtor para permitir que o objeto TableClient seja injetado na classe.

@Autowired
private TableClient tableClient;

Obter linhas de uma tabela

A classe TableClient contém um método chamado listEntities que permite selecionar linhas da tabela. Neste exemplo, como nenhum parâmetro está sendo passado para o método, todas as linhas serão selecionadas na tabela.

O método também usa um parâmetro genérico do tipo TableEntity que especifica que os dados da classe do modelo serão retornados como. Nesse caso, a classe interna TableEntity é usada, o que significa que o listEntities método retornará uma PagedIterable<TableEntity> coleção como seus resultados.

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

A classe TableEntity definida no com.azure.data.tables.models pacote tem propriedades para a chave de partição e valores de chave de linha na tabela. Juntos, esses dois valores para uma chave exclusiva para a linha na tabela. Neste exemplo de aplicação, o nome da estação meteorológica (cidade) é armazenado na chave de partição e a data/hora da observação é armazenada na chave de linha. Todas as outras propriedades (temperatura, umidade, velocidade do vento) são armazenadas em um dicionário no TableEntity objeto.

É prática comum mapear um objeto TableEntity para um objeto de sua própria definição. O aplicativo de exemplo define uma classe WeatherDataModel no diretório Models para essa finalidade. Essa classe tem propriedades para o nome da estação e a data de observação para as quais a chave de partição e a chave de linha serão mapeadas, fornecendo nomes de propriedade mais significativos para esses valores. Em seguida, ele usa um dicionário para armazenar todas as outras propriedades no objeto. Esse é um padrão comum ao trabalhar com o armazenamento de tabela, uma vez que uma linha pode ter qualquer número de propriedades arbitrárias e queremos que nossos objetos de modelo sejam capazes de capturar todas elas. Essa classe também contém métodos para listar as propriedades na classe.

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;
    }
}

O mapTableEntityToWeatherDataModel método é usado para mapear um objeto TableEntity para um WeatherDataModel objeto. O mapTableEntityToWeatherDataModel método mapeia diretamente as PartitionKeypropriedades , RowKey, Timestampe Etag e, em seguida, usa o properties.keySet para iterar sobre as outras propriedades no TableEntity objeto e mapeá-las para o WeatherDataModel objeto, menos as propriedades que já foram mapeadas diretamente.

Edite o mapTableEntityToWeatherDataModel código no método para corresponder ao seguinte bloco de código.

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));
        }
    });
}

Filtrar linhas retornadas de uma tabela

Para filtrar as linhas retornadas de uma tabela, você pode passar uma cadeia de caracteres de filtro de estilo OData para o método listEntities . Por exemplo, se você quisesse obter todas as leituras do tempo para Chicago entre a meia-noite de 1º de julho de 2021 e a meia-noite de 2 de julho de 2021 (inclusive), você passaria na seguinte cadeia de filtros.

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

Você pode exibir todos os operadores de filtro OData no site OData na seção Opção de consulta do sistema de filtro

No aplicativo de exemplo, o FilterResultsInputModel objeto é projetado para capturar qualquer critério de filtro fornecido pelo usuário.

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;
    }
}

Quando esse objeto é passado para o retrieveEntitiesByFilter método na TableServiceImpl classe, ele cria uma cadeia de caracteres de filtro para cada valor de propriedade não nula. Em seguida, ele cria uma cadeia de caracteres de filtro combinada unindo todos os valores com uma cláusula "e". Essa cadeia de caracteres de filtro combinada é passada para o método listEntities no objeto TableClient e somente as linhas correspondentes à cadeia de caracteres de filtro serão retornadas. Você pode usar um método semelhante em seu código para construir cadeias de caracteres de filtro adequadas, conforme exigido pelo seu aplicativo.

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));
}

Inserir dados usando um objeto TableEntity

A maneira mais simples de adicionar dados a uma tabela é usando um objeto TableEntity . Neste exemplo, os dados são mapeados de um objeto de modelo de entrada para um objeto TableEntity . As propriedades no objeto de entrada que representam o nome da estação meteorológica e a data/hora de observação são mapeadas para as PartitionKey propriedades e RowKey), respectivamente, que juntas formam uma chave exclusiva para a linha na tabela. Em seguida, as propriedades adicionais no objeto de modelo de entrada são mapeadas para propriedades de dicionário no objeto TableClient . Finalmente, o método createEntity no objeto TableClient é usado para inserir dados na tabela.

Modifique a insertEntity classe no aplicativo de exemplo para conter o código a seguir.

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

Dados de upsert usando um objeto TableEntity

Se tentar inserir uma linha numa tabela com uma combinação de chave de partição/chave de linha que já existe nessa tabela, receberá um erro. Por esse motivo, geralmente é preferível usar upsertEntity em vez do insertEntity método ao adicionar linhas a uma tabela. Se a combinação de chave de partição/chave de linha já existir na tabela, o método upsertEntity atualizará a linha existente. Caso contrário, a linha será adicionada à tabela.

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

Inserir ou atualizar dados com propriedades variáveis

Uma das vantagens de usar a API de Tabelas do Azure Cosmos DB é que, se um objeto que está sendo carregado em uma tabela contiver novas propriedades, essas propriedades serão adicionadas automaticamente à tabela e aos valores armazenados no Azure Cosmos DB. Não há necessidade de executar instruções DDL como ALTER TABLE adicionar colunas como em um banco de dados tradicional.

Esse modelo dá flexibilidade ao seu aplicativo ao lidar com fontes de dados que podem adicionar ou modificar quais dados precisam ser capturados ao longo do tempo ou quando entradas diferentes fornecem dados diferentes para seu aplicativo. Na aplicação de exemplo, podemos simular uma estação meteorológica que envia não apenas os dados meteorológicos base, mas também alguns valores adicionais. Quando um objeto com essas novas propriedades é armazenado na tabela pela primeira vez, as propriedades correspondentes (colunas) serão adicionadas automaticamente à tabela.

No aplicativo de exemplo, a ExpandableWeatherObject classe é criada em torno de um dicionário interno para oferecer suporte a qualquer conjunto de propriedades no objeto. Essa classe representa um padrão típico para quando um objeto precisa conter um conjunto arbitrário de propriedades.

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();
    }
}

Para inserir ou atualizar esse objeto usando a API para Table, mapeie as propriedades do objeto expansível em um objeto TableEntity e use os métodos createEntity ou upsertEntity no objeto TableClient conforme apropriado.

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

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

Atualizar uma entidade

As entidades podem ser atualizadas chamando o método updateEntity no objeto TableClient. Como uma entidade (linha) armazenada usando a API Tables pode conter qualquer conjunto arbitrário de propriedades, geralmente é útil criar um objeto de atualização com base em um objeto de dicionário semelhante ao discutido ExpandableWeatherObject anteriormente. Nesse caso, a única diferença é a adição de uma etag propriedade que é usada para controle de simultaneidade durante as atualizações.

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;
    }
}

No aplicativo de exemplo, esse objeto é passado para o updateEntity método na TableServiceImpl classe. Esse método primeiro carrega a entidade existente da API Tables usando o método getEntity no TableClient. Em seguida, ele atualiza esse objeto de entidade e usa o updateEntity método para salvar as atualizações no banco de dados. Observe como o método updateEntity usa o Etag atual do objeto para garantir que o objeto não tenha sido alterado desde que foi carregado inicialmente. Se você quiser atualizar a entidade independentemente disso, você pode passar um valor de etag para o updateEntity método.

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);
}

Remover uma entidade

Para remover uma entidade de uma tabela, chame o método deleteEntity no objeto TableClient com a chave de partição e a chave de linha do objeto.

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

7 - Execute o código

Execute o aplicativo de exemplo para interagir com a API de Tabelas do Azure Cosmos DB. Na primeira vez que você executar o aplicativo, não haverá dados porque a tabela está vazia. Use qualquer um dos botões na parte superior do aplicativo para adicionar dados à tabela.

Uma captura de tela do aplicativo mostrando o local dos botões usados para inserir dados no Azure Cosmos DB usando a API de tabela.

Selecionar o botão Inserir usando entidade da tabela abre uma caixa de diálogo que permite inserir ou atualizar uma nova linha usando um TableEntity objeto.

Uma captura de tela do aplicativo mostrando a caixa de diálogo usada para inserir dados usando um objeto TableEntity.

Selecionar o botão Inserir usando dados expansíveis exibe uma caixa de diálogo que permite inserir um objeto com propriedades personalizadas, demonstrando como a API de Tabelas do Azure Cosmos DB adiciona automaticamente propriedades (colunas) à tabela quando necessário. Use o botão Adicionar campo personalizado para adicionar uma ou mais novas propriedades e demonstrar esse recurso.

Uma captura de tela do aplicativo mostrando a caixa de diálogo usada para inserir dados usando um objeto com campos personalizados.

Use o botão Inserir Dados de Exemplo para carregar alguns dados de exemplo em sua tabela do Azure Cosmos DB.

Uma captura de tela do aplicativo mostrando o local do botão de inserção de dados de exemplo.

Selecione o item Filtrar Resultados no menu superior para ser direcionado para a página Resultados do Filtro. Nesta página, preencha os critérios de filtro para demonstrar como uma cláusula de filtro pode ser criada e passada para a API de Tabelas do Azure Cosmos DB.

Uma captura de tela do aplicativo mostrando a página de resultados do filtro e destacando o item de menu usado para navegar até a página.

Clean up resources (Limpar recursos)

Quando terminar o aplicativo de exemplo, remova todos os recursos do Azure relacionados a este artigo da sua conta do Azure. Você pode fazer isso excluindo o grupo de recursos.

Um grupo de recursos pode ser excluído usando o portal do Azure fazendo o seguinte.

Instruções Captura de ecrã
Para ir para o grupo de recursos, na barra de pesquisa, digite o nome do grupo de recursos. Em seguida, na guia Grupos de Recursos , selecione o nome do grupo de recursos. Uma captura de tela mostrando como procurar um grupo de recursos.
Selecione Excluir grupo de recursos na barra de ferramentas na parte superior da página do grupo de recursos. Uma captura de tela mostrando o local do botão Excluir grupo de recursos.
Uma caixa de diálogo aparecerá à direita da tela solicitando que você confirme a exclusão do grupo de recursos.
  1. Digite o nome completo do grupo de recursos na caixa de texto para confirmar a exclusão, conforme instruído.
  2. Selecione o botão Excluir na parte inferior da página.
Uma captura de tela mostrando a caixa de diálogo de confirmação para excluir um grupo de recursos.

Próximos passos

Neste guia de introdução, aprendeu a criar uma conta do Azure Cosmos DB, a criar uma tabela com o Data Explorer e a executar uma aplicação. Agora você pode consultar seus dados usando a API para Tabela.