연습 - Azure Cosmos DB Java SDK를 사용하여 쿼리하기
애플리케이션에 문서를 만들었으므로 애플리케이션에서 문서를 쿼리해 보겠습니다. Azure Cosmos DB Java SDK는 SQL 쿼리를 사용합니다. .NET SDK는 LINQ 쿼리에 대한 추가 지원을 제공하지만 Java SDK는 아날로그를 제공하지 않습니다. 이 단원에서는 SQL 쿼리를 포털이 아닌 애플리케이션에서 실행하는 방법을 중점적으로 살펴봅니다.
온라인 판매점 애플리케이션을 위해 만든 사용자 문서를 사용하여 이러한 쿼리를 테스트합니다.
SQL 쿼리 실행
다음 샘플은 Java 코드의 SQL에서 쿼리가 수행되는 방법을 보여 줍니다. 코드를 복사하여 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의 선언적 데이터 흐름 프로그래밍 모델을 다시 한 번 사용합니다. 이번에는 쿼리 응답 페이지를 비동기적으로 처리하는 데 사용하고 있습니다. 실제 사용 사례에는 수백 또는 수천 개의 쿼리에 대한 응답이 있을 수 있으므로 비동기 접근 방식을 살펴 보겠습니다. 쿼리 응답을 집계하는 작업은 비동기 프로그래밍의 향상된 스레드 효율성을 활용하기 때문에 CPU를 많이 사용하는 작업이 될 수 있습니다.
간단히 말하면 쿼리 응답을 처리하는 높은 처리량, 즉 스레드 하나당 높은 초당 페이지를 달성하고자 합니다.
queryitems
는CosmosPagedFlux
인스턴스pagedFluxResponse
를 반환하고,pagedFluxResponse.byPage(preferredPageSize)
는 비동기 페이지 이벤트의 원본인Flux
인스턴스를 만듭니다..flatMap( ... ).blockLast();
안의 작업 파이프라인은 비동기로 작동하고Flux
인스턴스에서 출력하는 각 이벤트에 연결된 쿼리 응답 페이지에 대해 의사 병렬로 작동합니다.다음 코드를 복사하여
basicOperations
메서드에서 문서 삭제 코드 앞에 붙여넣습니다.executeSimpleQuery("SELECT * FROM User WHERE User.lastName = 'Pindakova'");
IDE에서 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는 파생 쿼리 메서드와 사용자 지정 쿼리 메서드 모두 제공하며, 기본 Azure Cosmos DB Java SDK v4의 SQL 언어 쿼리 기능 기반의 빌드를 제공합니다. 이 단원에서는 Spring Data Azure Cosmos DB 쿼리를 포털이 아닌 애플리케이션에서 실행하는 방법을 중점적으로 살펴봅니다.
온라인 판매점 애플리케이션을 위해 만든 WebCustomer
문서를 사용하여 이러한 쿼리를 테스트합니다.
파생 쿼리 메서드 만들기 및 호출
파생 쿼리 메서드는 구현을 사용하지 않은 Spring Data 리포지토리 메서드입니다. 대신 메서드 이름에서 Spring Data로 신호를 보내 각 메서드 호출 및 인수를 기본 데이터베이스의 쿼리로 변환합니다. 예를 들어 일부 인수를 사용하여 findById
를 호출하는 경우 Spring Data는 "find by ID"로 메서드 이름을 읽고 인수로 지정된 문서를 반환하는 데이터베이스 쿼리를 어셈블합니다.
Spring Data Azure Cosmos DB에는 findById
를 포함한 기본 파생 쿼리 메서드가 있습니다. 이 섹션에서는 새로운 파생 쿼리 메서드를 구현하는 방법을 보여줍니다.
firstName
필드에 대해 특정 값을 보유한 모든 문서를 쿼리하는 파생 쿼리 메서드를 만듭니다. ReactiveWebCustomerRepository.java로 이동합니다. 다음 메서드 선언이 표시됩니다.Flux<WebCustomer> findByFirstName(String firstName);
이 리포지토리 메서드는 호출될 때
firstName
에 쿼리하는 메서드를 원하는 Spring Data로 선언합니다.WebCustomer
클래스는containerName
을WebCustomers
로 지정하는@Container
주석으로 시작되었습니다.findByFirstName
에서Flux<WebCustomer>
를 반환하므로 Spring Data는 이 메서드가 호출될 때WebCustomers
를 쿼리하는 것을 인식합니다.deleteWebCustomerDocument
호출 이전에 다음 코드를 복사하고run
메서드에 붙여넣습니다.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의 선언적 데이터 흐름 프로그래밍 모델을 다시 한 번 사용합니다. 이번에는 쿼리 응답 페이지를 비동기적으로 처리하는 데 사용하고 있습니다. 실제 사용 사례에는 수백 또는 수천 개의 쿼리에 대한 응답이 있을 수 있으므로 비동기 접근 방식을 살펴 보겠습니다. 쿼리 응답을 집계하는 작업은 비동기 프로그래밍의 향상된 스레드 효율성을 활용하기 때문에 CPU를 많이 사용하는 작업이 될 수 있습니다.
간단히 말하면 쿼리 응답을 처리하는 높은 처리량, 즉 스레드 하나당 높은 초당 응답 수를 달성하고자 합니다.
findByFirstName
은Flux<WebCustomer>
인스턴스인webCustomers
를 반환합니다..flatMap( ... ).blockLast();
안의 작업 파이프라인은 비동기로 작동하고Flux<WebCustomer>
에서 출력하는 각 이벤트에 연결된 쿼리 응답에 대해 의사 병렬로 작동합니다.IDE에서 CosmosSample.java를 빌드하고 실행하거나 터미널에서 다음을 사용하여 프로그램을 실행합니다.
mvn clean package mvn spring-boot:run
터미널에서 출력은 다음과 같습니다.
INFO: - WebCustomer is : maxaxam
사용자 지정 쿼리 만들기 및 호출
사용자 지정 쿼리 메서드는 쿼리 문자열을 지정하는 @Query
주석이 포함된 Spring Data 리포지토리 메서드이며, 쿼리 문자열에는 메서드 인수에 대한 자리 표시자가 포함됩니다. 이번에는 메서드 이름이 어떤 쿼리를 수행하는지에 영향을 미치지 않습니다. @Query
주석은 Spring Data에 신호를 보내 인수 자리 표시자를 메서드 인수의 값으로 채운 이후 기본 데이터베이스로 SQL 언어 쿼리를 실행합니다.
lastName
필드에 대해 특정 값을 보유한 모든 문서를 쿼리하는 사용자 지정 쿼리 메서드를 만듭니다. ReactiveWebCustomerRepository.java로 이동합니다. 다음 메서드 선언이 표시됩니다.@Query(value = "SELECT * FROM User WHERE User.lastName = @lastName") Flux<WebCustomer> findByLastName(@Param("lastName") String lastName);
이 리포지토리 메서드는 호출될 때
lastName
에 쿼리하는 메서드를 원하는 Spring Data로 선언합니다.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();
IDE에서 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
이 단원에서는 파생 쿼리와 사용자 지정 쿼리를 학습했습니다. 그런 다음 두 쿼리 유형을 애플리케이션에 추가하여 사용자 레코드를 검색했습니다.