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:
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
nachCosmos
nachgestellt ist.Java SDK 3.x.x: Alle Klassen gehören zur asynchronen API, sofern dem Klassennamen kein
Async
nachCosmos
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.
Verwalten von Abhängigkeitskonflikten
Durch das Upgrade des Azure Cosmos DB Java SDK V2 auf V4 können Abhängigkeitskonflikte aufgrund von Änderungen in den vom SDK verwendeten Bibliotheken auftreten. Die Lösung dieser Konflikte erfordert eine sorgfältige Verwaltung der Abhängigkeiten.
Verstehen der neuen Abhängigkeiten: Das Azure Cosmos DB V4 SDK verfügt über einen eigenen Satz von Abhängigkeiten, die sich von denen in früheren Versionen unterscheiden können. Stellen Sie sicher, dass Sie diese Abhängigkeiten kennen:
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
Entfernen der in Konflikt stehenden Abhängigkeiten: Entfernen Sie zunächst die Abhängigkeiten im Zusammenhang mit früheren Versionen des SDK aus der Datei
pom.xml
. Dazu gehörenazure-cosmosdb
und alle transitiven Abhängigkeiten, die möglicherweise im alten SDK enthalten waren.Hinzufügen von V4 SDK-Abhängigkeiten: Fügen Sie das V4 SDK und dessen Abhängigkeiten zu
pom.xml
hinzu. Ein Beispiel:<dependency> <groupId>com.azure</groupId> <artifactId>azure-cosmos</artifactId> <version>4.x.x</version> <!-- Use the latest version available --> </dependency>
Suchen nach Abhängigkeitskonflikten: Verwenden Sie den Maven-Befehl
dependency:tree
, um eine Abhängigkeitenstruktur zu generieren und Konflikte zu identifizieren. Führen Sie Folgendes aus:mvn dependency:tree
Suchen Sie nach allen in Konflikt stehenden Versionen von Abhängigkeiten. Diese Konflikte treten häufig bei Bibliotheken wie
reactor-core
,netty-handler
,guava
undjackson
auf.Verwenden der Abhängigkeitsverwaltung: Wenn Versionskonflikte auftreten, müssen Sie möglicherweise problematische Versionen im Abschnitt
<dependencyManagement>
vonpom.xml
überschreiben. Hier sehen Sie ein Beispiel zum Erzwingen einer bestimmten Version vonreactor-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>
Ausschließen transitiver Abhängigkeiten: Manchmal müssen Sie transitive Abhängigkeiten ausschließen, die von anderen Abhängigkeiten eingeführt werden. Wenn beispielsweise eine andere Bibliothek eine ältere Version einer Abhängigkeit einführt, die einen Konflikt auslöst, können Sie sie wie folgt ausschließen:
<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>
Neuerstellen und Testen: Erstellen Sie nach dem Vornehmen dieser Änderungen Ihr Projekt neu, und testen Sie es gründlich, um sicherzustellen, dass die neuen Abhängigkeiten ordnungsgemäß funktionieren und keine Laufzeitkonflikte auftreten.
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
- Erstellen einer Java-App zum Verwalten von Azure Cosmos DB for NoSQL mit dem V4-SDK
- Weitere Informationen über Reactor-basierte Java-SDKs
- Weitere Informationen über die Konvertierung von asynchronem RxJava-Code in asynchronen Reactor-Code mit der Gegenüberstellung von Reactor und RxJava
- Versuchen Sie, die Kapazitätsplanung für eine Migration zu Azure Cosmos DB durchzuführen?
- Wenn Sie nur die Anzahl der virtuellen Kerne und Server in Ihrem vorhandenen Datenbankcluster kennen, lesen Sie die Informationen zum Schätzen von Anforderungseinheiten mithilfe von virtuellen Kernen oder virtuellen CPUs
- Wenn Sie die typischen Anforderungsraten für Ihre aktuelle Datenbankworkload kennen, lesen Sie die Informationen zum Schätzen von Anforderungseinheiten mit dem Azure Cosmos DB-Kapazitätsplaner