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 naming conventions

  • Azure Cosmos DB Java SDK 3.x.x och 4.0 refererar till klientresurserna som Cosmos<resourceName>. Till exempel CosmosClient, 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 AsyncCosmos.

    • Java SDK 3.x.x: Alla klasser tillhör Async-API:et om inte klassnamnet läggs till efter AsyncCosmos.

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

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