Как использовать клиентскую библиотеку таблиц Azure для Java
Область применения: Таблица
Совет
Содержимое этой статьи относится к хранилищу таблиц Azure и Azure Cosmos DB для таблицы. API для таблицы — это предложение уровня "Премиум" для хранилища таблиц, которое предлагает оптимизированные для пропускной способности таблицы, глобальное распределение и автоматические вторичные индексы.
В этой статье показано, как создавать таблицы, сохранять данные и выполнять операции CRUD с такими данными. Примеры написаны на Java, и в них используется клиентская библиотека таблиц Azure для Java. Рассматриваются сценарии создания, перечисления и удаления таблиц, а также вставки, запроса, изменения и удаления сущностей в таблице. Дополнительные сведения о таблицах см. в разделе Дальнейшие действия.
Внимание
Последняя версия клиентской библиотеки таблиц Azure, поддерживающей хранилище таблиц и таблицу Azure Cosmos DB, — 12+.
Создание учетной записи службы Azure
Вы можете работать с таблицами, используя хранилище таблиц Azure или Azure Cosmos DB. Дополнительные сведения о различиях между предложениями таблиц в этих двух службах см. в обзоре API для таблиц. Для службы, которую вы планируете использовать, потребуется создать учетную запись. В следующих разделах показано, как создать и хранилище таблиц Azure, и учетную запись Azure Cosmos DB, однако можно использовать что-то одно.
Создание учетной записи службы хранилища Azure
Самый простой способ создать учетную запись хранения Azure — воспользоваться порталом Azure. Чтобы узнать больше, см. раздел Создание учетной записи хранилища.
Учетную запись хранения Azure можно создать также с помощью Azure PowerShell или Azure CLI.
Если вы не хотите сейчас создавать учетную запись хранения, код можно запустить и протестировать в локальной среде с помощью эмулятора хранения Azure. Дополнительные сведения см. в статье Использование Эмулятора службы хранилища Azure для разработки и тестирования.
Создание учетной записи Azure Cosmos DB
Инструкции по созданию учетной записи Azure Cosmos DB для таблицы см. в статье "Создание учетной записи базы данных".
Создание приложения Java
Для использования примеров из этой статьи сделайте следующее:
- Установите комплект SDK для Java (JDK).
- Создайте учетную запись хранения Azure или учетную запись Azure Cosmos DB в подписке Azure.
- Убедитесь, что ваша система разработки отвечает минимальным требованиям и зависимостям, указанным в репозитории клиентской библиотеки таблиц Azure для Java на сайте GitHub.
- Выполните инструкции по скачиванию и установке библиотек службы хранилища Azure для Java из указанного репозитория.
- Создайте приложение Java, в котором будут использоваться примеры, приведенные в этой статье.
Настройка приложения для доступа к Хранилищу таблиц
Добавьте приведенную ниже запись в раздел dependencies
файла pom.xml.
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-data-tables</artifactId>
<version>12.1.1</version>
</dependency>
Затем, если для доступа к таблицам нужно использовать API-интерфейсы таблиц Azure, добавьте следующие инструкции import
в верхнюю часть файла Java.
// Include the following imports to use table APIs
import com.azure.data.tables.TableClient;
import com.azure.data.tables.TableClientBuilder;
import com.azure.data.tables.TableServiceClient;
import com.azure.data.tables.TableServiceClientBuilder;
import com.azure.data.tables.models.ListEntitiesOptions;
import com.azure.data.tables.models.TableEntity;
import com.azure.data.tables.models.TableEntityUpdateMode;
import com.azure.data.tables.models.TableTransactionAction;
import com.azure.data.tables.models.TableTransactionActionType;
Добавление строки подключения
Вы можете подключиться к учетной записи хранения Azure или учетной записи Azure Cosmos DB для таблицы. Получите строку подключения на основе типа используемой учетной записи.
Добавление строки подключения к службе хранилища Azure
Клиент таблиц Azure может использовать строку подключения с целью хранения конечных точек и учетных данных для доступа к службам управления данными. При работе в клиентском приложении предоставьте ему строку подключения к службе хранилища в приведенном ниже формате, указав имя учетной записи хранения и первичный ключ доступа для этой учетной записи в качестве значений параметров AccountName и AccountKey. Эти значения вы можете найти на портале Azure.
В этом примере показано, как объявить статическое поле для размещения строки подключения:
// Define the connection-string with your values.
public final String connectionString =
"DefaultEndpointsProtocol=http;" +
"AccountName=your_storage_account;" +
"AccountKey=your_storage_account_key;" +
"EndpointSuffix=core.windows.net";
Добавление Azure Cosmos DB для таблиц строка подключения
Учетная запись Azure Cosmos DB использует строку подключения для хранения учетных данных и конечной точки таблицы. При работе в клиентском приложении предоставьте ему строку подключения к Azure Cosmos DB в приведенном ниже формате, указав имя учетной записи Azure Cosmos DB и первичный ключ доступа для этой учетной записи в качестве значений параметров AccountName и AccountKey. Эти значения вы можете найти на портале Azure.
В этом примере показано, как объявить статическое поле для размещения строки подключения к Azure Cosmos DB:
public final String connectionString =
"DefaultEndpointsProtocol=https;" +
"AccountName=your_cosmosdb_account;" +
"AccountKey=your_account_key;" +
"TableEndpoint=https://your_endpoint;";
Если приложение выполняется в роли на платформе Azure, строку подключения можно сохранить в файле конфигурации службы (ServiceConfiguration.cscfg), к которому можно обратиться с помощью метода System.getenv
. Ниже приведен пример получения строки подключения из элемента Setting с именем ConnectionString в файле конфигурации службы:
// Retrieve storage account from connection-string.
String connectionString = System.getenv("ConnectionString");
Также вы можете сохранить строку подключения в файле проекта config.properties.
connectionString = DefaultEndpointsProtocol=https;AccountName=your_account;AccountKey=your_account_key;TableEndpoint=https://your_table_endpoint/
В приведенных ниже примерах предполагается, что вы использовали один из описанных выше методов для получения строки подключения к хранилищу.
Создание таблицы
Объект TableServiceClient
позволяет взаимодействовать со службой таблиц: создавать, перечислять и удалять таблицы. Приведенный ниже код создает объект TableServiceClient
и использует его для создания нового объекта TableClient
, который представляет таблицу Employees
.
try
{
final String tableName = "Employees";
// Create a TableServiceClient with a connection string.
TableServiceClient tableServiceClient = new TableServiceClientBuilder()
.connectionString(connectionString)
.buildClient();
// Create the table if it not exists.
TableClient tableClient = tableServiceClient.createTableIfNotExists(tableName);
}
catch (Exception e)
{
// Output the stack trace.
e.printStackTrace();
}
Перечисление таблиц
Чтобы получить список таблиц, вызовите метод TableServiceClient.listTables
для извлечения пригодного к итерации списка имен таблиц.
try
{
// Create a TableServiceClient with a connection string.
TableServiceClient tableServiceClient = new TableServiceClientBuilder()
.connectionString(connectionString)
.buildClient();
// Loop through a collection of table names.
tableServiceClient.listTables().forEach(tableItem ->
System.out.printf(tableItem.getName())
);
}
catch (Exception e)
{
// Output the stack trace.
e.printStackTrace();
}
Добавление сущности в таблицу
Следующий код создает новый экземпляр класса TableEntity
с подлежащими сохранению данными клиента. Код вызывает метод upsertEntity
для объекта TableClient
. Этот метод либо вставляет в таблицу Employees
новую сущность Customer (Клиент), либо заменяет эту сущность, если она уже существует.
try
{
final String tableName = "Employees";
// Create a TableClient with a connection string and a table name.
TableClient tableClient = new TableClientBuilder()
.connectionString(connectionString)
.tableName(tableName)
.buildClient();
// Create a new employee TableEntity.
String partitionKey = "Sales";
String rowKey = "0001";
Map<String, Object> personalInfo= new HashMap<>();
personalInfo.put("FirstName", "Walter");
personalInfo.put("LastName", "Harp");
personalInfo.put("Email", "Walter@contoso.com");
personalInfo.put("PhoneNumber", "425-555-0101");
TableEntity employee = new TableEntity(partitionKey, rowKey).setProperties(personalInfo);
// Upsert the entity into the table
tableClient.upsertEntity(employee);
}
catch (Exception e)
{
// Output the stack trace.
e.printStackTrace();
}
Вставка пакета сущностей
Вы можете вставить пакет сущностей в таблицу в одной операции записи. Следующий код создает объект List<TableTransactionAction>
и добавляет в него три операции upsert. Для добавления каждой операции необходимо создать новый объект TableEntity
, задать его свойства, а затем вызвать метод submitTransaction
для объекта TableClient
.
try
{
final String tableName = "Employees";
// Create a TableClient with a connection string and a table name.
TableClient tableClient = new TableClientBuilder()
.connectionString(connectionString)
.tableName(tableName)
.buildClient();
String partitionKey = "Sales";
List<TableTransactionAction> tableTransactionActions = new ArrayList<>();
Map<String, Object> personalInfo1 = new HashMap<>();
personalInfo1.put("FirstName", "Jeff");
personalInfo1.put("LastName", "Smith");
personalInfo1.put("Email", "Jeff@contoso.com");
personalInfo1.put("PhoneNumber", "425-555-0104");
// Create an entity to add to the table.
tableTransactionActions.add(new TableTransactionAction(
TableTransactionActionType.UPSERT_MERGE,
new TableEntity(partitionKey, "0001")
.setProperties(personalInfo1)
));
Map<String, Object> personalInfo2 = new HashMap<>();
personalInfo2.put("FirstName", "Ben");
personalInfo2.put("LastName", "Johnson");
personalInfo2.put("Email", "Ben@contoso.com");
personalInfo2.put("PhoneNumber", "425-555-0102");
// Create another entity to add to the table.
tableTransactionActions.add(new TableTransactionAction(
TableTransactionActionType.UPSERT_MERGE,
new TableEntity(partitionKey, "0002")
.setProperties(personalInfo2)
));
Map<String, Object> personalInfo3 = new HashMap<>();
personalInfo3.put("FirstName", "Denise");
personalInfo3.put("LastName", "Rivers");
personalInfo3.put("Email", "Denise@contoso.com");
personalInfo3.put("PhoneNumber", "425-555-0103");
// Create a third entity to add to the table.
tableTransactionActions.add(new TableTransactionAction(
TableTransactionActionType.UPSERT_MERGE,
new TableEntity(partitionKey, "0003")
.setProperties(personalInfo3)
));
// Submit transaction on the "Employees" table.
tableClient.submitTransaction(tableTransactionActions);
}
catch (Exception e)
{
// Output the stack trace.
e.printStackTrace();
}
Некоторые другие примечания к пакетным операциям:
- В отдельном пакете можно выполнить до 100 операций вставки, удаления, объединения, замены, вставки или замены и вставки или замены операций в любом сочетании.
- Пакетная операция может иметь операцию извлечения, если она является единственной операцией в пакете.
- У всех сущностей в одной пакетной операции должен быть одинаковый ключ раздела.
- Максимальный объем полезных данных пакетной операции составляет 4 МБ.
Получение всех сущностей в разделе
Чтобы запросить из таблицы сущности раздела, можно использовать ListEntitiesOptions
. Вызовите ListEntitiesOptions.setFilter
, чтобы создать запрос для определенной таблицы, который возвращает результаты заданного типа. Приведенный ниже код задает фильтр для сущностей с ключом раздела Sales
. Когда выполняется запрос путем вызова listEntities
из объекта TableClient
, ответ содержит Iterator
для TableEntity
. Затем можно передать полученное значение Iterator
в цикл ForEach для обработки результатов. Этот код выводит на консоль поля каждой сущности в результатах запроса.
try
{
// Define constants for filters.
final String PARTITION_KEY = "PartitionKey";
final String tableName = "Employees";
// Create a TableClient with a connection string and a table name.
TableClient tableClient = new TableClientBuilder()
.connectionString(connectionString)
.tableName(tableName)
.buildClient();
// Create a filter condition where the partition key is "Sales".
ListEntitiesOptions options = new ListEntitiesOptions().setFilter(PARTITION_KEY + " eq 'Sales'");
// Loop through the results, displaying information about the entities.
tableClient.listEntities(options, null, null).forEach(tableEntity -> {
System.out.println(tableEntity.getPartitionKey() +
" " + tableEntity.getRowKey() +
"\t" + tableEntity.getProperty("FirstName") +
"\t" + tableEntity.getProperty("LastName") +
"\t" + tableEntity.getProperty("Email") +
"\t" + tableEntity.getProperty("PhoneNumber"));
});
}
catch (Exception e)
{
// Output the stack trace.
e.printStackTrace();
}
Получение диапазона сущностей в разделе
Если вы не хотите запрашивать все сущности в разделе, укажите диапазон с помощью операторов сравнения в фильтре. Приведенный ниже код объединяет два фильтра для получения всех сущностей в разделе Sales
с ключом строки от 0001 до 0004. После чего результаты запроса выводятся на консоль. Если вы используете сущности, добавленные в таблицу во время работы с разделом о пакетной вставке, то на этот раз возвращаются только две сущности (Ben и Denise).
try
{
// Define constants for filters.
final String PARTITION_KEY = "PartitionKey";
final String ROW_KEY = "RowKey";
final String tableName = "Employees";
// Create a TableServiceClient with a connection string.
// Create a TableClient with a connection string and a table name.
TableClient tableClient = new TableClientBuilder()
.connectionString(connectionString)
.tableName(tableName)
.buildClient();
// Create a filter condition where the partition key is "Sales".
ListEntitiesOptions options = new ListEntitiesOptions().setFilter(PARTITION_KEY + " eq 'Sales' AND " + ROW_KEY + " lt '0004' AND " + ROW_KEY + " gt '0001'");
// Loop through the results, displaying information about the entities.
tableClient.listEntities(options, null, null).forEach(tableEntity -> {
System.out.println(tableEntity.getPartitionKey() +
" " + tableEntity.getRowKey() +
"\t" + tableEntity.getProperty("FirstName") +
"\t" + tableEntity.getProperty("LastName") +
"\t" + tableEntity.getProperty("Email") +
"\t" + tableEntity.getProperty("PhoneNumber"));
});
}
catch (Exception e)
{
// Output the stack trace.
e.printStackTrace();
}
Извлечение одной сущности
Можно написать запрос для получения отдельной сущности. Следующий код вызывает TableClient.getEntity
с параметрами ключа раздела и ключа строки, позволяя получить сущность сотрудника Jeff Smith. Это дает такой же результат, как создание ListEntitiesOptions
и применение фильтров. При выполнении операция извлечения возвращает только одну сущность, а не коллекцию. Значение null
возвращается, если ни одна сущность не подходит по ключам раздела и строки. Указание ключа раздела и ключа строки в запросе — самый быстрый способ для получения одной сущности из службы таблиц .
try
{
final String tableName = "Employees";
// Create a TableClient with a connection string and a table name.
TableClient tableClient = new TableClientBuilder()
.connectionString(connectionString)
.tableName(tableName)
.buildClient();
// Get the specific entity.
TableEntity specificEntity = tableClient.getEntity("Sales", "0001");
// Output the entity.
if (specificEntity != null)
{
System.out.println(specificEntity.getPartitionKey() +
" " + specificEntity.getRowKey() +
"\t" + specificEntity.getProperty("FirstName") +
"\t" + specificEntity.getProperty("LastName") +
"\t" + specificEntity.getProperty("Email") +
"\t" + specificEntity.getProperty("PhoneNumber"));
}
}
catch (Exception e)
{
// Output the stack trace.
e.printStackTrace();
}
Изменение сущности
Чтобы изменить сущность, извлеките ее из службы таблиц, измените объект сущности и сохраните изменения в службе таблиц с помощью операции замены или объединения. Следующий код изменяет существующий номер телефона клиента. Вместо вызова tableClient.upsertEntity
(как мы делали при вставке) этот код вызывает tableClient.updateEntity
.
try
{
final String tableName = "Employees";
// Create a TableClient with a connection string and a table name.
TableClient tableClient = new TableClientBuilder()
.connectionString(connectionString)
.tableName(tableName)
.buildClient();
// Get the specific entity.
TableEntity specificEntity = tableClient.getEntity("Sales", "0001");
// Specify a new phone number
specificEntity.getProperties().put("PhoneNumber", "425-555-0105");
// Update the specific entity
tableClient.updateEntity(specificEntity, TableEntityUpdateMode.REPLACE);
}
catch (Exception e)
{
// Output the stack trace.
e.printStackTrace();
}
Запрос подмножества свойств сущности
Запрос к таблице может получить лишь несколько свойств сущности. Этот метод, который называется "проекцией", снижает потребление пропускной способности и может повысить производительность запросов, особенно для крупных сущностей. Запрос в следующем коде использует метод ListEntitiesOptions.setSelect
, чтобы возвратить только адреса электронной почты сущностей в таблице.
try
{
final String tableName = "Employees";
// Create a TableClient with a connection string and a table name.
TableClient tableClient = new TableClientBuilder()
.connectionString(connectionString)
.tableName(tableName)
.buildClient();
// Create a filter condition that retrieves only the Email property.
List<String> attributesToRetrieve = new ArrayList<>();
attributesToRetrieve.add("Email");
ListEntitiesOptions options = new ListEntitiesOptions().setSelect(attributesToRetrieve);
// Loop through the results, displaying the Email values.
tableClient.listEntities(options, null, null).forEach(tableEntity -> {
System.out.println(tableEntity.getProperty("Email"));
});
}
catch (Exception e)
{
// Output the stack trace.
e.printStackTrace();
}
Вставка и замена сущностей
Часто требуется добавить сущность в таблицу, не зная, присутствует ли она там. Операция вставки или замены позволяет выполнить один запрос. Этот запрос либо вставляет сущность, если она не существует, либо заменяет существующую. В продолжение материала предыдущих примеров следующий код вставляет или заменяет сущность "Walter Harp". После создания новой сущности этот код вызывает метод TableClient.upsertEntity
.
try
{
final String tableName = "Employees";
// Create a TableClient with a connection string and a table name.
TableClient tableClient = new TableClientBuilder()
.connectionString(connectionString)
.tableName(tableName)
.buildClient();
// Create a new table entity.
Map<String, Object> properties = new HashMap<>();
properties.put("FirstName", "Walter");
properties.put("LastName", "Harp");
properties.put("Email", "Walter@contoso.com");
properties.put("PhoneNumber", "425-555-0101");
TableEntity newEmployee = new TableEntity("Sales", "0004")
.setProperties(properties);
// Add the new customer to the Employees table.
tableClient.upsertEntity(newEmployee);
}
catch (Exception e)
{
// Output the stack trace.
e.printStackTrace();
}
Удаление сущности
Сущность можно удалить, указав ключ раздела и ключ строки с помощью TableClient.deleteEntity
.
try
{
final String tableName = "Employees";
// Create a TableClient with a connection string and a table name.
TableClient tableClient = new TableClientBuilder()
.connectionString(connectionString)
.tableName(tableName)
.buildClient();
// Delete the entity for partition key 'Sales' and row key '0001' from the table.
tableClient.deleteEntity("Sales", "0001");
}
catch (Exception e)
{
// Output the stack trace.
e.printStackTrace();
}
Удалить таблицу
Наконец, указанный ниже код удаляет таблицу из учетной записи. После удаления таблицы ее нельзя создать заново в течение примерно 40 секунд.
try
{
final String tableName = "Employees";
// Create a TableClient with a connection string and a table name.
TableClient tableClient = new TableClientBuilder()
.connectionString(connectionString)
.tableName(tableName)
.buildClient();
// Delete the table and all its data.
tableClient.deleteTable();
}
catch (Exception e)
{
// Output the stack trace.
e.printStackTrace();
}
Совет
См. примеры кода в репозитории службы хранилища Azure
Полные и простые в применении примеры кода для службы хранилища Azure можно скачать и запустить отсюда.
Следующие шаги
- Getting Started with Azure Table Service in Java (Приступая к работе со службой таблиц Azure на языке Java)
- Обозреватель хранилищ Microsoft Azure — это бесплатное автономное приложение от корпорации Майкрософт, позволяющее визуализировать данные из службы хранилища Azure на платформе Windows, macOS и Linux.
- Клиентская библиотека таблиц Azure для Java
- Справочник по клиентской библиотеке таблиц Azure
- REST API таблиц Azure
- Блог команды разработчиков таблиц Azure
Дополнительные сведения см. в разделе Azure for Java developers (Azure для разработчиков Java).