這很重要
欲了解更多關於此 SDK 的資訊,請參閱 Azure Cosmos DB Java SDK v4 版本釋出說明、 Maven 倉庫、Azure Cosmos DB Java SDK v4 效能提示,以及 Azure Cosmos DB Java SDK v4 故障排除指南。
這很重要
由於 Azure Cosmos DB Java SDK v4 具備多達 20% 增強的吞吐量、基於 TCP 的直接模式,以及對最新後端服務功能的支援,我們建議您下次有機會時升級至 v4。 繼續閱讀以下內容以了解更多。
更新至最新的 Azure Cosmos DB Java SDK,以充分發揮 Azure Cosmos DB 的優勢——一個管理型非關聯式資料庫服務,具備具競爭力的效能、五九項可用性、獨一無二的資源治理等多項功能。 本文說明如何將你現有使用舊版 Azure Cosmos DB Java SDK 的 Java 應用程式升級到更新版的 Azure Cosmos DB Java SDK 4.0 for API for NoSQL。 Azure Cosmos DB Java SDK v4 對應於該 com.azure.cosmos 套件。 如果你是從以下 Azure Cosmos DB Java SDK 遷移應用程式,可以使用本文件中的說明:
- 同步 Java SDK 2.x.x
- Async Java SDK 2.x.x
- Java SDK 3.x.x
Azure Cosmos DB Java SDK 與套件對應配置
下表列出不同的 Azure Cosmos DB Java SDK、套件名稱及版本資訊:
| Java 開發套件 | 發行日期 | 綁定式 API | 梅文·賈爾 | Java 套件名稱 | API 參考文件 | 發行說明 | 退役日期 |
|---|---|---|---|---|---|---|---|
| Async 2.x.x | 2018 年 6 月 | Async(RxJava) | com.microsoft.azure::azure-cosmosdb |
com.microsoft.azure.cosmosdb.rx |
應用程式介面 | 更新紀錄 | 2024 年 8 月 31 日 |
| 同步 2.x.x | 2018年9月 | 同步 | com.microsoft.azure::azure-documentdb |
com.microsoft.azure.cosmosdb |
應用程式介面 | 2024年2月29日 | |
| 3.x.x | 2019年7月 | 非同步(反應器)/同步 | com.microsoft.azure::azure-cosmos |
com.azure.data.cosmos |
應用程式介面 | - | 2024 年 8 月 31 日 |
| 4.0 | 2020 年 6 月 | 非同步(反應器)/同步 | com.azure::azure-cosmos |
com.azure.cosmos |
應用程式介面 | - | - |
SDK 層級的實作變更
以下是不同 SDK 之間的主要實作差異:
RxJava 在 Azure Cosmos DB Java SDK 3.x.x 與 4.0 版本中被 reactor 取代
如果你不熟悉非同步程式設計或反應式程式設計,請參閱 Reactor 模式指南 ,了解非同步程式設計與 Project Reactor。 如果你過去使用過 Azure Cosmos DB Sync Java SDK 2.x.x 或 Azure Cosmos DB Java SDK 3.x.x Sync API,這份指南可能會有幫助。
如果你一直在使用 Azure Cosmos DB Async Java SDK 2.x.x,並計劃遷移到 4.0 SDK,請參考 Reactor 與 RxJava 指南 ,了解如何將 RxJava 程式碼轉換成 Reactor。
Azure Cosmos DB Java SDK v4 在 Async 和 Sync API 中都有直接連接模式
如果你一直在使用 Azure Cosmos DB Sync Java SDK 2.x.x,請注意基於 TCP(而非 HTTP)的直接連線模式是在 Azure Cosmos DB Java SDK 4.0 中實現的,適用於非同步與同步 API。
API 層級變更
以下是 Azure Cosmos DB Java SDK 4.x.x 與先前 SDK(Java SDK 3.x.x、Async Java SDK 2.x.x 及 Sync Java SDK 2.x.x)相比的 API 層級變更:
Azure Cosmos DB Java SDK 3.x.x 與 4.0 將客戶端資源稱為
Cosmos<resourceName>。 例如,CosmosClient,CosmosDatabase,CosmosContainer, 。 而在 2.x.x 版本中,Azure Cosmos DB Java SDK 並沒有統一的命名方式。Azure Cosmos DB Java SDK 3.x.x 和 4.0 同時提供 Sync 和 Async API。
Java SDK 4.0:所有類別都屬於 Sync API,除非類別名稱後面附加
AsyncCosmos。Java SDK 3.x.x:所有類別都屬於 Async API,除非類別名稱後面有
AsyncCosmos附加。Async Java SDK 2.x.x:類別名稱與 Sync Java SDK 2.x.x 相似,但名稱以 Async 開頭。
階層式 API 結構
Azure Cosmos DB Java SDK 4.0 與 3.x.x 引入了階層式 API 結構,將客戶端、資料庫與容器以巢狀方式組織,如下 4.0 SDK 程式碼摘要所示:
CosmosContainer container = client.getDatabase("MyDatabaseName").getContainer("MyContainerName");
在 Azure Cosmos DB Java SDK 2.x.x 版本中,所有對資源與文件的操作皆透過用戶端實例執行。
文件表示
在 Azure Cosmos DB Java SDK 4.0 中,自訂 POJO 和 JsonNodes 是兩個可以從 Azure Cosmos DB 讀寫文件的選項。
在 Azure Cosmos DB Java SDK 3.x.x 中, CosmosItemProperties 物件由公開 API 揭露並作為文件表示。 此類別在 4.0 版本中不再公開公開。
匯入
Azure Cosmos DB Java SDK 4.0 套件起始於
com.azure.cosmosAzure Cosmos DB Java SDK 3.x.x packages 開始於
com.azure.data.cosmosAzure Cosmos DB Java SDK 2.x.x Sync API 套件以
com.microsoft.azure.documentdb開始。Azure Cosmos DB Java SDK 4.0 將多個類別置於巢狀套件
com.azure.cosmos.models中。 其中一些方案包括:CosmosContainerResponseCosmosDatabaseResponseCosmosItemResponse- 上述所有套件的 Async API 對應版本
CosmosContainerPropertiesFeedOptionsPartitionKeyIndexingPolicy-
IndexingMode...等等。
Accessors
Azure Cosmos DB Java SDK 4.0 提供getset方法來存取實例成員。 例如,實 CosmosContainer 例有 container.getId() 和 container.setId() 方法。
這和 Azure Cosmos DB Java SDK 3.x.x 不同,後者使用流暢介面設計。 例如,一個 CosmosSyncContainer 實例具有 container.id() ,它被重載以取得或設定該 id 值。
管理依賴性衝突
從 Azure Cosmos DB Java SDK V2 升級到 V4 時,可能會因 SDK 所用函式庫的變更而產生相依性衝突。 解決這些衝突需要謹慎管理依賴關係。
了解新的相依性:Azure Cosmos DB V4 SDK 擁有一套相依性,這些相依性可能與先前版本不同。 務必了解以下依賴性:
azure-cosmosreactor-corereactor-nettynetty-handlerguavaslf4j-apijackson-databindjackson-annotationsjackson-corecommons-lang3commons-collections4azure-coreazure-core-http-netty
移除衝突的相依性:首先從
pom.xml檔案中移除與先前版本的 SDK 相關的相依性。 這些包括azure-cosmosdb以及舊 SDK 可能存在的任何傳遞依賴。新增 V4 SDK 相依賴性:將 V4 SDK 及其相依性加入你的
pom.xml. 以下為範例:<dependency> <groupId>com.azure</groupId> <artifactId>azure-cosmos</artifactId> <version>4.x.x</version> <!-- Use the latest version available --> </dependency>檢查相依性衝突:使用 Maven
dependency:tree指令產生相依樹並識別任何衝突。 請執行:mvn dependency:tree注意是否有相互矛盾的相依版本。 這些衝突常發生在像
reactor-core、netty-handler、guavajackson和 這樣的函式庫中。使用相依性管理:如果你遇到版本衝突,可能需要使用
<dependencyManagement>部分在你的pom.xml中覆蓋問題版本。 這裡是一個用以強制特定版本的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>排除遞移依賴:有時你可能需要排除由其他依賴帶來的傳遞依賴。 例如,如果另一個函式庫引入了較舊版本的相依性並發生衝突,你可以這樣排除它:
<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>重建與測試:完成這些變更後,重建專案並徹底測試,確保新相依關係正常運作,且不會發生執行時衝突。
程式碼片段比較
建立資源
以下程式碼摘要展示了 4.0、3.x.x 非同步、2.x.x 同步及 2.x.x 非同步 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();
項目操作
以下程式碼摘要展示了 4.0、3.x.x 非同步、2.x.x 同步及 2.x.x 非同步 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.
索引
以下程式碼片段展示了 4.0、3.x.x 非同步、2.x.x 同步與 2.x.x 非同步 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);
預存程序
以下程式碼片段展示了 4.0、3.x.x Async、2.x.x Sync 與 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();
變更摘要
以下程式碼範例展示了 4.0 與 3.x.x 非同步 API 執行變更饋送操作的差異:
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.boundedElastic())
.subscribe();
容器層級存活時間(TTL)
以下程式碼片段展示了 4.0、3.x.x Async、2.x.x Sync 與 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");
物品等級存活時間(TTL)
以下程式碼片段展示了 4.0、3.x.x 非同步、2.x.x 同步與 2.x.x 非同步 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
);
後續步驟
- 建立一個 Java 應用程式 ,用 V4 SDK 管理 Azure Cosmos DB for NoSQL 資料
- 了解 基於 Reactor 的 Java SDK
- 了解如何將 RxJava 非同步程式碼轉換成 Reactor 非同步程式碼,請參閱 Reactor 與 RxJava 指南
- 正在嘗試為遷移至 Azure Cosmos DB 進行容量規劃嗎?
- 如果您知道現有資料庫叢集中的虛擬核心和伺服器數目,請參閱使用虛擬核心或 vCPU 來估計要求單位
- 如果您知道目前資料庫工作負載的一般要求率,請參閱使用 Azure Cosmos DB 容量規劃工具來估計要求單位