Migrieren einer Anwendung für die Verwendung des Azure Cosmos DB Java SDK V4

GILT FÜR: NoSQL

Wichtig

Weitere Informationen zu diesem SDK finden Sie in den Versionshinweisen zu Azure Cosmos DB Java SDK V4, im Maven-Repository, in den Tipps zur Leistungssteigerung für Azure Cosmos DB Java SDK V4 und im Leitfaden zur Problembehandlung für Azure Cosmos DB Java SDK V4.

Wichtig

Da Azure Cosmos DB Java SDK v4 über einen um bis zu 20 % höheren Durchsatz, einen TCP-basierten direkten Modus und Unterstützung für die neuesten Back-End-Dienstfeatures verfügt, empfehlen wir Ihnen, bei der nächsten Gelegenheit ein Upgrade auf v4 durchzuführen. Lesen Sie weiter, um mehr zu erfahren.

Aktualisieren Sie auf das neueste Azure Cosmos DB Java SDK, um das Beste zu nutzen, was Azure Cosmos DB zu bieten hat – einen verwalteten, nicht relationalen Datenbankdienst mit wettbewerbsfähiger Leistung, einer Verfügbarkeit von fünf Neunen, einzigartiger Ressourcenkontrolle und mehr. In diesem Artikel wird erläutert, wie Sie Ihre vorhandene Java-Anwendung von der Verwendung der älteren Azure Cosmos DB Java SDKs auf das neuere Azure Cosmos DB Java SDK 4.0 für die API für NoSQL aktualisieren. Azure Cosmos DB Java SDK V4 entspricht dem Paket com.azure.cosmos. Sie können die Anweisungen in diesem Dokument verwenden, wenn Sie Ihre Anwendung von einer der folgenden Azure Cosmos DB Java SDKs migrieren:

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

Zuordnungen von Azure Cosmos DB Java SDK und Paket

In der folgenden Tabelle werden verschiedene Azure Cosmos DB Java SDKs, der Paketname und die Veröffentlichungsinformationen aufgeführt:

Java-SDK Veröffentlichungsdatum Gebündelte APIs Maven-JAR Java-Paketname API-Referenz Versionsinformationen Datum der Außerbetriebnahme
Async 2.x.x Juni 2018 Async(RxJava) com.microsoft.azure::azure-cosmosdb com.microsoft.azure.cosmosdb.rx API Versionsanmerkungen 31. August 2024
Sync 2.x.x September 2018 Synchronisierung com.microsoft.azure::azure-documentdb com.microsoft.azure.cosmosdb API 29. Februar 2024
3.x.x Juli 2019 Async(Reactor)/Sync com.microsoft.azure::azure-cosmos com.azure.data.cosmos API - 31. August 2024
4,0 Juni 2020 Async(Reactor)/Sync com.azure::azure-cosmos com.azure.cosmos API - -

Änderungen an der Implementierung auf SDK-Ebene

Im Folgenden finden Sie die wichtigsten Unterschiede bei der Implementierung zwischen verschiedenen SDKs:

RxJava wurde in Azure Cosmos DB Java SDK-Versionen 3.x.x und 4.0 durch Reactor ersetzt

Wenn Sie mit der asynchronen oder reaktiven Programmierung nicht vertraut sind, finden Sie im Einführungsleitfaden zu Reactor-Mustern eine Einführung in die asynchrone Programmierung und Projekt Reactor. Dieser Leitfaden ist möglicherweise hilfreich, wenn Sie in der Vergangenheit Azure Cosmos DB Sync Java SDK 2.x.x oder Azure Cosmos DB Java SDK 3.x.x Sync API verwendet haben.

Wenn Sie Azure Cosmos DB Async Java SDK 2.x.x verwendet haben und eine Migration zum 4.0 SDK beabsichtigen, finden Sie in der Gegenüberstellung von Reactor und RxJava Empfehlungen für die Konvertierung von RxJava-Code zur Verwendung von Reactor.

Azure Cosmos DB Java SDK V4 verfügt in asynchronen und synchronen APIs über einen Modus für die direkte Konnektivität

Wenn Sie Azure Cosmos DB Sync Java SDK 2.x.x, ist der Modus für die direkte Konnektivität auf Basis von TCP (im Gegensatz zu HTTP) in Azure Cosmos DB Java SDK 4.0 für asynchrone und synchrone APIs implementiert.

Änderungen auf API-Ebene

Im Folgenden sind die Änderungen auf API-Ebene in Azure Cosmos DB Java SDK 4.x.x im Vergleich zu früheren SDKs (Java SDK 3.x.x, Async Java SDK 2.x.x, und Sync Java SDK 2.x.x) aufgeführt:

Azure Cosmos DB Java SDK naming conventions

  • Im Azure Cosmos DB Java SDK 3.x.x und 4.0 werden die Clientressourcen als Cosmos<resourceName> bezeichnet. Beispiel: CosmosClient, CosmosDatabase, CosmosContainer. In Version 2.x.x verfügen die Azure Cosmos DB Java SDKs jedoch nicht über ein einheitliches Benennungsschema.

  • Azure Cosmos DB Java SDK 3.x.x und 4.0 bieten synchrone und asynchrone APIs.

    • Java SDK 4.0 : Alle Klassen gehören zur synchronen API, sofern dem Klassennamen kein Async nach Cosmos nachgestellt ist.

    • Java SDK 3.x.x: Alle Klassen gehören zur asynchronen API, sofern dem Klassennamen kein Async nach Cosmos nachgestellt ist.

    • Async Java SDK 2.x.x: Die Klassennamen ähneln dem Sync Java SDK 2.x.x, der Name beginnt jedoch mit Async.

Hierarchische API-Struktur

Azure Cosmos DB Java SDK 4.0 und 3.x.x enthalten erstmals eine hierarchische API-Struktur, in der Clients, Datenbanken und Container verschachtelt angeordnet sind, wie der folgende Codeausschnitt für das 4.0-SDK veranschaulicht:

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

In Version 2.x.x des Azure Cosmos DB Java SDK werden alle Vorgänge für Ressourcen und Dokumente über die Clientinstanz durchgeführt.

Darstellen von Dokumenten

Im Azure Cosmos DB Java SDK 4.0 stellen benutzerdefinierte POJOs und JsonNodes die beiden Optionen zum Lesen und Schreiben der Dokumente aus Azure Cosmos DB dar.

Im Azure Cosmos DB Java SDK 3.x.x wird das CosmosItemProperties-Objekt von der öffentlichen API verfügbar gemacht und als Dokumentdarstellung bereitgestellt. Diese Klasse wird in Version 4.0 nicht mehr öffentlich verfügbar gemacht.

Importe

  • Die Pakete des Azure Cosmos DB Java SDK 4.0 beginnen mit com.azure.cosmos.

  • Pakete des Azure Cosmos DB Java SDK 3.x.x beginnen mit com.azure.data.cosmos.

  • Pakete der Sync-API des Azure Cosmos DB Java SDK 2.x.x beginnen mit com.microsoft.azure.documentdb.

  • Azure Cosmos DB Java SDK 4.0 platziert mehrere Klassen in das verschachtelte Paket com.azure.cosmos.models. Einige dieser Pakete lauten wie folgt:

    • CosmosContainerResponse
    • CosmosDatabaseResponse
    • CosmosItemResponse
    • Die Async API enthält Entsprechungen für alle oben aufgeführten Pakete.
    • CosmosContainerProperties
    • FeedOptions
    • PartitionKey
    • IndexingPolicy
    • IndexingMode usw.

Accessoren

Azure Cosmos DB Java SDK 4.0 macht get- und set-Methoden für den Zugriff auf Instanzelemente verfügbar. Beispielsweise verfügt die CosmosContainer-Instanz über die Methoden container.getId() und container.setId().

Damit unterscheidet es sich vom Azure Cosmos DB Java SDK 3.x.x, das eine Fluent-Schnittstelle verfügbar macht. Beispielsweise verfügt eine CosmosSyncContainer-Instanz über container.id(), die zum Abrufen und Festlegen des id-Werts überladen wird.

Vergleich von Codeausschnitten

Erstellen von Ressourcen

Der folgende Codeausschnitt zeigt die Unterschiede bei der Erstellung von Ressourcen zwischen den Async APIs 4.0 und 3.x.x, der 2.x.x Sync API und der 2.x.x Async API:


// 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();

Elementvorgänge

Der folgende Codeausschnitt zeigt die Unterschiede bei der Ausführung von Elementvorgängen zwischen den Async APIs 4.0 und 3.x.x, der 2.x.x Sync API und der 2.x.x Async API:


// 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.

Indizierung

Der folgende Codeausschnitt zeigt die Unterschiede bei der Indizierungserstellung zwischen den Async APIs 4.0 und 3.x.x, der 2.x.x Sync API und der 2.x.x Async API:


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);

Gespeicherte Prozeduren

Der folgende Codeausschnitt zeigt die Unterschiede bei der Erstellung gespeicherter Prozeduren zwischen den Async APIs 4.0 und 3.x.x, der 2.x.x Sync API und der 2.x.x Async API:


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();

Änderungsfeed

Der folgende Codeausschnitt zeigt die Unterschiede bei der Ausführung von Änderungsfeedvorgängen zwischen den Async APIs 4.0 und 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();

Gültigkeitsdauer (TTL) auf Containerebene

Der folgende Codeausschnitt zeigt die Unterschiede beim Erstellen einer Gültigkeitsdauer für Daten im Container zwischen den Async APIs 4.0 und 3.x.x, der 2.x.x Sync API und der 2.x.x Async API:


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");

Gültigkeitsdauer (TTL) auf Elementebene

Der folgende Codeausschnitt zeigt die Unterschiede beim Erstellen einer Gültigkeitsdauer für ein Element zwischen den Async APIs 4.0 und 3.x.x, der 2.x.x Sync API und der 2.x.x Async API:


// 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
);

Nächste Schritte