Упражнение. Выполнение запросов с помощью пакета SDK Azure Cosmos DB для Java
Итак, документы в приложении созданы, и мы можем запросить их из приложения. Пакет SDK Azure Cosmos DB для Java использует SQL-запросы. Пакет SDK для .NET обеспечивает дополнительную поддержку запросов LINQ, но в пакете SDK для Java такая поддержка отсутствует. Этот урок посвящен запуску SQL-запросов из своего приложения, а не с портала.
Для тестирования этих запросов будут использоваться документы, созданные для приложения интернет-магазина.
Выполнение запросов SQL
В следующем примере показано выполнение запроса в SQL из кода Java. Скопируйте код и добавьте его в конец файла CosmosApp.java.
/** * Execute a custom query on the Azure Cosmos DB container. * @param query Query String. */ private static void executeSimpleQuery(final String query) { final int preferredPageSize = 10; CosmosQueryRequestOptions queryOptions = new CosmosQueryRequestOptions(); CosmosPagedFlux<User> pagedFluxResponse = container.queryItems( query, queryOptions, User.class); logger.info("Running SQL query..."); pagedFluxResponse.byPage(preferredPageSize).flatMap(fluxResponse -> { logger.info("Got a page of query result with " + fluxResponse.getResults().size() + " items(s) and request charge of " + fluxResponse.getRequestCharge()); logger.info("Item Ids " + fluxResponse .getResults() .stream() .map(User::getId) .collect(Collectors.toList())); return Flux.empty(); }).blockLast(); }
Обратите внимание, что в этом коде мы снова используем декларативную модель Project Reactor для программирования потоков данных. Но на этот раз мы используем ее для асинхронной обработки страниц ответов на запросы. Мы демонстрируем асинхронный подход, так как в реальных вариантах использования на один запрос можно получить более сотен тысяч ответов. Агрегирование ответов на запрос может быть очень ресурсоемкой для ЦП задачей, выполнение которой упрощается благодаря повышенной эффективности работы потоков, обеспечиваемой асинхронным программированием.
Вкратце, нам нужна высокая пропускная способность при обработке ответов на запросы или большое число страниц в секунду на поток.
queryitems
возвращаетpagedFluxResponse
экземпляраCosmosPagedFlux
, аpagedFluxResponse.byPage(preferredPageSize)
создает экземплярFlux
, который является источником асинхронных событий страницы. Конвейер операций в.flatMap( ... ).blockLast();
асинхронно и в псевдопараллельном режиме обрабатывает страницу ответов на запрос, связанную с каждым событием, создаваемым экземпляромFlux
.Скопируйте и вставьте следующий код в метод
basicOperations
, перед кодом удаления документа.executeSimpleQuery("SELECT * FROM User WHERE User.lastName = 'Pindakova'");
Выполните сборку и запустите CosmosApp.java в интегрированной среде разработки или запустите программу в терминале:
mvn clean package mvn exec:java -Dexec.mainClass="com.azure.cosmos.examples.mslearnbasicapp.CosmosApp"
Результат должен выглядеть следующим образом.
INFO: Database and container validation complete INFO: User 1 already exists in the database INFO: User 2 already exists in the database INFO: Read User 1 INFO: Replaced last name for Suh INFO: Running SQL query... INFO: Got a page of query result with 1 items(s) and request charge of 2.83 INFO: Item Ids [2] INFO: Deleted User 1
Итак, документы в приложении созданы, и мы можем запросить их из приложения. Spring Data Azure Cosmos DB предоставляет как методы производных запросов, так и методы пользовательских запросов. Оба они построены на возможностях запросов на языке SQL базового пакета SDK Azure Cosmos DB для Java версии 4. Этот урок посвящен запуску запросов Spring Data Azure Cosmos DB из своего приложения, а не с портала.
Для тестирования этих запросов будут использоваться документы WebCustomer
, созданные для приложения интернет-магазина.
Создание и вызов методов производных запросов
Методы производных запросов — это методы репозитория Spring Data без реализации. Вместо этого имя метода подает сигнал Spring Data, чтобы преобразовать каждый вызов метода и его аргументы в запрос к основной базе данных. Например, при вызове findById
с некоторыми аргументами Spring Data считывает имя метода как "поиск по ИД" и создает запрос базы данных, который возвращает документ, заданный аргументами.
Spring Data Azure Cosmos DB содержит ряд встроенных методов производных запросов, включая findById
. В этом разделе описано, как реализовать новые методы производных запросов.
Мы создадим метод производных запросов, который будет запрашивать все документы с определенным значением для поля
firstName
. Перейдите к файлу ReactiveWebCustomerRepository.java. Отобразится следующее объявление метода:Flux<WebCustomer> findByFirstName(String firstName);
Этот метод репозитория объявляет Spring Data, что вам нужен метод, который при вызове запрашивает
firstName
. Напомним, что классWebCustomer
начался с аннотации@Container
, указывающейcontainerName
в качествеWebCustomers
. Так какfindByFirstName
возвращаетFlux<WebCustomer>
, Spring Data запрашиваетWebCustomers
при вызове этого метода.Скопируйте и вставьте приведенный ниже код в метод
run
перед вызовомdeleteWebCustomerDocument
.logger.info("Running derived query..."); Flux<WebCustomer> webCustomers = reactiveWebCustomerRepository.findByFirstName("Max"); webCustomers.flatMap(webCustomer -> { logger.info("- WebCustomer is : {}", webCustomer.getUserId()); return Mono.empty(); }).blockLast();
Обратите внимание, что в этом коде мы снова используем декларативную модель Project Reactor для программирования потоков данных. Но на этот раз мы используем ее для асинхронной обработки страниц ответов на запросы. Мы демонстрируем асинхронный подход, так как в реальных вариантах использования на один запрос можно получить более сотен тысяч ответов. Агрегирование ответов на запрос может быть очень ресурсоемкой для ЦП задачей, выполнение которой упрощается благодаря повышенной эффективности работы потоков, обеспечиваемой асинхронным программированием.
Вкратце, нам нужна высокая пропускная способность при обработке ответов на запросы или большое число ответов в секунду на поток.
findByFirstName
возвращает экземплярFlux<WebCustomer>
webCustomers
. Конвейер операций в.flatMap( ... ).blockLast();
работает асинхронно и в псевдопараллельном режиме в ответах на запрос, связанных с каждым событием, создаваемымFlux<WebCustomer>
.Выполните сборку и запустите CosmosSample.java в интегрированной среде разработки или запустите программу в терминале:
mvn clean package mvn spring-boot:run
Результат должен выглядеть следующим образом.
INFO: - WebCustomer is : maxaxam
Создание и вызов методов пользовательских запросов
Методы пользовательских запросов — это методы репозитория Spring Data с заметкой @Query
, указывающей строку запроса, которая содержит заполнители для аргументов метода. На этот раз имя метода не влияет на выполняемый запрос. Заметка @Query
подает сигнал Spring Data, чтобы создать запрос на языке SQL к основной базе данных, после введения для заполнителей значений аргументов метода.
Мы создадим метод пользовательского запроса, который будет запрашивать все документы с определенным значением для поля
lastName
. Перейдите к файлу ReactiveWebCustomerRepository.java. Отобразится следующее объявление метода:@Query(value = "SELECT * FROM User WHERE User.lastName = @lastName") Flux<WebCustomer> findByLastName(@Param("lastName") String lastName);
Этот метод репозитория объявляет Spring Data, что вам нужен метод, который при вызове запрашивает
lastName
. Значение аргументаlastName
будет заменено на заполнитель@lastName
.Скопируйте и вставьте следующий код в метод
run
после кода производного запроса.logger.info("Running custom query..."); webCustomers = reactiveWebCustomerRepository.findByLastName("Axam"); webCustomers.flatMap(webCustomer -> { logger.info("- WebCustomer is : {}", webCustomer.getUserId()); return Mono.empty(); }).blockLast();
Выполните сборку и запустите CosmosSample.java в интегрированной среде разработки или запустите программу в терминале:
mvn clean package mvn spring-boot:run
Результат должен выглядеть следующим образом.
INFO: Running derived query... INFO: - WebCustomer is : maxaxam INFO: Running custom query... INFO: - WebCustomer is : maxaxam
Из этого урока вы узнали о производных и пользовательских запросах. Затем вы добавили оба типа запросов в свое приложение и извлекли записи пользователей.