Oefening: NoSQL-gegevens programmatisch maken, lezen, bijwerken en verwijderen
U hebt de verbinding naar Azure Cosmos DB gemaakt. In deze eenheid gaat u gebruikersdocumenten in uw WebCustomers
-verzameling maken. Vervolgens haalt u de documenten op per ID, vervangt u ze en verwijdert u ze.
Programmatisch werken met documenten
Gegevens zijn opgeslagen in JSON-documenten in Azure Cosmos DB. Documenten in de portal kunnen programmatisch worden gemaakt, opgehaald, vervangen of verwijderd. Dit lab gaat over programmatische bewerkingen. Azure Cosmos DB biedt SDK’s aan de clientzijde voor .NET, .NET Core, Java, Node.js en Python. Elk van deze SDK’s biedt ondersteuning voor deze bewerkingen. In deze module wordt gebruikgemaakt van de Java SDK om CRUD-bewerkingen (maken, ophalen, bijwerken en verwijderen) uit te voeren op NoSQL-gegevens die zijn opgeslagen in Azure Cosmos DB.
De belangrijkste bewerkingen voor Azure Cosmos DB-documenten zijn onderdeel van de klasse CosmosAsyncContainer:
Met upsert wordt een bewerking voor maken of vervangen uitgevoerd, afhankelijk van het feit of het document al bestaat.
Als u een van deze bewerkingen wilt uitvoeren, hebt u helperklassen (Java POJO-klassen) nodig die de objecten vertegenwoordigen die in de database zijn opgeslagen. Omdat we werken met een database met gebruikers, moet u een User
-klasse instellen die gebruikersentiteiten vertegenwoordigt. Met deze klasse worden primaire gegevens opgeslagen, zoals voornaam, achternaam en gebruikers-ID. (De ID is vereist omdat dit de partitiesleutel is om horizontaal schalen mogelijk te maken.)
Omdat iedere gebruiker enkele gekoppelde verzendvoorkeuren en coupons heeft, kunt u ShippingPreference
- en CouponsUsed
-gegevenstypen gebruiken om deze entiteiten weer te geven. Tot slot kan iedere gebruiker een bestelgeschiedenis hebben die mogelijk niet gebonden is. U kunt daarom het beste afzonderlijke OrderHistory
-entiteiten met een bijbehorende Java POJO-klasse gebruiken.
Ga naar src/main/Java/com/azure/Azure-Cosmos-Java-SQL-app-mslearn en zoek in de map gegevenstypen. U ziet een aantal POJO's: User
, ShippingPreference
, OrderHistory
en CouponsUsed
. Daarom hebben we alle entiteits-POJO's en hun helperklassen verstrekt.
Vervolgens maken we een aantal entiteiten en voeren we enkele eenvoudige CRUD-bewerkingen uit op de Azure Cosmos DB-container en de daarin opgenomen documenten. U kunt Azure Cosmos DB een Jackson-ObjectNode
-instantie doorgeven die rechtstreeks het JSON-document opgeeft. Maar Azure Cosmos DB kan ook Java-POJO's naar JSON serialiseren. Aangezien dit de eenvoudigste aanpak is en er verder geen verschillen zijn, raden we deze methode aan.
Documenten maken
Open User.java en bekijk de inhoud. Het ziet er ongeveer als volgt uit:
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.List; @Data @NoArgsConstructor @AllArgsConstructor public class User { /** Document ID (required by Azure Cosmos DB). */ private String id; /** User ID. */ private String userId; /** User last name. */ private String lastName; /** User first name. */ private String firstName; /** User email address. */ private String email; /** User dividend setting. */ private String dividend; /** User shipping preferences. */ private ShippingPreference shippingPreference; /** User order history. */ private List<OrderHistory> orderHistory; /** Coupons recorded by the user. */ private List<CouponsUsed> coupons; }
Houd er rekening mee dat de toegangsmethoden voor de velden
id
,userId
en andere velden impliciet zijn (dus niet gedefinieerd in code). Dit gedrag is mogelijk omdat we de annotatie Project Lombok@Data
gebruiken om ze automatisch te maken.Met de annotatie
@NoArgsConstructor
wordt een constructor gegenereerd zonder argumenten voor het instellen van standaard veldwaarden. Met de annotatie@AllArgsConstructor
wordt een andere constructor met een volledige set argumenten gegenereerd om alle veldwaarden rechtstreeks op te geven.Houd er rekening mee dat
User
eenid
-eigenschap heeft. Alle Azure Cosmos DB-documenten vereisen eenid
-eigenschap en daarom moeten alle POJO's die we willen serialiseren naar JSON-documenten, eenid
-veld bevatten.Voeg de volgende methode toe aan CosmosApp.java:
/** * Take in list of Java POJOs, check if each exists, and if not insert it. * @param users List of User POJOs to insert. */ private static void createUserDocumentsIfNotExist(final List<User> users) { Flux.fromIterable(users).flatMap(user -> { try { container.readItem(user.getId(), new PartitionKey(user.getUserId()), User.class).block(); logger.info("User {} already exists in the database", user.getId()); return Mono.empty(); } catch (Exception err) { logger.info("Creating User {}", user.getId()); return container.createItem(user, new PartitionKey(user.getUserId()), new CosmosItemRequestOptions()); } }).blockLast(); }
Keer terug naar de methode
basicOperations
en voeg het volgende toe aan het einde van die methode, nog vóór declient.close()
-aanroep.User maxaxam = new User( "1", "maxaxam", "Axam", "Max", "maxaxam@contoso.com", "2.0", new ShippingPreference( 1, "90 W 8th St", "", "New York", "NY", "10001", "USA" ), new ArrayList<OrderHistory>(Arrays.asList( new OrderHistory( "3", "1000", "08/17/2018", "52.49" ) )), new ArrayList<CouponsUsed>(Arrays.asList( new CouponsUsed( "A7B89F" ) )) ); User nelapin = new User( "2", "nelapin", "Pindakova", "Nela", "nelapin@contoso.com", "8.50", new ShippingPreference( 1, "505 NW 5th St", "", "New York", "NY", "10001", "USA" ), new ArrayList<OrderHistory>(Arrays.asList( new OrderHistory( "4", "1001", "08/17/2018", "105.89" ) )), new ArrayList<CouponsUsed>(Arrays.asList( new CouponsUsed( "Fall 2018" ) )) ); createUserDocumentsIfNotExist(new ArrayList<User>(Arrays.asList(maxaxam, nelapin)));
Zorg dat u CosmosApp.java bouwt en uitvoert in de IDE of voer het programma uit in de terminal met behulp van:
mvn clean package mvn exec:java -Dexec.mainClass="com.azure.cosmos.examples.mslearnbasicapp.CosmosApp"
Bij het maken van elk nieuw gebruikersdocument wordt uitvoer weergegeven op de terminal.
INFO: Database and container validation complete INFO: Creating User 1 INFO: Creating User 2
Mogelijk wordt er ook extra tekst weergegeven die door de logger is verzonden, zoals timestamps.
Gefeliciteerd U hebt uw eerste gegevens in Azure Cosmos DB gemaakt vanuit een Java-toepassing. Laat we eens evalueren wat u hier hebt gedaan.
Er zijn drie nieuwe acties in basicOperations
:
- Maak het maxaxam
User
-exemplaar. - Maak het nelapin
User
-exemplaar. - Roep
createUserDocumentsIfNotExist
aan en geef maxaxam en nelapin door als een lijst.
Met het aanroepen van createUserDocumentsIfNotExist
worden beide User
-instanties als items/documenten toegevoegd aan Azure Cosmos DB. Als u de User
-instanties doorgeeft als een lijst, is het onze bedoeling om een performante methode te modelleren om met behulp van een minimum aan rekenresources snel POJO's in Azure Cosmos DB op te nemen. createUserDocumentsIfNotExist
implementeert efficiënte asynchrone invoeging van een lijst met POJO's.
Stel dat ons doel is om het aantal aanvragen per seconde per thread te maximaliseren. Ter vergelijking, de synchronisatiebenadering voor het schrijven van createUserDocumentsIfNotExist
, waarbij we de readItem
-controle voorlopig negeren, is om te itereren over elk User
-exemplaar in users
. Voor elke User
u
maken we een blokkerende aanroep naar createItem
:
container.createItem(u, new PartitionKey(u.getUserId()), new CosmosItemRequestOptions()).block(); // <= Note the .block() which loops until request response.
Deze synchronisatiestijl implementeert een intuïtief proces: aanvraag indienen, wachten op antwoord, volgende aanvraag indienen. createUserDocumentsIfNotExist
gebruikt deze methode echter niet, omdat blokkerende aanroepen in feite CPU-cycli verspillen tijdens de reactietijd van de aanvraag, wat leidt tot een laag aantal aanvragen per seconde.
U kunt deze aanvragen/het tweede probleem omzeilen door meerdere threads te produceren om parallelle aanroepen voor het blokkeren van aanvragen te doen. De meerdere threads zorgen voor een betere uitvoering van de runtime. Maar als het uw doel is zuinig te zijn met threadresources, blijft dit een verspilling. Elke thread wordt opnieuw uitgevoerd tijdens de reactietijd van een aanvraag, terwijl de thread in plaats daarvan meerdere taken had kunnen verwerken voor iets anders, waardoor u per thread maar weinig aanvragen per seconde kunt sturen.
Daarom en omdat we u een threadefficiënte invoeging van Java POJO's willen tonen, hebben we in plaats daarvan een asynchroon voorbeeld van documentinvoeging gegeven. De ondersteuning voor Azure Cosmos DB Java SDK v4 is afkomstig van Project Reactor, een Java-toepassingsframework dat een stroomgebaseerd programmeermodel met declaratieve gegevensstromen biedt voor asynchroon, gebeurtenisgestuurd programmeren. Met createDocumentsIfNotExist
wordt de asynchrone programmering van Project Reactor geïmplementeerd.
In createUserDocumentsIfNotExist
is Flux.fromIterable(users)
een Project Reactor-factory-methode. Er wordt een Flux
-exemplaar gemaakt dat een bron is van asynchrone gebeurtenissen. In dit geval bevat elke asynchrone gebeurtenis een argument van het User
-exemplaar. Het Flux
-exemplaar bevat twee dergelijke gebeurtenissen, één voor maxaxam en één voor nelapin. De code in .flatMap( ... ).blockLast();
definieert een pijplijn van opeenvolgende bewerkingen die moeten worden uitgevoerd voor de gebeurtenissen die worden gegenereerd door het Flux
-exemplaar.
Een van deze bewerkingen is createItem
. Het idee is dat deze pijplijn bijna identiek is aan de synchrone implementatie, met dit verschil dat de createItem
-aanroep niet blokkeren. Meer in het bijzonder betekent de aanroep van blockLast()
een abonnement op de geassembleerde pijplijn, waardoor de Flux
de twee eigen gebeurtenissen asynchroon uitvoert. Vervolgens wordt in de pijplijn binnen .flatMap( ... ).blockLast();
elk van deze gebeurtenissen op een pseudo-parallelle manier verwerkt. Wanneer een aanvraag is ingediend en er wordt gewacht op een reactie, verwerkt Project Reactor de andere aanvragen op de achtergrond, wat een essentiële factor is om het aantal aanvragen per seconde per thread te maximaliseren.
Nu we efficiënte asynchrone databaseaanvragen met Project Reactor hebben gedemonstreerd, worden er voor de rest van dit lab blokkerende (synchrone) aanroepen gebruikt om het proces eenvoudig te houden. Voor meer informatie over Project Reactor gaat u naar de handleiding voor Reactor-patronen van Azure Cosmos DB.
Documenten lezen
Als u documenten uit de database wilt lezen, voegt u de volgende methode toe aan
CosmosApp
:/** * Take in a Java POJO argument, extract ID and partition key, and read the corresponding document from the container. * In this case the ID is the partition key. * @param user User POJO to pull ID and partition key from. */ private static CosmosItemResponse<User> readUserDocument(final User user) { CosmosItemResponse<User> userReadResponse = null; try { userReadResponse = container.readItem(user.getId(), new PartitionKey(user.getUserId()), User.class).block(); logger.info("Read user {}", user.getId()); } catch (CosmosException de) { logger.error("Failed to read user {}", user.getId(), de); } return userReadResponse; }
Kopieer en plak de volgende code aan het eind van de methode
basicOperations
, na de code voor het maken van het document:readUserDocument(maxaxam);
Zorg dat u CosmosApp.java bouwt en uitvoert in de IDE of voer het programma uit in de terminal met behulp van:
mvn clean package mvn exec:java -Dexec.mainClass="com.azure.cosmos.examples.mslearnbasicapp.CosmosApp"
In de terminal wordt de volgende uitvoer weergegeven, waarbij 'Read user 1' aangeeft dat het document is opgehaald.
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
Mogelijk wordt er ook extra tekst weergegeven die is verzonden door de logger.
Documenten vervangen
Azure Cosmos DB biedt ondersteuning voor het vervangen van JSON-documenten. In dit geval werken we een gebruikersaccount bij vanwege een wijziging in de achternaam.
Voeg in het bestand CosmosApp.java na de methode
readUserDocument
de methodereplaceUserDocument
toe./** * Take in a Java POJO argument, extract ID and partition key, * and replace the existing document with the same ID and partition key to match. * @param user User POJO representing the document update. */ private static void replaceUserDocument(final User user) { try { CosmosItemResponse<User> userReplaceResponse = container.replaceItem(user, user.getId(), new PartitionKey(user.getUserId())).block(); logger.info("Replaced User {}", user.getId()); } catch (CosmosException de) { logger.error("Failed to replace User {}", user.getUserId()); } }
Kopieer en plak de volgende code aan het einde van de
basicOperations
methode, na het lezen van de documentcode.maxaxam.setLastName("Suh"); replaceUserDocument(maxaxam);
Zorg dat u CosmosApp.java bouwt en uitvoert in de IDE of voer het programma uit in de terminal met behulp van:
mvn clean package mvn exec:java -Dexec.mainClass="com.azure.cosmos.examples.mslearnbasicapp.CosmosApp"
In de terminal wordt de volgende uitvoer weergegeven, waarbij 'Replaced last name for Suh' aangeeft dat het document is vervangen.
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
Documenten verwijderen
Kopieer en plak de
deleteUserDocument
-methode onder uwreplaceUserDocument
-methode./** * Take in a Java POJO argument, extract ID and partition key, * and delete the corresponding document. * @param user User POJO representing the document update. */ private static void deleteUserDocument(final User user) { try { container.deleteItem(user.getId(), new PartitionKey(user.getUserId())).block(); logger.info("Deleted user {}", user.getId()); } catch (CosmosException de) { logger.error("User {} could not be deleted.", user.getId()); } }
Kopieer en plak de volgende code aan het eind van de methode
basicOperations
.deleteUserDocument(maxaxam);
Zorg dat u CosmosApp.java bouwt en uitvoert in de IDE of voer het programma uit in de terminal met behulp van:
mvn clean package mvn exec:java -Dexec.mainClass="com.azure.cosmos.examples.mslearnbasicapp.CosmosApp"
In de terminal wordt de volgende uitvoer weergegeven, waarbij 'Deleted user 1' aangeeft dat het document is verwijderd.
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: Deleted User 1
Programmatisch werken met documenten
Gegevens zijn opgeslagen in JSON-documenten in Azure Cosmos DB. Documenten in de portal kunnen programmatisch worden gemaakt, opgehaald, vervangen of verwijderd. Dit lab gaat over programmatische bewerkingen. Al deze bewerkingen zijn beschikbaar in azure Cosmos DB Java SDK en zijn ook toegankelijk via het Spring Data-programmeermodel. In deze module gebruiken we Spring Data Azure Cosmos DB om CRUD-bewerkingen (maken, ophalen, bijwerken en verwijderen) uit te voeren op NoSQL-gegevens die zijn opgeslagen in Azure Cosmos DB.
De belangrijkste bewerkingen voor Spring Data Azure Cosmos DB-documenten zijn basisbewerkingen in het Spring Data-programmeermodel:
save
- een document punt-schrijven of bijwerken, afhankelijk van of het document al bestaat.view
- een document punt-lezendelete
- een document punt-verwijderen
Als u een van deze bewerkingen wilt uitvoeren, hebt u helperklassen (Java POJO-klassen) nodig die de objecten vertegenwoordigen die in de database zijn opgeslagen. Omdat we werken met een database met online klanten, kunt u het beste een WebCustomer
-klasse gebruiken die gebruikersentiteiten vertegenwoordigt. Met deze klasse worden primaire gegevens opgeslagen, zoals voornaam, achternaam en gebruikers-ID. (De ID is vereist omdat dit de partitiesleutel is om horizontaal schalen mogelijk te maken.)
Omdat iedere webgebruiker enkele gekoppelde verzendvoorkeuren en coupons heeft, kunt u ShippingPreference
- en CouponsUsed
-gegevenstypen gebruiken om deze entiteiten weer te geven. Tot slot kan iedere webklant een bestelgeschiedenis hebben die mogelijk niet gebonden is. U kunt daarom het beste afzonderlijke OrderHistory
-entiteiten met een bijbehorende Java POJO-klasse gebruiken.
Ga naar src/main/java/com/azure/cosmos/examples/springexamples. De WebCustomer
-POJO wordt weergeven. Kijk nu in de map common. U ziet een aantal POJO's: ShippingPreference
, OrderHistory
en CouponsUsed
. Daarom hebben we alle entiteits-POJO's en hun helperklassen verstrekt.
Vervolgens maken we een aantal entiteiten en voeren we enkele eenvoudige CRUD-bewerkingen uit op de Azure Cosmos DB-container en de daarin opgenomen documenten. U kunt Azure Cosmos DB een Jackson-ObjectNode
-instantie doorgeven die rechtstreeks het JSON-document opgeeft. Maar Azure Cosmos DB kan ook Java-POJO's naar JSON serialiseren. Aangezien dit de eenvoudigste aanpak is en er verder geen verschillen zijn, raden we deze methode aan.
Documenten maken en bijwerken
Open WebCustomer.java en bekijk de inhoud. Het ziet er ongeveer als volgt uit:
// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. package com.azure.cosmos.examples.springexamples; import com.azure.cosmos.examples.springexamples.common.CouponsUsed; import com.azure.cosmos.examples.springexamples.common.OrderHistory; import com.azure.cosmos.examples.springexamples.common.ShippingPreference; import com.azure.spring.data.cosmos.core.mapping.Container; import com.azure.spring.data.cosmos.core.mapping.PartitionKey; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.List; @Data @NoArgsConstructor @AllArgsConstructor @Container(containerName = "WebCustomer", ru = "400") public class WebCustomer { /** Document ID (required by Azure Cosmos DB). */ private String id; /** WebCustomer ID. */ private String userId; /** WebCustomer last name. */ @PartitionKey private String lastName; /** WebCustomer first name. */ private String firstName; /** WebCustomer email address. */ private String email; /** WebCustomer dividend setting. */ private String dividend; /** WebCustomer shipping preferences. */ private ShippingPreference shippingPreference; /** WebCustomer order history. */ private List<OrderHistory> orderHistory; /** Coupons recorded by the user. */ private List<CouponsUsed> coupons; }
Houd er rekening mee dat de toegangsmethoden voor de velden
id
,userId
en andere velden impliciet zijn (dus niet gedefinieerd in code). Dit gedrag is mogelijk omdat we de annotatie Project Lombok@Data
gebruiken om ze automatisch te maken.Met de annotatie
@NoArgsConstructor
wordt een constructor gegenereerd zonder argumenten voor het instellen van standaard veldwaarden. Met de annotatie@AllArgsConstructor
wordt een andere constructor met een volledige set argumenten gegenereerd om alle veldwaarden rechtstreeks op te geven.Houd er rekening mee dat
WebCustomer
eenid
-eigenschap heeft. Alle Azure Cosmos DB-documenten vereisen eenid
-eigenschap en daarom moeten alle POJO's die we willen serialiseren naar JSON-documenten, eenid
-veld bevatten.Voeg de volgende methode toe aan CosmosSample.java:
/** * Take in list of Java POJOs and insert them into the database. * @param webCustomers List of WebCustomer POJOs to insert. */ private void createWebCustomerDocumentsIfNotExist(final List<WebCustomer> webCustomers) { Flux.fromIterable(webCustomers).flatMap(webCustomer -> { logger.info("Creating WebCustomer {}", webCustomer.getId()); return this.reactiveWebCustomerRepository.save(webCustomer); }).blockLast(); }
Zoek de methode
run
en voeg de volgende code toe aan het einde van die methode.WebCustomer maxaxam = new WebCustomer( "1", "maxaxam", "Axam", "Max", "maxaxam@contoso.com", "2.0", new ShippingPreference( 1, "90 W 8th St", "", "New York", "NY", "10001", "USA" ), new ArrayList<OrderHistory>(Arrays.asList( new OrderHistory( "3", "1000", "08/17/2018", "52.49" ) )), new ArrayList<CouponsUsed>(Arrays.asList( new CouponsUsed( "A7B89F" ) )) ); WebCustomer nelapin = new WebCustomer( "2", "nelapin", "Pindakova", "Nela", "nelapin@contoso.com", "8.50", new ShippingPreference( 1, "505 NW 5th St", "", "New York", "NY", "10001", "USA" ), new ArrayList<OrderHistory>(Arrays.asList( new OrderHistory( "4", "1001", "08/17/2018", "105.89" ) )), new ArrayList<CouponsUsed>(Arrays.asList( new CouponsUsed( "Fall 2018" ) )) ); createWebCustomerDocumentsIfNotExist(new ArrayList(Arrays.asList(maxaxam, nelapin)));
Bouw CosmosSample.java en voer die uit in de IDE, of voer het programma uit in de terminal met behulp van:
mvn clean package mvn spring-boot:run
In de uitvoer van de terminal ziet u
INFO: Creating WebCustomer 1 INFO: Creating WebCustomer 2
Gefeliciteerd U hebt uw eerste gegevens in Azure Cosmos DB gemaakt en/of bijgewerkt vanuit een Java-toepassing. Laat we eens evalueren wat u hier hebt gedaan.
Er zijn drie nieuwe acties in run
:
- Maak of werk het
WebCustomer
-exemplaar van maxaxam bij. - Maak of werk het
WebCustomer
-exemplaar van nelapin bij. - Roep
createWebCustomerDocumentsIfNotExist
aan en geef maxaxam en nelapin door als een lijst.
Met het aanroepen van createWebCustomerDocumentsIfNotExist
worden beide WebCustomer
-instanties als items/documenten toegevoegd aan Azure Cosmos DB. Als u de WebCustomer
-instanties doorgeeft als een lijst, is het onze bedoeling om een performante methode te modelleren om met behulp van een minimum aan rekenresources snel POJO's in Azure Cosmos DB op te nemen. createWebCustomerDocumentsIfNotExist
implementeert efficiënte asynchrone invoeging van een lijst met POJO's. Als een van beide documenten al bestaat, wordt door save
een update uitgevoerd in plaats van dat er een document wordt gemaakt.
Stel dat ons doel is om het aantal aanvragen per seconde per thread te maximaliseren. Ter vergelijking, de synchronisatiebenadering voor het schrijven van createWebCustomerDocumentsIfNotExist
is om elk WebCustomer
-exemplaar te herhalen in webCustomers
. Voor elke WebCustomer
webCustomer
maken we een blokkerende aanroep naar save
:
this.reactiveWebCustomerRepository.save(webCustomer).block(); // <= Note the .block() which loops until request response.
Deze synchronisatiestijl implementeert een intuïtief proces: aanvraag indienen, wachten op antwoord, volgende aanvraag indienen. createWebCustomerDocumentsIfNotExist
gebruikt deze methode echter niet, omdat blokkerende aanroepen in feite CPU-cycli verspillen tijdens de reactietijd van de aanvraag, wat leidt tot een laag aantal aanvragen per seconde.
U kunt deze aanvragen/het tweede probleem omzeilen door meerdere threads te produceren om parallelle aanroepen voor het blokkeren van aanvragen te doen. De meerdere threads zorgen voor een betere uitvoering van de runtime. Maar als het uw doel is zuinig te zijn met threadresources, blijft dit een verspilling. Elke thread wordt opnieuw uitgevoerd tijdens de reactietijd van een aanvraag, terwijl de thread in plaats daarvan meerdere taken had kunnen verwerken voor iets anders, waardoor u per thread maar weinig aanvragen per seconde kunt sturen.
Daarom en omdat we u een threadefficiënte invoeging van Java POJO's willen tonen, hebben we in plaats daarvan een asynchroon voorbeeld van documentinvoeging gegeven. De ondersteuning voor Spring Data is afkomstig van Project Reactor, een Java-toepassingsframework dat een stroomgebaseerd programmeermodel met declaratieve gegevensstromen biedt voor asynchroon, gebeurtenisgestuurd programmeren. Met createWebCustomerDocumentsIfNotExist
wordt de asynchrone programmering van Project Reactor geïmplementeerd.
In createWebCustomerDocumentsIfNotExist
is Flux.fromIterable(webCustomers)
een Project Reactor-factory-methode. Er wordt een Flux
-exemplaar gemaakt dat een bron is van asynchrone gebeurtenissen. In dit geval bevat elke asynchrone gebeurtenis een argument van het WebCustomer
-exemplaar. Het Flux
-exemplaar bevat twee dergelijke gebeurtenissen, één voor maxaxam en één voor nelapin. De code in .flatMap( ... ).blockLast();
definieert een pijplijn van opeenvolgende bewerkingen die moeten worden uitgevoerd voor de gebeurtenissen die worden gegenereerd door het Flux
-exemplaar.
In dit geval zijn de twee bewerkingen in de pijplijn save
-aanroepen. Het idee is dat deze pijplijn bijna identiek is aan de synchrone implementatie, met dit verschil dat de save
-aanroep niet blokkeren. Meer in het bijzonder betekent de aanroep van blockLast()
een abonnement op de geassembleerde pijplijn, waardoor de Flux
de twee eigen gebeurtenissen asynchroon uitvoert. Vervolgens wordt in de pijplijn binnen .flatMap( ... ).blockLast();
elk van deze gebeurtenissen op een pseudo-parallelle manier verwerkt. Wanneer een aanvraag is ingediend en er wordt gewacht op een reactie, verwerkt Project Reactor de andere aanvragen op de achtergrond, wat een essentiële factor is om het aantal aanvragen per seconde per thread te maximaliseren.
Nu we efficiënte asynchrone databaseaanvragen met Project Reactor hebben gedemonstreerd, worden er voor de rest van dit lab blokkerende asynchrone aanroepen (in principe sync-aanroepen) gebruikt om het proces eenvoudig te houden. Voor meer informatie over Project Reactor gaat u naar de handleiding voor Reactor-patronen van Azure Cosmos DB.
Documenten lezen
Als u documenten uit de database wilt lezen, voegt u de volgende methode toe aan
CosmosSample
:/** * Take in a Java POJO argument, extract ID and partition key, and read the corresponding document from the container. * In this case the ID is the partition key. * @param webCustomer User POJO to pull ID and partition key from. */ private WebCustomer readWebCustomerDocument(final WebCustomer webCustomer) { WebCustomer webCustomerResult = null; try { logger.info("Read webCustomer {}", webCustomer.getId()); webCustomerResult = this.reactiveWebCustomerRepository.findById(webCustomer.getId(), new PartitionKey(webCustomer.getLastName())).block(); } catch (CosmosException de) { logger.error("Failed to read webCustomer {}", webCustomer.getId(), de); } return webCustomer; }
Kopieer en plak de volgende code aan het eind van de methode
run
, na de code voor het maken van het document:readWebCustomerDocument(maxaxam);
Bouw CosmosSample.java en voer die uit in de IDE, of voer het programma uit in de terminal met behulp van:
mvn clean package mvn spring-boot:run
In de uitvoer van de terminal ziet u het volgende. 'Gebruiker 1 gelezen' geeft aan dat het document is opgehaald.
INFO: Read webCustomer 1
Documenten verwijderen
Kopieer en plak de
deleteWebCustomerDocument
-methode onder uwreadWebCustomerDocument
-methode./** * Take in a Java POJO argument, extract ID and partition key, * and delete the corresponding document. * @param webCustomer User POJO representing the document update. */ private void deleteWebCustomerDocument(final WebCustomer webCustomer) { try { this.reactiveWebCustomerRepository.deleteById(webCustomer.getId(),new PartitionKey(webCustomer.getLastName())).block(); logger.info("Deleted webCustomer {}", webCustomer.getId()); } catch (CosmosException de) { logger.error("User {} could not be deleted.", webCustomer.getId()); } }
Kopieer en plak de volgende code aan het eind van de methode
run
.deleteWebCustomerDocument(maxaxam);
Bouw CosmosSample.java en voer die uit in de IDE, of voer het programma uit in de terminal met behulp van:
mvn clean package mvn spring-boot:run
In de uitvoer van de terminal ziet u het volgende. 'Gebruiker 1 verwijderd' geeft aan dat het document is verwijderd.
INFO: Deleted webCustomer 1
In deze les hebt u documenten gemaakt, bijgewerkt, gelezen en verwijderd in uw Azure Cosmos DB-database.