Migrera ditt program för att använda Azure Cosmos DB Java SDK v4
GÄLLER FÖR: NoSQL
Viktigt!
Mer information om denna SDK finns i Azure Cosmos DB Java SDK v4 Viktig information, Maven-lagringsplats, Azure Cosmos DB Java SDK v4-prestandatips och Felsökningsguide för Azure Cosmos DB Java SDK v4.
Viktigt!
Eftersom Azure Cosmos DB Java SDK v4 har upp till 20 % förbättrat dataflöde, TCP-baserat direktläge och stöd för de senaste funktionerna i serverdelstjänsten rekommenderar vi att du uppgraderar till v4 vid nästa tillfälle. Fortsätt läsa nedan om du vill veta mer.
Uppdatera till den senaste Azure Cosmos DB Java SDK för att få ut det bästa av vad Azure Cosmos DB har att erbjuda – en hanterad icke-relationell databastjänst med konkurrenskraftiga prestanda, femnios tillgänglighet, unik resursstyrning med mera. Den här artikeln beskriver hur du uppgraderar ditt befintliga Java-program som använder en äldre Azure Cosmos DB Java SDK till nyare Azure Cosmos DB Java SDK 4.0 för API för NoSQL. Azure Cosmos DB Java SDK v4 motsvarar com.azure.cosmos
paketet. Du kan använda anvisningarna i det här dokumentet om du migrerar ditt program från någon av följande Azure Cosmos DB Java SDK:er:
- Synkronisera Java SDK 2.x.x
- Async Java SDK 2.x.x
- Java SDK 3.x.x
Azure Cosmos DB Java SDK:s och paketmappningar
I följande tabell visas olika Java-SDK:er för Azure Cosmos DB, paketnamnet och versionsinformationen:
Java SDK | Utgivningsdatum | Paketerade API:er | Maven Jar | Java-paketnamn | API-referens | Viktig information | Datum för borttagning |
---|---|---|---|---|---|---|---|
Async 2.x.x | 2018 juni | Async(RxJava) | com.microsoft.azure::azure-cosmosdb |
com.microsoft.azure.cosmosdb.rx |
API | Viktig information | 31 augusti 2024 |
Synkronisera 2.x.x | Sept 2018 | Synkronisera | com.microsoft.azure::azure-documentdb |
com.microsoft.azure.cosmosdb |
API | 29 februari 2024 | |
3.x.x | Juli 2019 | Async(Reactor)/Sync | com.microsoft.azure::azure-cosmos |
com.azure.data.cosmos |
API | - | 31 augusti 2024 |
4.0 | Juni 2020 | Async(Reactor)/Sync | com.azure::azure-cosmos |
com.azure.cosmos |
API | - | - |
Implementeringsändringar på SDK-nivå
Följande är de viktigaste implementeringsskillnaderna mellan olika SDK:er:
RxJava ersätts med reaktor i Azure Cosmos DB Java SDK version 3.x.x och 4.0
Om du inte känner till asynkron programmering eller reaktiv programmering kan du läsa Reaktormönsterguiden för en introduktion till asynkron programmering och Project Reactor. Den här guiden kan vara användbar om du tidigare har använt Azure Cosmos DB Sync Java SDK 2.x.x eller Azure Cosmos DB Java SDK 3.x.x Sync API.
Om du har använt Azure Cosmos DB Async Java SDK 2.x.x och planerar att migrera till 4.0 SDK kan du läsa guiden Reactor vs RxJava (Reaktor vs RxJava) för vägledning om hur du konverterar RxJava-kod till att använda Reactor.
Azure Cosmos DB Java SDK v4 har direktanslutningsläge i både Async- och Sync-API:er
Om du har använt Azure Cosmos DB Sync Java SDK 2.x.x bör du tänka på att direktanslutningsläget baserat på TCP (i stället för HTTP) implementeras i Azure Cosmos DB Java SDK 4.0 för både Async- och Sync-API:erna.
Ändringar på API-nivå
Följande är ändringar på API-nivå i Azure Cosmos DB Java SDK 4.x.x jämfört med tidigare SDK:er (Java SDK 3.x.x, Async Java SDK 2.x.x och Sync Java SDK 2.x.x):
Azure Cosmos DB Java SDK 3.x.x och 4.0 refererar till klientresurserna som
Cosmos<resourceName>
. Till exempelCosmosClient
,CosmosDatabase
,CosmosContainer
. I version 2.x.x har Azure Cosmos DB Java SDK:er inte något enhetligt namngivningsschema.Azure Cosmos DB Java SDK 3.x.x och 4.0 erbjuder både Sync- och Async-API:er.
Java SDK 4.0 : Alla klasser tillhör Synkroniserings-API:et om inte klassnamnet läggs till efter
Async
Cosmos
.Java SDK 3.x.x: Alla klasser tillhör Async-API:et om inte klassnamnet läggs till efter
Async
Cosmos
.Async Java SDK 2.x.x: Klassnamnen liknar Sync Java SDK 2.x.x, men namnet börjar med Async.
Hierarkisk API-struktur
Azure Cosmos DB Java SDK 4.0 och 3.x.x introducerar en hierarkisk API-struktur som organiserar klienter, databaser och containrar på ett kapslat sätt enligt följande kodfragment på 4,0 SDK:
CosmosContainer container = client.getDatabase("MyDatabaseName").getContainer("MyContainerName");
I version 2.x.x av Azure Cosmos DB Java SDK utförs alla åtgärder på resurser och dokument via klientinstansen.
Representerar dokument
I Azure Cosmos DB Java SDK 4.0 är anpassade POJO:er och JsonNodes
de två alternativen för att läsa och skriva dokumenten från Azure Cosmos DB.
I Azure Cosmos DB Java SDK 3.x.x CosmosItemProperties
exponeras objektet av det offentliga API:et och hanteras som en dokumentrepresentation. Den här klassen exponeras inte längre offentligt i version 4.0.
Importer
Azure Cosmos DB Java SDK 4.0-paketen börjar med
com.azure.cosmos
Azure Cosmos DB Java SDK 3.x.x-paket börjar med
com.azure.data.cosmos
Azure Cosmos DB Java SDK 2.x.x Sync API-paket börjar med
com.microsoft.azure.documentdb
Azure Cosmos DB Java SDK 4.0 placerar flera klasser i ett kapslat paket
com.azure.cosmos.models
. Några av dessa paket är:CosmosContainerResponse
CosmosDatabaseResponse
CosmosItemResponse
- Async API-analoger för alla ovanstående paket
CosmosContainerProperties
FeedOptions
PartitionKey
IndexingPolicy
IndexingMode
... etc.
Accessors
Azure Cosmos DB Java SDK 4.0 exponerar get
och set
metoder för åtkomst till instansmedlemmarna. Till exempel har container.getId()
instansen CosmosContainer
och container.setId()
metoder.
Detta skiljer sig från Azure Cosmos DB Java SDK 3.x.x som exponerar ett fluent-gränssnitt. Till exempel har container.id()
en CosmosSyncContainer
instans som är överbelastad för att hämta eller ange id
värdet.
Hantera beroendekonflikter
Uppgradering från Azure Cosmos DB Java SDK V2 till V4 kan medföra beroendekonflikter på grund av ändringar i de bibliotek som används av SDK. För att lösa dessa konflikter krävs noggrann hantering av beroendena.
Förstå de nya beroendena: Azure Cosmos DB V4 SDK har en egen uppsättning beroenden som kan skilja sig från dem i tidigare versioner. Kontrollera att du är medveten om dessa beroenden:
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
Ta bort beroenden i konflikt: Börja med att ta bort beroenden som är relaterade till tidigare versioner av SDK:t från filen
pom.xml
. Dessa inkluderarazure-cosmosdb
och eventuella transitiva beroenden som det gamla SDK:et kan ha haft.Lägg till V4 SDK-beroenden: Lägg till V4 SDK och dess beroenden i din
pom.xml
. Här är ett exempel:<dependency> <groupId>com.azure</groupId> <artifactId>azure-cosmos</artifactId> <version>4.x.x</version> <!-- Use the latest version available --> </dependency>
Sök efter beroendekonflikter: Använd Maven-kommandot
dependency:tree
för att generera ett beroendeträd och identifiera eventuella konflikter. Kör:mvn dependency:tree
Leta efter eventuella motstridiga versioner av beroenden. Dessa konflikter uppstår ofta med bibliotek som
reactor-core
,netty-handler
,guava
ochjackson
.Använd Beroendehantering: Om du stöter på versionskonflikter kan du behöva åsidosätta problematiska versioner med hjälp av
<dependencyManagement>
avsnittet i dinpom.xml
. Här är ett exempel för att framtvinga en specifik version avreactor-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>
Exkludera transitiva beroenden: Ibland kan du behöva undanta transitiva beroenden som har tagits in av andra beroenden. Om ett annat bibliotek till exempel innehåller en äldre version av ett beroende som står i konflikt kan du exkludera det så här:
<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>
Återskapa och testa: När du har gjort dessa ändringar återskapar du projektet och testar det noggrant för att säkerställa att de nya beroendena fungerar korrekt och att inga körningskonflikter inträffar.
Jämförelse av kodfragment
Skapa resurser
Följande kodfragment visar skillnaderna i hur resurser skapas mellan API:erna 4.0, 3.x.x Async, 2.x.x Sync och 2.x.x Async:
// 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();
Objektåtgärder
Följande kodfragment visar skillnaderna i hur objektåtgärder utförs mellan API:erna 4.0, 3.x.x Async, 2.x.x Sync och 2.x.x Async:
// 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.
Indexering
Följande kodfragment visar skillnaderna i hur indexering skapas mellan API:erna 4.0, 3.x.x Async, 2.x.x Sync och 2.x.x Async:
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);
Lagrade procedurer
Följande kodfragment visar skillnaderna i hur lagrade procedurer skapas mellan API:erna 4.0, 3.x.x Async, 2.x.x Sync och 2.x.x Async:
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();
Ändringsfeed
Följande kodfragment visar skillnaderna i hur ändringsflödesåtgärder körs mellan API:erna 4.0 och 3.x.x Async:
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) på containernivå
Följande kodfragment visar skillnaderna i hur du skapar tid att leva för data i containern mellan API:erna 4.0, 3.x.x Async, 2.x.x Sync och 2.x.x Async:
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");
Tid till live(TTL) på objektnivå
Följande kodfragment visar skillnaderna i hur du skapar tid att leva för ett objekt mellan API:erna 4.0, 3.x.x Async, 2.x.x Sync och 2.x.x Async:
// 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ästa steg
- Skapa en Java-app för att hantera Azure Cosmos DB för NoSQL-data med hjälp av V4 SDK
- Lär dig mer om reaktorbaserade Java-SDK:er
- Lär dig mer om att konvertera RxJava-asynkron kod till asynkron reaktorkod med guiden Reactor vs RxJava
- Försöker du planera kapacitet för en migrering till Azure Cosmos DB?
- Om allt du vet är antalet virtuella kärnor och servrar i ditt befintliga databaskluster läser du om att uppskatta enheter för begäranden med virtuella kärnor eller virtuella kärnor
- Om du känner till vanliga begärandefrekvenser för din aktuella databasarbetsbelastning kan du läsa om att uppskatta enheter för begäranden med azure Cosmos DB-kapacitetshanteraren