Add repo-wide auditing and targeted repair scripts for skill metadata. Fix truncated descriptions automatically, keep heading normalization conservative, and remove synthetic boilerplate sections that degrade editorial quality while regenerating repo indexes and catalogs. Fixes #365
340 lines
8.8 KiB
Markdown
340 lines
8.8 KiB
Markdown
---
|
|
name: azure-data-tables-java
|
|
description: "Build table storage applications using the Azure Tables SDK for Java. Works with both Azure Table Storage and Cosmos DB Table API."
|
|
risk: unknown
|
|
source: community
|
|
date_added: "2026-02-27"
|
|
---
|
|
|
|
# Azure Tables SDK for Java
|
|
|
|
Build table storage applications using the Azure Tables SDK for Java. Works with both Azure Table Storage and Cosmos DB Table API.
|
|
|
|
## Installation
|
|
|
|
```xml
|
|
<dependency>
|
|
<groupId>com.azure</groupId>
|
|
<artifactId>azure-data-tables</artifactId>
|
|
<version>12.6.0-beta.1</version>
|
|
</dependency>
|
|
```
|
|
|
|
## Client Creation
|
|
|
|
### With Connection String
|
|
|
|
```java
|
|
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();
|
|
```
|
|
|
|
### With Shared Key
|
|
|
|
```java
|
|
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();
|
|
```
|
|
|
|
### With SAS Token
|
|
|
|
```java
|
|
TableServiceClient serviceClient = new TableServiceClientBuilder()
|
|
.endpoint("<your-table-account-url>")
|
|
.sasToken("<sas-token>")
|
|
.buildClient();
|
|
```
|
|
|
|
### With DefaultAzureCredential (Storage only)
|
|
|
|
```java
|
|
import com.azure.identity.DefaultAzureCredentialBuilder;
|
|
|
|
TableServiceClient serviceClient = new TableServiceClientBuilder()
|
|
.endpoint("<your-table-account-url>")
|
|
.credential(new DefaultAzureCredentialBuilder().build())
|
|
.buildClient();
|
|
```
|
|
|
|
## Key Concepts
|
|
|
|
- **TableServiceClient**: Manage tables (create, list, delete)
|
|
- **TableClient**: Manage entities within a table (CRUD)
|
|
- **Partition Key**: Groups entities for efficient queries
|
|
- **Row Key**: Unique identifier within a partition
|
|
- **Entity**: A row with up to 252 properties (1MB Storage, 2MB Cosmos)
|
|
|
|
## Core Patterns
|
|
|
|
### Create Table
|
|
|
|
```java
|
|
// Create table (throws if exists)
|
|
TableClient tableClient = serviceClient.createTable("mytable");
|
|
|
|
// Create if not exists (no exception)
|
|
TableClient tableClient = serviceClient.createTableIfNotExists("mytable");
|
|
```
|
|
|
|
### Get Table Client
|
|
|
|
```java
|
|
// From service client
|
|
TableClient tableClient = serviceClient.getTableClient("mytable");
|
|
|
|
// Direct construction
|
|
TableClient tableClient = new TableClientBuilder()
|
|
.connectionString("<connection-string>")
|
|
.tableName("mytable")
|
|
.buildClient();
|
|
```
|
|
|
|
### Create Entity
|
|
|
|
```java
|
|
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);
|
|
```
|
|
|
|
### Get Entity
|
|
|
|
```java
|
|
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);
|
|
```
|
|
|
|
### Update Entity
|
|
|
|
```java
|
|
import com.azure.data.tables.models.TableEntityUpdateMode;
|
|
|
|
// Merge (update only specified properties)
|
|
TableEntity updateEntity = new TableEntity("partitionKey", "rowKey")
|
|
.addProperty("Price", 24.99);
|
|
tableClient.updateEntity(updateEntity, TableEntityUpdateMode.MERGE);
|
|
|
|
// Replace (replace entire entity)
|
|
TableEntity replaceEntity = new TableEntity("partitionKey", "rowKey")
|
|
.addProperty("Name", "Product A Updated")
|
|
.addProperty("Price", 24.99)
|
|
.addProperty("Quantity", 150);
|
|
tableClient.updateEntity(replaceEntity, TableEntityUpdateMode.REPLACE);
|
|
```
|
|
|
|
### Upsert Entity
|
|
|
|
```java
|
|
// Insert or update (merge mode)
|
|
tableClient.upsertEntity(entity, TableEntityUpdateMode.MERGE);
|
|
|
|
// Insert or replace
|
|
tableClient.upsertEntity(entity, TableEntityUpdateMode.REPLACE);
|
|
```
|
|
|
|
### Delete Entity
|
|
|
|
```java
|
|
tableClient.deleteEntity("partitionKey", "rowKey");
|
|
```
|
|
|
|
### List Entities
|
|
|
|
```java
|
|
import com.azure.data.tables.models.ListEntitiesOptions;
|
|
|
|
// List all entities
|
|
for (TableEntity entity : tableClient.listEntities()) {
|
|
System.out.printf("%s - %s%n",
|
|
entity.getPartitionKey(),
|
|
entity.getRowKey());
|
|
}
|
|
|
|
// With filtering and selection
|
|
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"));
|
|
}
|
|
```
|
|
|
|
### Query with OData Filter
|
|
|
|
```java
|
|
// Filter by partition key
|
|
ListEntitiesOptions options = new ListEntitiesOptions()
|
|
.setFilter("PartitionKey eq 'electronics'");
|
|
|
|
// Filter with multiple conditions
|
|
options.setFilter("PartitionKey eq 'electronics' and Price gt 100");
|
|
|
|
// Filter with comparison operators
|
|
options.setFilter("Quantity ge 10 and Quantity le 100");
|
|
|
|
// Top N results
|
|
options.setTop(10);
|
|
|
|
for (TableEntity entity : tableClient.listEntities(options, null, null)) {
|
|
System.out.println(entity.getRowKey());
|
|
}
|
|
```
|
|
|
|
### Batch Operations (Transactions)
|
|
|
|
```java
|
|
import com.azure.data.tables.models.TableTransactionAction;
|
|
import com.azure.data.tables.models.TableTransactionActionType;
|
|
import java.util.Arrays;
|
|
|
|
// All entities must have same partition key
|
|
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);
|
|
```
|
|
|
|
### List Tables
|
|
|
|
```java
|
|
import com.azure.data.tables.models.TableItem;
|
|
import com.azure.data.tables.models.ListTablesOptions;
|
|
|
|
// List all tables
|
|
for (TableItem table : serviceClient.listTables()) {
|
|
System.out.println(table.getName());
|
|
}
|
|
|
|
// Filter tables
|
|
ListTablesOptions options = new ListTablesOptions()
|
|
.setFilter("TableName eq 'mytable'");
|
|
|
|
for (TableItem table : serviceClient.listTables(options, null, null)) {
|
|
System.out.println(table.getName());
|
|
}
|
|
```
|
|
|
|
### Delete Table
|
|
|
|
```java
|
|
serviceClient.deleteTable("mytable");
|
|
```
|
|
|
|
## Typed Entities
|
|
|
|
```java
|
|
public class Product implements TableEntity {
|
|
private String partitionKey;
|
|
private String rowKey;
|
|
private OffsetDateTime timestamp;
|
|
private String eTag;
|
|
private String name;
|
|
private double price;
|
|
|
|
// Getters and setters for all fields
|
|
@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; }
|
|
// ... other getters/setters
|
|
|
|
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; }
|
|
}
|
|
|
|
// Usage
|
|
Product product = new Product();
|
|
product.setPartitionKey("electronics");
|
|
product.setRowKey("laptop-001");
|
|
product.setName("Laptop");
|
|
product.setPrice(999.99);
|
|
|
|
tableClient.createEntity(product);
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
```java
|
|
import com.azure.data.tables.models.TableServiceException;
|
|
|
|
try {
|
|
tableClient.createEntity(entity);
|
|
} catch (TableServiceException e) {
|
|
System.out.println("Status: " + e.getResponse().getStatusCode());
|
|
System.out.println("Error: " + e.getMessage());
|
|
// 409 = Conflict (entity exists)
|
|
// 404 = Not Found
|
|
}
|
|
```
|
|
|
|
## Environment Variables
|
|
|
|
```bash
|
|
# Storage Account
|
|
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
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
1. **Partition Key Design**: Choose keys that distribute load evenly
|
|
2. **Batch Operations**: Use transactions for atomic multi-entity updates
|
|
3. **Query Optimization**: Always filter by PartitionKey when possible
|
|
4. **Select Projection**: Only select needed properties for performance
|
|
5. **Entity Size**: Keep entities under 1MB (Storage) or 2MB (Cosmos)
|
|
|
|
## Trigger Phrases
|
|
|
|
- "Azure Tables Java"
|
|
- "table storage SDK"
|
|
- "Cosmos DB Table API"
|
|
- "NoSQL key-value storage"
|
|
- "partition key row key"
|
|
- "table entity CRUD"
|
|
|
|
## When to Use
|
|
This skill is applicable to execute the workflow or actions described in the overview.
|