Azure 数据表 Java SDK
Azure Tables Java SDK
使用 Azure Tables Java SDK 构建表存储应用程序。同时支持 Azure Table Storage 和 Cosmos DB Table API。
安装
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-data-tables</artifactId>
<version>12.6.0-beta.1</version>
</dependency>客户端创建
使用连接字符串
import com.azure.data.tables.TableServiceClient;
import com.azure.data.tables.TableServiceClientBuilder;
import com.azure.data.tables.TableClient;
TableServiceClient serviceClient = new TableServiceClientBuilder()
.connectionString("<your-connection-string>")
.buildClient();
使用共享密钥
import com.azure.core.credential.AzureNamedKeyCredential;
AzureNamedKeyCredential credential = new AzureNamedKeyCredential(
"<account-name>",
"<account-key>");
TableServiceClient serviceClient = new TableServiceClientBuilder()
.endpoint("<your-table-account-url>")
.credential(credential)
.buildClient();
使用 SAS 令牌
TableServiceClient serviceClient = new TableServiceClientBuilder()
.endpoint("<your-table-account-url>")
.sasToken("<sas-token>")
.buildClient();使用 DefaultAzureCredential(仅限存储)
import com.azure.identity.DefaultAzureCredentialBuilder;
TableServiceClient serviceClient = new TableServiceClientBuilder()
.endpoint("<your-table-account-url>")
.credential(new DefaultAzureCredentialBuilder().build())
.buildClient();
核心概念
- TableServiceClient: 管理表(创建、列出、删除)
- TableClient: 管理表内的实体(CRUD 操作)
- Partition Key (分区键): 对实体进行分组以实现高效查询
- Row Key (行键): 分区内的唯一标识符
- Entity (实体): 一行数据,最多包含 252 个属性(存储账户上限 1MB,Cosmos DB 上限 2MB)
核心模式
创建表
// 创建表(如果已存在则抛出异常)
TableClient tableClient = serviceClient.createTable("mytable");
// 如果不存在则创建(不抛出异常)
TableClient tableClient = serviceClient.createTableIfNotExists("mytable");
获取表客户端
// 通过服务客户端获取
TableClient tableClient = serviceClient.getTableClient("mytable");
// 直接构建
TableClient tableClient = new TableClientBuilder()
.connectionString("<connection-string>")
.tableName("mytable")
.buildClient();
创建实体
import com.azure.data.tables.models.TableEntity;
TableEntity entity = new TableEntity("partitionKey", "rowKey")
.addProperty("Name", "Product A")
.addProperty("Price", 29.99)
.addProperty("Quantity", 100)
.addProperty("IsAvailable", true);
tableClient.createEntity(entity);
获取实体
TableEntity entity = tableClient.getEntity("partitionKey", "rowKey");
String name = (String) entity.getProperty("Name");
Double price = (Double) entity.getProperty("Price");
System.out.printf("Product: %s, Price: %.2f%n", name, price);
更新实体
import com.azure.data.tables.models.TableEntityUpdateMode;
// 合并 (仅更新指定的属性)
TableEntity updateEntity = new TableEntity("partitionKey", "rowKey")
.addProperty("Price", 24.99);
tableClient.updateEntity
(updateEntity, TableEntityUpdateMode.MERGE);
// 替换(替换整个实体)
TableEntity replaceEntity = new TableEntity("partitionKey", "rowKey")
.addProperty("Name", "Product A Updated")
.addProperty("Price", 24.99)
.addProperty("Quantity", 150);
tableClient.updateEntity(replaceEntity, TableEntityUpdateMode.REPLACE);
### Upsert 实体// 插入或更新(合并模式)
tableClient.upsertEntity(entity, TableEntityUpdateMode.MERGE);
// 插入或替换
tableClient.upsertEntity(entity, TableEntityUpdateMode.REPLACE);
### 删除实体tableClient.deleteEntity("partitionKey", "rowKey");
### 列出实体import com.azure.data.tables.models.ListEntitiesOptions;
// 列出所有实体
for (TableEntity entity : tableClient.listEntities()) {
System.out.printf("%s - %s%n",
entity.getPartitionKey(),
entity.getRowKey());
}
// 使用过滤和选择
ListEntitiesOptions options = new ListEntitiesOptions()
.setFilter("PartitionKey eq 'sales'")
.setSelect("Name", "Price");
for (TableEntity entity : tableClient.listEntities(options, null, null)) {
System.out.printf("%s: %.2f%n",
entity.getProperty("Name"),
entity.getProperty("Price"));
}
### 使用 OData 过滤器查询// 按分区键过滤
ListEntitiesOptions options = new ListEntitiesOptions()
.setFilter("PartitionKey eq 'electronics'");
// 使用多个条件过滤
options.setFilter("PartitionKey eq 'electronics' and Price gt 100");
// 使用比较运算符过滤
options.setFilter("Quantity ge 10 and Quantity le 100");
// 限制返回前 N 条结果
options.setTop(10);
for (TableEntity entity : tableClient.listEntities(options, null, null)) {
System.out.println(entity.getRowKey());
}
### 批量操作(事务)import com.azure.data.tables.models.TableTransactionAction;
import com.azure.data.tables.models.TableTransactionActionType;
import java.util.Arrays;
// 所有实体必须具有相同的分区键
List<TableTransactionAction> actions = Arrays.asList(
new TableTransactionAction(
TableTransactionActionType.CREATE,
new TableEntity("batch", "row1").addProperty("Name", "Item 1")),
new TableTransactionAction(
TableTransactionActionType.CREATE,
new TableEntity("batch", "row2").addProperty("Name", "Item 2")),
new TableTransactionAction(
TableTransactionActionType.UPSERT_MERGE,
new TableEntity("batch", "row3").addProperty("Name", "Item 3"))
);
tableClient.submitTransaction(actions);
### 列出表import com.azure.data.tables.models.TableItem;
import com.azure.data.tables.models.ListTablesOptions;
// 列出所有表
for (TableItem table : serviceClient.listTables()) {
System.out.println(table.getName());
}
// 过滤表
ListTablesOptions options = new ListTablesOptions()
.setFilter("TableName eq 'mytable'");
for (TableItem table : serviceClient.listTables(options, null, null)) {
System.out.println(table.getName());
}
### 删除表serviceClient.deleteTable("mytable");
## 强类型实体public class Product implements TableEntity {
private String partitionKey;
private String rowKey;
private OffsetDateTime timestamp;
private String eTag;
private String name;
private double price;
// 所有字段的 Getter 和 Setter
@Override
public String getPartitionKey() { return partitionKey; }
@Override
public void setPartitionKey(String partitionKey) { this.partitionKey = partitionKey; }
@Override
public String getRowKey() { return rowKey; }
@Override
public void setRowKey(String rowKey) { this.rowKey = rowKey; }
// ... 其他 getter/setter
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public double getPrice() { return price; }
public void setPrice(double price) { this.price = price; }
}
// 使用示例
Product product = new Product();
product.setPartitionKey("electronics");
product.setRowKey("laptop-001");
product.setName("Laptop");
product.setPrice(999.99);
tableClient.createEntity(product);
## 错误处理import com.azure.data.tables.models.TableServiceException;
try {
tableClient.createEntity(entity);
} catch (TableServiceException e) {
System.out.println("状态码: " + e.getResponse().getStatusCode());
System.out.println("错误: " + e.getMessage());
// 409 = 冲突 (实体已存在)
// 404 = 未找到
}
## 环境变量存储账户
AZURE_TABLES_CONNECTION_STRING=DefaultEndpointsProtocol=https;AccountName=...
AZURE_TABLES_ENDPOINT=https://<account>.table.core.windows.net
Cosmos DB Table API
COSMOS_TABLE_ENDPOINT=https://<account>.table.cosmosdb.azure.com ```最佳实践
1. 分区键 (Partition Key) 设计:选择能均匀分布负载的键。
2. 批量操作:使用事务来实现多实体的原子性更新。
3. 查询优化:尽可能始终通过 PartitionKey 进行过滤。
4. 选择投影 (Select Projection):仅选择必要的属性以提升性能。
5. 实体大小:将实体控制在 1MB (存储账户) 或 2MB (Cosmos DB) 以内。
触发词
- "Azure Tables Java"
- "table storage SDK"
- "Cosmos DB Table API"
- "NoSQL 键值存储"
- "partition key row key"
- "table entity CRUD"
适用场景
此技能适用于执行概述中描述的工作流或操作。局限性
- 仅在任务明确符合上述范围时使用此技能。
- 不要将输出视为特定环境验证、测试或专家评审的替代方案。
- 如果缺少必要的输入、权限、安全边界或成功标准,请停止并请求澄清。