如何通过 Java 使用 Azure 表存储或 Azure Cosmos DB 表 APIHow to use Azure Table storage or Azure Cosmos DB Table API from Java

Tip

本文中的内容适用于 Azure 表存储和 Azure Cosmos DB 表 API。The content in this article applies to Azure Table storage and the Azure Cosmos DB Table API. Azure Cosmos DB 表 API 是表存储的高级产品,可提供吞吐量优化表、全局分发和自动辅助索引。The Azure Cosmos DB Table API is a premium offering for table storage that offers throughput-optimized tables, global distribution, and automatic secondary indexes.

概述Overview

本文演示如何使用 Azure 表存储服务和 Azure Cosmos DB 执行常见方案。This article demonstrates how to perform common scenarios using the Azure Table storage service and Azure Cosmos DB. 这些示例用 Java 编写并使用用于 Java 的 Azure 存储 SDKThe samples are written in Java and use the Azure Storage SDK for Java. 涉及的方案包括创建列出删除表,以及插入查询修改删除表中的实体。The scenarios covered include creating, listing, and deleting tables, as well as inserting, querying, modifying, and deleting entities in a table. 有关表的详细信息,请参阅后续步骤部分。For more information on tables, see the Next steps section.

Note

SDK 提供给在 Android 设备上使用 Azure 存储的开发人员。An SDK is available for developers who are using Azure Storage on Android devices. 有关详细信息,请参阅用于 Android 的 Azure 存储 SDKFor more information, see the Azure Storage SDK for Android.

创建 Azure 服务帐户Create an Azure service account

可以通过 Azure 表存储或 Azure Cosmos DB 使用表。You can work with tables using Azure Table storage or Azure Cosmos DB. 若要了解有关服务之间差异的详细信息,请参阅表产品To learn more about the differences between the services, see Table offerings. 需要为所要使用的服务创建一个帐户。You'll need to create an account for the service you're going to use.

创建 Azure 存储帐户Create an Azure storage account

创建 Azure 存储帐户的最简单方法是使用 Azure 门户The easiest way to create an Azure storage account is by using the Azure portal. 若要了解更多信息,请参阅 创建存储帐户To learn more, see Create a storage account.

也可以使用 Azure PowerShellAzure CLI 创建 Azure 存储帐户。You can also create an Azure storage account by using Azure PowerShell or Azure CLI.

如果暂时不想创建存储帐户,也可以使用 Azure 存储模拟器在本地环境中运行和测试代码。If you prefer not to create a storage account at this time, you can also use the Azure storage emulator to run and test your code in a local environment. 有关详细信息,请参阅使用 Azure 存储模拟器进行开发和测试For more information, see Use the Azure storage emulator for development and testing.

创建 Azure Cosmos DB 帐户Create an Azure Cosmos DB account

有关创建 Azure Cosmos DB 表 API 帐户的说明,请参阅创建数据库帐户For instructions on creating an Azure Cosmos DB Table API account, see Create a database account.

创建 Java 应用程序Create a Java application

在本指南中,将使用存储功能,这些功能可在本地 Java 应用程序中运行,或通过 Azure 的 Web 角色或辅助角色中运行的代码运行。In this guide, you will use storage features that you can run in a Java application locally, or in code running in a web role or worker role in Azure.

若要使用本文中的示例,请安装 Java 开发工具包 (JDK),并在 Azure 订阅中创建一个 Azure 存储帐户或 Azure Cosmos DB 帐户。To use the samples in this article, install the Java Development Kit (JDK), then create an Azure storage account or Azure Cosmos DB account in your Azure subscription. 完成此操作后,请验证开发系统是否满足 GitHub 上用于 Java 的 Azure 存储 SDK 存储库中列出的最低要求和依赖项。Once you have done so, verify that your development system meets the minimum requirements and dependencies that are listed in the Azure Storage SDK for Java repository on GitHub. 如果系统满足这些要求,可以按照说明从该存储库将用于 Java 的 Azure 存储库下载并安装到你的系统中。If your system meets those requirements, you can follow the instructions to download and install the Azure Storage Libraries for Java on your system from that repository. 完成这些任务后,便可以创建一个 Java 应用程序,以使用本文中的示例。After you complete those tasks, you can create a Java application that uses the examples in this article.

配置应用程序以访问表存储Configure your application to access table storage

将以下 import 语句添加到要使用 Azure 存储器 API 或 Azure Cosmos DB 表 API 访问表的 Java 文件的顶部:Add the following import statements to the top of the Java file where you want to use Azure storage APIs or the Azure Cosmos DB Table API to access tables:

// Include the following imports to use table APIs
import com.microsoft.azure.storage.*;
import com.microsoft.azure.storage.table.*;
import com.microsoft.azure.storage.table.TableQuery.*;

添加 Azure 存储连接字符串Add an Azure storage connection string

Azure 存储客户端使用存储连接字符串来存储用于访问数据管理服务的终结点和凭据。An Azure storage client uses a storage connection string to store endpoints and credentials for accessing data management services. 在客户端应用程序中运行时,必须提供以下格式的存储连接字符串,并对 AccountName 和 AccountKey 值使用 Azure 门户中列出的存储帐户的名称和存储帐户的主访问密钥。When running in a client application, you must provide the storage connection string in the following format, using the name of your storage account and the Primary access key for the storage account listed in the Azure portal for the AccountName and AccountKey values.

此示例演示如何声明一个静态字段以保存连接字符串:This example shows how you can declare a static field to hold the connection string:

// Define the connection-string with your values.
public static final String storageConnectionString =
    "DefaultEndpointsProtocol=http;" +
    "AccountName=your_storage_account;" +
    "AccountKey=your_storage_account_key;" +
    "EndpointSuffix=core.chinacloudapi.cn";

添加 Azure Cosmos DB 表 API 连接字符串Add an Azure Cosmos DB Table API connection string

Azure Cosmos DB 帐户使用连接字符串存储表终结点和凭据。An Azure Cosmos DB account uses a connection string to store the table endpoint and your credentials. 在客户端应用程序中运行时,必须提供以下格式的 Azure Cosmos DB 连接字符串,并使用 Azure 门户中列出的帐户的 Azure Cosmos DB 帐户名称和主访问密钥作为 AccountNameAccountKey 值。When running in a client application, you must provide the Azure Cosmos DB connection string in the following format, using the name of your Azure Cosmos DB account and the primary access key for the account listed in the Azure portal for the AccountName and AccountKey values.

此示例演示如何声明一个静态字段以保存 Azure Cosmos DB 连接字符串:This example shows how you can declare a static field to hold the Azure Cosmos DB connection string:

public static final String storageConnectionString =
    "DefaultEndpointsProtocol=https;" + 
    "AccountName=your_cosmosdb_account;" + 
    "AccountKey=your_account_key;" + 
    "TableEndpoint=https://your_endpoint;" ;

对于在 Azure 的角色中运行的应用程序,可将此字符串存储在服务配置文件 ServiceConfiguration.cscfg 中,并可通过调用 RoleEnvironment.getConfigurationSettings 方法对其进行访问。In an application running within a role in Azure, you can store this string in the service configuration file, ServiceConfiguration.cscfg, and you can access it with a call to the RoleEnvironment.getConfigurationSettings method. 下面是从服务配置文件中名为 StorageConnectionStringSetting 元素中获取连接字符串的示例:Here's an example of getting the connection string from a Setting element named StorageConnectionString in the service configuration file:

// Retrieve storage account from connection-string.
String storageConnectionString =
    RoleEnvironment.getConfigurationSettings().get("StorageConnectionString");

还可以将连接字符串存储在项目的 config.properties 文件中:You can also store your connection string in your project's config.properties file:

StorageConnectionString = DefaultEndpointsProtocol=https;AccountName=your_account;AccountKey=your_account_key;TableEndpoint=https://your_table_endpoint/

以下示例假定已使用上述其中一个方法获取存储连接字符串。The following samples assume that you have used one of these methods to get the storage connection string.

创建表Create a table

利用 CloudTableClient 对象,可以获得表和实体的引用对象。A CloudTableClient object lets you get reference objects for tables and entities. 以下代码可创建 CloudTableClient 对象并使用它创建新的 CloudTable 对象,用于表示名为“people”的表。The following code creates a CloudTableClient object and uses it to create a new CloudTable object which represents a table named "people".

Note

还可以通过其他方式创建 CloudStorageAccount 对象;有关详细信息,请参阅 Azure 存储客户端 SDK 参考中的 CloudStorageAccount 。There are other ways to create CloudStorageAccount objects; for more information, see CloudStorageAccount in the Azure Storage Client SDK Reference).

try
{
    // Retrieve storage account from connection-string.
    CloudStorageAccount storageAccount =
        CloudStorageAccount.parse(storageConnectionString);

    // Create the table client.
    CloudTableClient tableClient = storageAccount.createCloudTableClient();

    // Create the table if it doesn't exist.
    String tableName = "people";
    CloudTable cloudTable = tableClient.getTableReference(tableName);
    cloudTable.createIfNotExists();
}
catch (Exception e)
{
    // Output the stack trace.
    e.printStackTrace();
}

列出表List the tables

若要获取表的列表,请调用 CloudTableClient.listTables() 方法来检索表名称的迭代列表。To get a list of tables, call the CloudTableClient.listTables() method to retrieve an iterable list of table names.

try
{
    // Retrieve storage account from connection-string.
    CloudStorageAccount storageAccount =
        CloudStorageAccount.parse(storageConnectionString);

    // Create the table client.
    CloudTableClient tableClient = storageAccount.createCloudTableClient();

    // Loop through the collection of table names.
    for (String table : tableClient.listTables())
    {
        // Output each table name.
        System.out.println(table);
    }
}
catch (Exception e)
{
    // Output the stack trace.
    e.printStackTrace();
}

将实体添加到表Add an entity to a table

实体映射到 Java 对象,该对象使用可实现 TableEntity 的自定义类。Entities map to Java objects using a custom class implementing TableEntity. 为方便起见,TableServiceEntity 类实现 TableEntity,并使用反射将属性映射到以属性本身命名的 getter 和 setter 方法。For convenience, the TableServiceEntity class implements TableEntity and uses reflection to map properties to getter and setter methods named for the properties. 要将实体添加到表,首先要创建用于定义实体的属性的类。To add an entity to a table, first create a class that defines the properties of your entity. 以下代码定义将客户的名字和姓氏分别用作行键和分区键的实体类。The following code defines an entity class that uses the customer's first name as the row key, and last name as the partition key. 实体的分区键和行键共同唯一地标识表中的实体。Together, an entity's partition and row key uniquely identify the entity in the table. 查询分区键相同的实体的速度可以快于查询分区键不同的实体的速度。Entities with the same partition key can be queried faster than those with different partition keys.

public class CustomerEntity extends TableServiceEntity {
    public CustomerEntity(String lastName, String firstName) {
        this.partitionKey = lastName;
        this.rowKey = firstName;
    }

    public CustomerEntity() { }

    String email;
    String phoneNumber;

    public String getEmail() {
        return this.email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPhoneNumber() {
        return this.phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }
}

涉及实体的表操作需要 TableOperation 对象。Table operations involving entities require a TableOperation object. 此对象用于定义要对实体执行的操作,该操作可使用 CloudTable 对象执行。This object defines the operation to be performed on an entity, which can be executed with a CloudTable object. 以下代码可创建包含要存储某些客户数据的 CustomerEntity 类的新实例。The following code creates a new instance of the CustomerEntity class with some customer data to be stored. 接下来,该代码调用 TableOperation.insertOrReplace 来创建 TableOperation 对象,以便将实体插入表中,并将新的 CustomerEntity 与之关联。The code next calls TableOperation.insertOrReplace to create a TableOperation object to insert an entity into a table, and associates the new CustomerEntity with it. 最后,该代码对 CloudTable 对象调用 execute 方法,并指定“people”表和新的 TableOperation,后者随后向存储服务发送将新客户实体插入“people”表或在实体已存在的情况下替换实体的请求。Finally, the code calls the execute method on the CloudTable object, specifying the "people" table and the new TableOperation, which then sends a request to the storage service to insert the new customer entity into the "people" table, or replace the entity if it already exists.

try
{
    // Retrieve storage account from connection-string.
    CloudStorageAccount storageAccount =
        CloudStorageAccount.parse(storageConnectionString);

    // Create the table client.
    CloudTableClient tableClient = storageAccount.createCloudTableClient();

    // Create a cloud table object for the table.
    CloudTable cloudTable = tableClient.getTableReference("people");

    // Create a new customer entity.
    CustomerEntity customer1 = new CustomerEntity("Harp", "Walter");
    customer1.setEmail("Walter@contoso.com");
    customer1.setPhoneNumber("425-555-0101");

    // Create an operation to add the new customer to the people table.
    TableOperation insertCustomer1 = TableOperation.insertOrReplace(customer1);

    // Submit the operation to the table service.
    cloudTable.execute(insertCustomer1);
}
catch (Exception e)
{
    // Output the stack trace.
    e.printStackTrace();
}

插入一批实体Insert a batch of entities

可以通过一次写入操作将一批实体插入到表服务。You can insert a batch of entities to the table service in one write operation. 以下代码创建一个 TableBatchOperation 对象,并向其中添加三个插入操作。The following code creates a TableBatchOperation object, then adds three insert operations to it. 每个插入操作的添加方法如下:创建一个新的实体对象,设置它的值,然后对 TableBatchOperation 对象调用 insert 方法以将实体与新插入操作相关联。Each insert operation is added by creating a new entity object, setting its values, and then calling the insert method on the TableBatchOperation object to associate the entity with a new insert operation. 然后,该代码对 CloudTable 对象调用 execute,并指定“people”表和 TableBatchOperation 对象,后者会在单个请求中向存储服务发送一批表操作。Then the code calls execute on the CloudTable object, specifying the "people" table and the TableBatchOperation object, which sends the batch of table operations to the storage service in a single request.

try
{
    // Retrieve storage account from connection-string.
    CloudStorageAccount storageAccount =
        CloudStorageAccount.parse(storageConnectionString);

    // Create the table client.
    CloudTableClient tableClient = storageAccount.createCloudTableClient();

    // Define a batch operation.
    TableBatchOperation batchOperation = new TableBatchOperation();

    // Create a cloud table object for the table.
    CloudTable cloudTable = tableClient.getTableReference("people");

    // Create a customer entity to add to the table.
    CustomerEntity customer = new CustomerEntity("Smith", "Jeff");
    customer.setEmail("Jeff@contoso.com");
    customer.setPhoneNumber("425-555-0104");
    batchOperation.insertOrReplace(customer);

    // Create another customer entity to add to the table.
    CustomerEntity customer2 = new CustomerEntity("Smith", "Ben");
    customer2.setEmail("Ben@contoso.com");
    customer2.setPhoneNumber("425-555-0102");
    batchOperation.insertOrReplace(customer2);

    // Create a third customer entity to add to the table.
    CustomerEntity customer3 = new CustomerEntity("Smith", "Denise");
    customer3.setEmail("Denise@contoso.com");
    customer3.setPhoneNumber("425-555-0103");
    batchOperation.insertOrReplace(customer3);

    // Execute the batch of operations on the "people" table.
    cloudTable.execute(batchOperation);
}
catch (Exception e)
{
    // Output the stack trace.
    e.printStackTrace();
}

批处理操作的注意事项如下:Some things to note on batch operations:

  • 在单次批处理操作中最多可以执行 100 个插入、删除、合并、替换、插入或合并以及插入或替换操作(可以是这些操作的任意组合)。You can perform up to 100 insert, delete, merge, replace, insert or merge, and insert or replace operations in any combination in a single batch.
  • 批处理操作也可以包含检索操作,但前提是检索操作是批处理中仅有的操作。A batch operation can have a retrieve operation, if it is the only operation in the batch.
  • 单次批处理操作中的所有实体都必须具有相同的分区键。All entities in a single batch operation must have the same partition key.
  • 批处理操作的数据负载限制为 4MB。A batch operation is limited to a 4MB data payload.

检索分区中的所有实体Retrieve all entities in a partition

若要对表查询分区中的实体,可以使用 TableQueryTo query a table for entities in a partition, you can use a TableQuery. 调用 TableQuery.from 可创建针对特定表的查询,该查询将返回指定的结果类型。Call TableQuery.from to create a query on a particular table that returns a specified result type. 以下代码指定了一个筛选器,用于筛选其中的分区键是“Smith”的实体。The following code specifies a filter for entities where 'Smith' is the partition key. TableQuery.generateFilterCondition 是一个用于创建查询筛选器的帮助器方法。TableQuery.generateFilterCondition is a helper method to create filters for queries. TableQuery.from 方法返回的引用调用 where 可对查询应用筛选器。Call where on the reference returned by the TableQuery.from method to apply the filter to the query. 通过对 CloudTable 对象调用 execute 来执行查询时,该查询将返回指定了 CustomerEntity 结果类型的 IteratorWhen the query is executed with a call to execute on the CloudTable object, it returns an Iterator with the CustomerEntity result type specified. 然后,可以利用在 for each 循环中返回的 Iterator 来使用结果。You can then use the Iterator returned in a for each loop to consume the results. 此代码会将查询结果中每个实体的字段打印到控制台。This code prints the fields of each entity in the query results to the console.

try
{
    // Define constants for filters.
    final String PARTITION_KEY = "PartitionKey";
    final String ROW_KEY = "RowKey";
    final String TIMESTAMP = "Timestamp";

    // Retrieve storage account from connection-string.
    CloudStorageAccount storageAccount =
        CloudStorageAccount.parse(storageConnectionString);

    // Create the table client.
    CloudTableClient tableClient = storageAccount.createCloudTableClient();

    // Create a cloud table object for the table.
    CloudTable cloudTable = tableClient.getTableReference("people");

    // Create a filter condition where the partition key is "Smith".
    String partitionFilter = TableQuery.generateFilterCondition(
        PARTITION_KEY,
        QueryComparisons.EQUAL,
        "Smith");

    // Specify a partition query, using "Smith" as the partition key filter.
    TableQuery<CustomerEntity> partitionQuery =
        TableQuery.from(CustomerEntity.class)
        .where(partitionFilter);

    // Loop through the results, displaying information about the entity.
    for (CustomerEntity entity : cloudTable.execute(partitionQuery)) {
        System.out.println(entity.getPartitionKey() +
            " " + entity.getRowKey() +
            "\t" + entity.getEmail() +
            "\t" + entity.getPhoneNumber());
    }
}
catch (Exception e)
{
    // Output the stack trace.
    e.printStackTrace();
}

检索分区中的一部分实体Retrieve a range of entities in a partition

如果不想查询分区中的所有实体,则可以在筛选器中使用比较运算符来指定一个范围。If you don't want to query all the entities in a partition, you can specify a range by using comparison operators in a filter. 以下代码组合了两个筛选器来获取分区“Smith”中的、行键(名字)以字母“E”及字母“E”前面的字母开头的所有实体。The following code combines two filters to get all entities in partition "Smith" where the row key (first name) starts with a letter up to 'E' in the alphabet. 然后,该代码打印了查询结果。Then it prints the query results. 如果使用添加到本指南的批量插入部分的表的实体,则此次只返回两个实体(Ben 和 Denise Smith),而不会包括 Jeff Smith。If you use the entities added to the table in the batch insert section of this guide, only two entities are returned this time (Ben and Denise Smith); Jeff Smith is not included.

try
{
    // Define constants for filters.
    final String PARTITION_KEY = "PartitionKey";
    final String ROW_KEY = "RowKey";
    final String TIMESTAMP = "Timestamp";

    // Retrieve storage account from connection-string.
    CloudStorageAccount storageAccount =
        CloudStorageAccount.parse(storageConnectionString);

    // Create the table client.
    CloudTableClient tableClient = storageAccount.createCloudTableClient();

    // Create a cloud table object for the table.
    CloudTable cloudTable = tableClient.getTableReference("people");

    // Create a filter condition where the partition key is "Smith".
    String partitionFilter = TableQuery.generateFilterCondition(
        PARTITION_KEY,
        QueryComparisons.EQUAL,
        "Smith");

    // Create a filter condition where the row key is less than the letter "E".
    String rowFilter = TableQuery.generateFilterCondition(
        ROW_KEY,
        QueryComparisons.LESS_THAN,
        "E");

    // Combine the two conditions into a filter expression.
    String combinedFilter = TableQuery.combineFilters(partitionFilter,
        Operators.AND, rowFilter);

    // Specify a range query, using "Smith" as the partition key,
    // with the row key being up to the letter "E".
    TableQuery<CustomerEntity> rangeQuery =
        TableQuery.from(CustomerEntity.class)
        .where(combinedFilter);

    // Loop through the results, displaying information about the entity
    for (CustomerEntity entity : cloudTable.execute(rangeQuery)) {
        System.out.println(entity.getPartitionKey() +
            " " + entity.getRowKey() +
            "\t" + entity.getEmail() +
            "\t" + entity.getPhoneNumber());
    }
}
catch (Exception e)
{
    // Output the stack trace.
    e.printStackTrace();
}

检索单个实体Retrieve a single entity

可以编写查询以检索单个特定实体。You can write a query to retrieve a single, specific entity. 以下代码使用分区键和行键参数调用 TableOperation.retrieve 来指定客户“Jeff Smith”,而不是创建 TableQuery 并使用筛选器来执行同一操作。The following code calls TableOperation.retrieve with partition key and row key parameters to specify the customer "Jeff Smith", instead of creating a TableQuery and using filters to do the same thing. 执行的检索操作将只返回一个实体,而不会返回一个集合。When executed, the retrieve operation returns just one entity, rather than a collection. getResultAsType 方法会将结果转换为分配目标的类型 - CustomerEntity 对象。The getResultAsType method casts the result to the type of the assignment target, a CustomerEntity object. 如果此类型与为查询指定的类型不兼容,则会引发异常。If this type is not compatible with the type specified for the query, an exception is thrown. 如果没有实体具有完全匹配的分区键和行键,则会返回 null 值。A null value is returned if no entity has an exact partition and row key match. 在查询中指定分区键和行键是从表服务中检索单个实体的最快方法。Specifying both partition and row keys in a query is the fastest way to retrieve a single entity from the Table service.

try
{
    // Retrieve storage account from connection-string.
    CloudStorageAccount storageAccount =
        CloudStorageAccount.parse(storageConnectionString);

    // Create the table client.
    CloudTableClient tableClient = storageAccount.createCloudTableClient();

    // Create a cloud table object for the table.
    CloudTable cloudTable = tableClient.getTableReference("people");

    // Retrieve the entity with partition key of "Smith" and row key of "Jeff"
    TableOperation retrieveSmithJeff =
        TableOperation.retrieve("Smith", "Jeff", CustomerEntity.class);

    // Submit the operation to the table service and get the specific entity.
    CustomerEntity specificEntity =
        cloudTable.execute(retrieveSmithJeff).getResultAsType();

    // Output the entity.
    if (specificEntity != null)
    {
        System.out.println(specificEntity.getPartitionKey() +
            " " + specificEntity.getRowKey() +
            "\t" + specificEntity.getEmail() +
            "\t" + specificEntity.getPhoneNumber());
    }
}
catch (Exception e)
{
    // Output the stack trace.
    e.printStackTrace();
}

修改实体Modify an entity

要修改实体,请从表服务中检索它,对实体对象进行更改,然后通过替换或合并操作将更改保存回表服务。To modify an entity, retrieve it from the table service, make changes to the entity object, and save the changes back to the table service with a replace or merge operation. 以下代码将更改现有客户的电话号码。The following code changes an existing customer's phone number. 此代码将调用 TableOperation.replace,而不是像执行插入时那样调用 TableOperation.insertInstead of calling TableOperation.insert as we did to insert, this code calls TableOperation.replace. CloudTable.execute 方法将调用表服务,并替换该实体,除非在此应用程序检索到该实体之后另一个应用程序对它进行了更改。The CloudTable.execute method calls the table service, and the entity is replaced, unless another application changed it in the time since this application retrieved it. 如果出现这种情况,则会引发异常,必须再次检索、修改并保存该实体。When that happens, an exception is thrown, and the entity must be retrieved, modified, and saved again. 此乐观并发重试模式在分布式存储系统中很常见。This optimistic concurrency retry pattern is common in a distributed storage system.

try
{
    // Retrieve storage account from connection-string.
    CloudStorageAccount storageAccount =
        CloudStorageAccount.parse(storageConnectionString);

    // Create the table client.
    CloudTableClient tableClient = storageAccount.createCloudTableClient();

    // Create a cloud table object for the table.
    CloudTable cloudTable = tableClient.getTableReference("people");

    // Retrieve the entity with partition key of "Smith" and row key of "Jeff".
    TableOperation retrieveSmithJeff =
        TableOperation.retrieve("Smith", "Jeff", CustomerEntity.class);

    // Submit the operation to the table service and get the specific entity.
    CustomerEntity specificEntity =
        cloudTable.execute(retrieveSmithJeff).getResultAsType();

    // Specify a new phone number.
    specificEntity.setPhoneNumber("425-555-0105");

    // Create an operation to replace the entity.
    TableOperation replaceEntity = TableOperation.replace(specificEntity);

    // Submit the operation to the table service.
    cloudTable.execute(replaceEntity);
}
catch (Exception e)
{
    // Output the stack trace.
    e.printStackTrace();
}

查询一部分实体属性Query a subset of entity properties

对表的查询可以只检索实体中的少数几个属性。A query to a table can retrieve just a few properties from an entity. 此方法称为“投影”,可减少带宽并提高查询性能,尤其适用于大型实体。This technique, called projection, reduces bandwidth and can improve query performance, especially for large entities. 以下代码中的查询使用 select 方法,仅返回表中实体的电子邮件地址。The query in the following code uses the select method to return only the email addresses of entities in the table. 返回结果在 EntityResolver(用于对从服务器返回的实体执行类型转换)的帮助下投影到 String 集合中。The results are projected into a collection of String with the help of an EntityResolver, which does the type conversion on the entities returned from the server. 可以在以下文章中了解有关投影的详细信息:[Azure 表:介绍 Upsert 和查询投影][Azure 表:介绍 Upsert 和查询投影]。You can learn more about projection in [Azure Tables: Introducing Upsert and Query Projection][Azure Tables: Introducing Upsert and Query Projection]. 请注意,本地存储模拟器不支持投影,因此,此代码仅在使用表服务中的帐户时才能运行。Note that projection is not supported on the local storage emulator, so this code runs only when using an account on the table service.

try
{
    // Retrieve storage account from connection-string.
    CloudStorageAccount storageAccount =
        CloudStorageAccount.parse(storageConnectionString);

    // Create the table client.
    CloudTableClient tableClient = storageAccount.createCloudTableClient();

    // Create a cloud table object for the table.
    CloudTable cloudTable = tableClient.getTableReference("people");

    // Define a projection query that retrieves only the Email property
    TableQuery<CustomerEntity> projectionQuery =
        TableQuery.from(CustomerEntity.class)
        .select(new String[] {"Email"});

    // Define an Entity resolver to project the entity to the Email value.
    EntityResolver<String> emailResolver = new EntityResolver<String>() {
        @Override
        public String resolve(String PartitionKey, String RowKey, Date timeStamp, HashMap<String, EntityProperty> properties, String etag) {
            return properties.get("Email").getValueAsString();
        }
    };

    // Loop through the results, displaying the Email values.
    for (String projectedString :
        cloudTable.execute(projectionQuery, emailResolver)) {
            System.out.println(projectedString);
    }
}
catch (Exception e)
{
    // Output the stack trace.
    e.printStackTrace();
}

插入或替换实体Insert or Replace an entity

经常需要将某个实体添加到表中,但又不知道该实体是否已存在于表中。Often you want to add an entity to a table without knowing if it already exists in the table. 利用插入或替换操作,可以提出一个以下形式的请求:如果实体不存在,则插入一个实体;如果实体存在,则将其替换为现有实体。An insert-or-replace operation allows you to make a single request which will insert the entity if it does not exist or replace the existing one if it does. 以下代码基于前面的示例针对“Walter Harp”插入或替换实体。Building on prior examples, the following code inserts or replaces the entity for "Walter Harp". 创建新实体后,此代码调用 TableOperation.insertOrReplace 方法。After creating a new entity, this code calls the TableOperation.insertOrReplace method. 此代码随后使用表和插入或将表操作替换为参数对 CloudTable 对象调用 executeThis code then calls execute on the CloudTable object with the table and the insert or replace table operation as the parameters. 若要只更新实体的一部分,可以改用 TableOperation.insertOrMerge 方法。To update only part of an entity, the TableOperation.insertOrMerge method can be used instead. 请注意,本地存储模拟器不支持插入或替换,因此,此代码仅在使用表服务中的帐户时才能运行。Note that insert-or-replace is not supported on the local storage emulator, so this code runs only when using an account on the table service. 可以在以下文章中了解有关插入或替换和插入或合并的更多信息:[Azure 表:介绍 Upsert 和查询投影][Azure 表:介绍 Upsert 和查询投影]。You can learn more about insert-or-replace and insert-or-merge in this [Azure Tables: Introducing Upsert and Query Projection][Azure Tables: Introducing Upsert and Query Projection].

try
{
    // Retrieve storage account from connection-string.
    CloudStorageAccount storageAccount =
        CloudStorageAccount.parse(storageConnectionString);

    // Create the table client.
    CloudTableClient tableClient = storageAccount.createCloudTableClient();

    // Create a cloud table object for the table.
    CloudTable cloudTable = tableClient.getTableReference("people");

    // Create a new customer entity.
    CustomerEntity customer5 = new CustomerEntity("Harp", "Walter");
    customer5.setEmail("Walter@contoso.com");
    customer5.setPhoneNumber("425-555-0106");

    // Create an operation to add the new customer to the people table.
    TableOperation insertCustomer5 = TableOperation.insertOrReplace(customer5);

    // Submit the operation to the table service.
    cloudTable.execute(insertCustomer5);
}
catch (Exception e)
{
    // Output the stack trace.
    e.printStackTrace();
}

删除实体Delete an entity

可以在检索到实体后轻松将其删除。You can easily delete an entity after you have retrieved it. 检索到实体后,对要删除的实体调用 TableOperation.deleteAfter the entity is retrieved, call TableOperation.delete with the entity to delete. 然后对 CloudTable 对象调用 executeThen call execute on the CloudTable object. 以下代码检索并删除一个客户实体。The following code retrieves and deletes a customer entity.

try
{
    // Retrieve storage account from connection-string.
    CloudStorageAccount storageAccount =
        CloudStorageAccount.parse(storageConnectionString);

    // Create the table client.
    CloudTableClient tableClient = storageAccount.createCloudTableClient();

    // Create a cloud table object for the table.
    CloudTable cloudTable = tableClient.getTableReference("people");

    // Create an operation to retrieve the entity with partition key of "Smith" and row key of "Jeff".
    TableOperation retrieveSmithJeff = TableOperation.retrieve("Smith", "Jeff", CustomerEntity.class);

    // Retrieve the entity with partition key of "Smith" and row key of "Jeff".
    CustomerEntity entitySmithJeff =
        cloudTable.execute(retrieveSmithJeff).getResultAsType();

    // Create an operation to delete the entity.
    TableOperation deleteSmithJeff = TableOperation.delete(entitySmithJeff);

    // Submit the delete operation to the table service.
    cloudTable.execute(deleteSmithJeff);
}
catch (Exception e)
{
    // Output the stack trace.
    e.printStackTrace();
}

删除表Delete a table

最后,以下代码将从存储帐户中删除一个表。Finally, the following code deletes a table from a storage account. 删除表后约 40 秒,无法重新创建该表。For about 40 seconds after you delete a table, you cannot recreate it.

try
{
    // Retrieve storage account from connection-string.
    CloudStorageAccount storageAccount =
        CloudStorageAccount.parse(storageConnectionString);

    // Create the table client.
    CloudTableClient tableClient = storageAccount.createCloudTableClient();

    // Delete the table and all its data if it exists.
    CloudTable cloudTable = tableClient.getTableReference("people");
    cloudTable.deleteIfExists();
}
catch (Exception e)
{
    // Output the stack trace.
    e.printStackTrace();
}

Tip

查看 Azure 存储代码示例存储库Check out the Azure Storage code samples repository

如需易用且能够下载和运行的端到端 Azure 存储代码示例,请查看我们的 Azure 存储示例列表。For easy-to-use end-to-end Azure Storage code samples that you can download and run, please check out our list of Azure Storage Samples.

后续步骤Next steps

有关详细信息,请访问面向 Java 开发人员的 AzureFor more information, visit Azure for Java developers.