Delen via


Uw toepassing migreren om de Azure Cosmos DB Java SDK v4 te gebruiken

VAN TOEPASSING OP: NoSQL

Belangrijk

Raadpleeg de releaseopmerkingen voor Azure Cosmos DB Java SDK v4, Maven-opslagplaats, Azure Cosmos DB Java SDK v4-prestatietips en probleemoplossingsgids voor Azure Cosmos DB Java SDK v4 voor meer informatie over deze SDK.

Belangrijk

Omdat Azure Cosmos DB Java SDK v4 maximaal 20% verbeterde doorvoer, directe tcp-modus en ondersteuning heeft voor de nieuwste functies van de back-endservice, raden we u aan om bij de volgende gelegenheid een upgrade naar v4 uit te voeren. Lees hieronder verder voor meer informatie.

Werk bij naar de nieuwste Azure Cosmos DB Java SDK om optimaal te kunnen werken met wat Azure Cosmos DB te bieden heeft: een beheerde niet-relationele databaseservice met concurrerende prestaties, beschikbaarheid van vijf negens, een-op-een-soort resourcebeheer en meer. In dit artikel wordt uitgelegd hoe u een upgrade uitvoert van uw bestaande Java-toepassing die gebruikmaakt van een oudere Azure Cosmos DB Java SDK naar de nieuwere Azure Cosmos DB Java SDK 4.0 voor API voor NoSQL. Azure Cosmos DB Java SDK v4 komt overeen met het com.azure.cosmos pakket. U kunt de instructies in dit document gebruiken als u uw toepassing migreert vanuit een van de volgende Azure Cosmos DB Java SDK's:

  • Java SDK 2.x.x synchroniseren
  • Async Java SDK 2.x.x
  • Java SDK 3.x.x

Azure Cosmos DB Java SDK's en pakkettoewijzingen

De volgende tabel bevat verschillende Azure Cosmos DB Java SDK's, de pakketnaam en de release-informatie:

Java-SDK Releasedatum Gebundelde API's Maven Jar Naam van Java-pakket API-verwijzing Opmerkingen bij de release Datum buiten gebruik stellen
Async 2.x.x 2018 juni Async(RxJava) com.microsoft.azure::azure-cosmosdb com.microsoft.azure.cosmosdb.rx API Releaseopmerkingen zaterdag 31 augustus 2024
Sync 2.x.x September 2018 Synchroniseren com.microsoft.azure::azure-documentdb com.microsoft.azure.cosmosdb API donderdag 29 februari 2024
3.x.x Juli 2019 Async(Reactor)/Sync com.microsoft.azure::azure-cosmos com.azure.data.cosmos API - zaterdag 31 augustus 2024
4.0 Juni 2020 Async(Reactor)/Sync com.azure::azure-cosmos com.azure.cosmos API - -

Implementatiewijzigingen op SDK-niveau

Hier volgen de belangrijkste verschillen in implementatie tussen verschillende SDK's:

RxJava wordt vervangen door reactor in Azure Cosmos DB Java SDK-versies 3.x.x en 4.0

Als u niet bekend bent met asynchrone programmering of reactief programmeren, raadpleegt u de reactorpatroonhandleiding voor een inleiding tot asynchrone programmering en Project Reactor. Deze handleiding kan nuttig zijn als u in het verleden Azure Cosmos DB Sync Java SDK 2.x.x of Azure Cosmos DB Java SDK 3.x.x Sync-API hebt gebruikt.

Als u Azure Cosmos DB Async Java SDK 2.x.x hebt gebruikt en u van plan bent om te migreren naar de 4.0 SDK, raadpleegt u de Reactor vs RxJava Guide voor hulp bij het converteren van RxJava-code voor het gebruik van Reactor.

Azure Cosmos DB Java SDK v4 heeft de directe connectiviteitsmodus in zowel Async- als synchronisatie-API's

Als u Azure Cosmos DB Sync Java SDK 2.x.x hebt gebruikt, moet u er rekening mee houden dat de directe verbindingsmodus op basis van TCP (in tegenstelling tot HTTP) is geïmplementeerd in Azure Cosmos DB Java SDK 4.0 voor zowel de Async- als synchronisatie-API's.

Wijzigingen op API-niveau

Hier volgen de wijzigingen op API-niveau in Azure Cosmos DB Java SDK 4.x.x vergeleken met eerdere SDK's (Java SDK 3.x.x, Async Java SDK 2.x.x en Sync Java SDK 2.x.x):

Naamconventies voor Azure Cosmos DB Java SDK

  • De Azure Cosmos DB Java SDK 3.x.x en 4.0 verwijzen naar de clientbronnen als Cosmos<resourceName>. Bijvoorbeeld, CosmosClient, CosmosDatabase. CosmosContainer In versie 2.x.x hebben de Java SDK's van Azure Cosmos DB geen uniform naamgevingsschema.

  • Azure Cosmos DB Java SDK 3.x.x en 4.0 bieden zowel Sync- als Async-API's.

    • Java SDK 4.0: alle klassen behoren tot de synchronisatie-API, tenzij de klassenaam erna Cosmoswordt toegevoegdAsync.

    • Java SDK 3.x.x: alle klassen behoren tot de Async-API, tenzij de klassenaam erna Cosmoswordt toegevoegdAsync.

    • Async Java SDK 2.x.x: de klassenamen zijn vergelijkbaar met Sync Java SDK 2.x.x, maar de naam begint met Async.

Hiërarchische API-structuur

Azure Cosmos DB Java SDK 4.0 en 3.x.x introduceert een hiërarchische API-structuur die de clients, databases en containers op geneste wijze ordent, zoals wordt weergegeven in het volgende codefragment van de 4.0 SDK:

CosmosContainer container = client.getDatabase("MyDatabaseName").getContainer("MyContainerName");

In versie 2.x.x van de Azure Cosmos DB Java SDK worden alle bewerkingen op resources en documenten uitgevoerd via het clientexemplaren.

Documenten vertegenwoordigen

In Azure Cosmos DB Java SDK 4.0 zijn aangepaste POJO's en JsonNodes zijn de twee opties voor het lezen en schrijven van de documenten uit Azure Cosmos DB.

In de Azure Cosmos DB Java SDK 3.x.x wordt het CosmosItemProperties object weergegeven door de openbare API en als documentweergave geleverd. Deze klasse wordt niet meer openbaar weergegeven in versie 4.0.

Imports

  • De Azure Cosmos DB Java SDK 4.0-pakketten beginnen met com.azure.cosmos

  • Azure Cosmos DB Java SDK 3.x.x-pakketten beginnen met com.azure.data.cosmos

  • Azure Cosmos DB Java SDK 2.x.x Sync API-pakketten beginnen met com.microsoft.azure.documentdb

  • Azure Cosmos DB Java SDK 4.0 plaatst verschillende klassen in een genest pakket com.azure.cosmos.models. Enkele van deze pakketten zijn:

    • CosmosContainerResponse
    • CosmosDatabaseResponse
    • CosmosItemResponse
    • De Asynchrone API-analogen voor alle bovenstaande pakketten
    • CosmosContainerProperties
    • FeedOptions
    • PartitionKey
    • IndexingPolicy
    • IndexingMode ... enz.

Accessors

Azure Cosmos DB Java SDK 4.0 bevat get en set methoden voor toegang tot de leden van het exemplaar. Het exemplaar heeft container.getId() bijvoorbeeld CosmosContainer en container.setId() methoden.

Dit verschilt van Azure Cosmos DB Java SDK 3.x.x, waarmee een fluent-interface wordt weergegeven. Een exemplaar heeft container.id() bijvoorbeeld CosmosSyncContainer overbelast om de waarde op te halen of in id te stellen.

Afhankelijkheidsconflicten beheren

Als u een upgrade uitvoert van Azure Cosmos DB Java SDK V2 naar V4, kunnen afhankelijkheidsconflicten ontstaan vanwege wijzigingen in de bibliotheken die door de SDK worden gebruikt. Voor het oplossen van deze conflicten is zorgvuldig beheer van de afhankelijkheden vereist.

  1. Inzicht in de nieuwe afhankelijkheden: de Azure Cosmos DB V4 SDK heeft een eigen set afhankelijkheden die mogelijk afwijken van die in eerdere versies. Zorg ervoor dat u op de hoogte bent van deze afhankelijkheden:

    • azure-cosmos
    • reactor-core
    • reactor-netty
    • netty-handler
    • guava
    • slf4j-api
    • jackson-databind
    • jackson-annotations
    • jackson-core
    • commons-lang3
    • commons-collections4
    • azure-core
    • azure-core-http-netty
  2. Conflicterende afhankelijkheden verwijderen: verwijder eerst de afhankelijkheden die betrekking hebben op eerdere versies van de SDK uit uw pom.xml bestand. Deze omvatten azure-cosmosdb en eventuele transitieve afhankelijkheden die de oude SDK mogelijk had gehad.

  3. V4 SDK-afhankelijkheden toevoegen: voeg de V4 SDK en de bijbehorende afhankelijkheden toe aan uw pom.xml. Hier volgt een voorbeeld:

    <dependency>
        <groupId>com.azure</groupId>
        <artifactId>azure-cosmos</artifactId>
        <version>4.x.x</version> <!-- Use the latest version available -->
    </dependency>
    
  4. Controleer op afhankelijkheidsconflicten: gebruik de Maven-opdracht dependency:tree om een afhankelijkheidsstructuur te genereren en eventuele conflicten te identificeren. Run:

    mvn dependency:tree
    

    Zoek naar conflicterende versies van afhankelijkheden. Deze conflicten treden vaak op met bibliotheken zoals reactor-core, netty-handler, guavaen jackson.

  5. Gebruik Afhankelijkheidsbeheer: als er versieconflicten optreden, moet u mogelijk problematische versies overschrijven met behulp van de <dependencyManagement> sectie in uw pom.xml. Hier volgt een voorbeeld voor het afdwingen van een specifieke versie van reactor-core:

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.projectreactor</groupId>
                <artifactId>reactor-core</artifactId>
                <version>3.x.x</version> <!-- Use a compatible version -->
            </dependency>
            <!-- Repeat for any other conflicting dependencies -->
        </dependencies>
    </dependencyManagement>
    
  6. Transitieve afhankelijkheden uitsluiten: Soms moet u transitieve afhankelijkheden uitsluiten die door andere afhankelijkheden worden gebracht. Als een andere bibliotheek bijvoorbeeld een oudere versie van een afhankelijkheid bevat die conflicteert, kunt u deze als volgt uitsluiten:

    <dependency>
        <groupId>some.group</groupId>
        <artifactId>some-artifact</artifactId>
        <version>x.x.x</version>
        <exclusions>
            <exclusion>
                <groupId>conflicting.group</groupId>
                <artifactId>conflicting-artifact</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    
  7. Opnieuw bouwen en testen: Nadat u deze wijzigingen hebt aangebracht, bouwt u het project opnieuw en test u het grondig om ervoor te zorgen dat de nieuwe afhankelijkheden correct werken en dat er geen runtimeconflicten optreden.

Vergelijkingen van codefragmenten

Resources maken

In het volgende codefragment ziet u de verschillen in de manier waarop resources worden gemaakt tussen de Async-API's 4.0, 3.x.x Async, 2.x.x Sync en 2.x.x:


// Create Async client.
// Building an async client is still a sync operation.
CosmosAsyncClient client = new CosmosClientBuilder()
        .endpoint("your.hostname")
        .key("yourmasterkey")
        .consistencyLevel(ConsistencyLevel.EVENTUAL)
        .buildAsyncClient();

// Create database with specified name
client.createDatabaseIfNotExists("YourDatabaseName")
        .flatMap(databaseResponse -> {
            testDatabaseAsync = client.getDatabase("YourDatabaseName");
            // Container properties - name and partition key
            CosmosContainerProperties containerProperties =
                    new CosmosContainerProperties("YourContainerName", "/id");

            // Provision manual throughput
            ThroughputProperties throughputProperties = ThroughputProperties.createManualThroughput(400);

            // Create container
            return database.createContainerIfNotExists(containerProperties, throughputProperties);
        }).flatMap(containerResponse -> {
    testContainerAsync = database.getContainer("YourContainerName");
    return Mono.empty();
}).subscribe();

Itembewerkingen

In het volgende codefragment ziet u de verschillen in de manier waarop itembewerkingen worden uitgevoerd tussen de Async-API's 4.0, 3.x.x Async, 2.x.x Sync en 2.x.x:


// Container is created. Generate many docs to insert.
int number_of_docs = 50000;
ArrayList<JsonNode> docs = generateManyDocs(number_of_docs);

// Insert many docs into container...
Flux.fromIterable(docs)
        .flatMap(doc -> testContainerAsync.createItem(doc))
        .subscribe(); // ...Subscribing triggers stream execution.

Indexeren

In het volgende codefragment ziet u de verschillen in de manier waarop indexering wordt gemaakt tussen de Async-API's 4.0, 3.x.x Async, 2.x.x Sync en 2.x.x:


CosmosContainerProperties containerProperties = new CosmosContainerProperties(containerName, "/lastName");

// Custom indexing policy
IndexingPolicy indexingPolicy = new IndexingPolicy();
indexingPolicy.setIndexingMode(IndexingMode.CONSISTENT);

// Included paths
List<IncludedPath> includedPaths = new ArrayList<>();
includedPaths.add(new IncludedPath("/*"));
indexingPolicy.setIncludedPaths(includedPaths);

// Excluded paths
List<ExcludedPath> excludedPaths = new ArrayList<>();
excludedPaths.add(new ExcludedPath("/name/*"));
indexingPolicy.setExcludedPaths(excludedPaths);

containerProperties.setIndexingPolicy(indexingPolicy);

ThroughputProperties throughputProperties = ThroughputProperties.createManualThroughput(400);

database.createContainerIfNotExists(containerProperties, throughputProperties);
CosmosAsyncContainer containerIfNotExists = database.getContainer(containerName);

Opgeslagen procedures

In het volgende codefragment ziet u de verschillen in hoe opgeslagen procedures worden gemaakt tussen de Async-API's 4.0, 3.x.x Async, 2.x.x Sync en 2.x.x:


logger.info("Creating stored procedure...\n");

String sprocId = "createMyDocument";

String sprocBody = "function createMyDocument() {\n" +
        "var documentToCreate = {\"id\":\"test_doc\"}\n" +
        "var context = getContext();\n" +
        "var collection = context.getCollection();\n" +
        "var accepted = collection.createDocument(collection.getSelfLink(), documentToCreate,\n" +
        "    function (err, documentCreated) {\n" +
        "if (err) throw new Error('Error' + err.message);\n" +
        "context.getResponse().setBody(documentCreated.id)\n" +
        "});\n" +
        "if (!accepted) return;\n" +
        "}";

CosmosStoredProcedureProperties storedProcedureDef = new CosmosStoredProcedureProperties(sprocId, sprocBody);
container.getScripts()
        .createStoredProcedure(storedProcedureDef,
                new CosmosStoredProcedureRequestOptions()).block();

// ...

logger.info(String.format("Executing stored procedure %s...\n\n", sprocId));

CosmosStoredProcedureRequestOptions options = new CosmosStoredProcedureRequestOptions();
options.setPartitionKey(new PartitionKey("test_doc"));

container.getScripts()
        .getStoredProcedure(sprocId)
        .execute(null, options)
        .flatMap(executeResponse -> {
            logger.info(String.format("Stored procedure %s returned %s (HTTP %d), at cost %.3f RU.\n",
                    sprocId,
                    executeResponse.getResponseAsString(),
                    executeResponse.getStatusCode(),
                    executeResponse.getRequestCharge()));
            return Mono.empty();
        }).block();

Feed wijzigen

In het volgende codefragment ziet u de verschillen in hoe wijzigingenfeedbewerkingen worden uitgevoerd tussen de Async-API's 4.0 en 3.x.x:


ChangeFeedProcessor changeFeedProcessorInstance =
        new ChangeFeedProcessorBuilder()
                .hostName(hostName)
                .feedContainer(feedContainer)
                .leaseContainer(leaseContainer)
                .handleChanges((List<JsonNode> docs) -> {
                    logger.info("--->setHandleChanges() START");

                    for (JsonNode document : docs) {
                        try {
                            //Change Feed hands the document to you in the form of a JsonNode
                            //As a developer you have two options for handling the JsonNode document provided to you by Change Feed
                            //One option is to operate on the document in the form of a JsonNode, as shown below. This is great
                            //especially if you do not have a single uniform data model for all documents.
                            logger.info("---->DOCUMENT RECEIVED: " + OBJECT_MAPPER.writerWithDefaultPrettyPrinter()
                                    .writeValueAsString(document));

                            //You can also transform the JsonNode to a POJO having the same structure as the JsonNode,
                            //as shown below. Then you can operate on the POJO.
                            CustomPOJO pojo_doc = OBJECT_MAPPER.treeToValue(document, CustomPOJO.class);
                            logger.info("----=>id: " + pojo_doc.getId());

                        } catch (JsonProcessingException e) {
                            e.printStackTrace();
                        }
                    }
                    logger.info("--->handleChanges() END");

                })
                .buildChangeFeedProcessor();

// ...

changeFeedProcessorInstance.start()
        .subscribeOn(Schedulers.elastic())
        .subscribe();

Time-To-Live (TTL) op containerniveau

In het volgende codefragment ziet u de verschillen in het maken van time to live voor gegevens in de container tussen de ASYNC-API's 4.0, 3.x.x Async, 2.x.x Sync en 2.x.x:


CosmosAsyncContainer container;

// Create a new container with TTL enabled with default expiration value
CosmosContainerProperties containerProperties = new CosmosContainerProperties("myContainer", "/myPartitionKey");
containerProperties.setDefaultTimeToLiveInSeconds(90 * 60 * 60 * 24);
ThroughputProperties throughputProperties = ThroughputProperties.createManualThroughput(400);
database.createContainerIfNotExists(containerProperties, throughputProperties).block();
container = database.getContainer("myContainer");

Time-to-live(TTL) op itemniveau

In het volgende codefragment ziet u de verschillen in het maken van time to live voor een item tussen de Async-API's 4.0, 3.x.x Async, 2.x.x Sync en 2.x.x:


// Include a property that serializes to "ttl" in JSON
class SalesOrder
{
    private String id;
    private String customerId;
    private Integer ttl;

    public SalesOrder(String id, String customerId, Integer ttl) {
        this.id = id;
        this.customerId = customerId;
        this.ttl = ttl;
    }

    public String getId() {return this.id;}
    public void setId(String new_id) {this.id = new_id;}
    public String getCustomerId() {return this.customerId;}
    public void setCustomerId(String new_cid) {this.customerId = new_cid;}
    public Integer getTtl() {return this.ttl;}
    public void setTtl(Integer new_ttl) {this.ttl = new_ttl;}

    //...
}


// Set the value to the expiration in seconds
SalesOrder salesOrder = new SalesOrder(
        "SO05",
        "CO18009186470",
        60 * 60 * 24 * 30  // Expire sales orders in 30 days
);

Volgende stappen