本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
D ynamoDBMapper 類別
DynamoDBMapper
類別是 Amazon DynamoDB 的進入點。它提供 DynamoDB 端點的存取,也讓您可以存取多個資料表中的資料。它還可讓您對項目執行各種建立、讀取、更新和刪除 (CRUD) 操作,以及執行查詢和掃描資料表。此類別提供下列使用 DynamoDB 的方法。
如需對應的 Javadoc 文件,請參閱 AWS SDK for Java API參考中的 DynamoDBMapper。
主題
save
將指定的物件儲存至資料表。您要儲存的物件是此方法的唯一必要參數。您可以使用 DynamoDBMapperConfig
物件來提供選用的組態參數。
如果具有相同主索引鍵的項目不存在,則此方法會在資料表中建立新的項目。如果具有相同主索引鍵的項目存在,則會更新現有項目。如果分割區索引鍵和排序索引鍵是字串類型,並以 標註@DynamoDBAutoGeneratedKey
,則如果保持未初始化,則會為其提供隨機全域唯一識別碼 (UUID)。標註 @DynamoDBVersionAttribute
的版本欄位會遞增一。此外,如果更新版本欄位或產生索引鍵,則會因這項操作而更新傳入的物件。
根據預設,只會更新對應至已映射類別屬性的屬性。項目上的任何其他現有屬性則不受影響。不過,如果您指定 SaveBehavior.CLOBBER
,則可以強制完全覆寫項目。
DynamoDBMapperConfig config = DynamoDBMapperConfig.builder() .withSaveBehavior(DynamoDBMapperConfig.SaveBehavior.CLOBBER).build(); mapper.save(item, config);
如果您已啟用版本控制,則用戶端與伺服器端項目版本必須相符。不過,如果使用 SaveBehavior.CLOBBER
選項,則版本不需要相符。如需版本控制的詳細資訊,請參閱「DynamoDB 和具有版本編號的樂觀鎖定」。
load
從資料表擷取項目。您必須提供要擷取之項目的主索引鍵。您可以使用 DynamoDBMapperConfig
物件來提供選用的組態參數。例如,您可以選擇性地請求強烈一致讀取,確保此方法只擷取最新的項目數值,如下列 Java 陳述式所示。
DynamoDBMapperConfig config = DynamoDBMapperConfig.builder() .withConsistentReads(DynamoDBMapperConfig.ConsistentReads.CONSISTENT).build(); CatalogItem item = mapper.load(CatalogItem.class, item.getId(), config);
DynamoDB 預設會傳回數值最終一致的項目。如需 DynamoDB 最終一致性模型的資訊,請參閱 DynamoDB 讀取一致性。
刪除
刪除資料表中的項目。您必須傳入已映射類別的物件執行個體。
如果您已啟用版本控制,則用戶端與伺服器端項目版本必須相符。不過,如果使用 SaveBehavior.CLOBBER
選項,則版本不需要相符。如需版本控制的詳細資訊,請參閱「DynamoDB 和具有版本編號的樂觀鎖定」。
query
查詢資料表或次要索引。
假設您有一個存放論壇主題回覆的 Reply
資料表。每個對話主旨都可以有零個以上的回覆。Reply
資料表的主索引鍵包含 Id
和 ReplyDateTime
欄位;其中,Id
是分割區索引鍵,而 ReplyDateTime
是主索引鍵的排序索引鍵。
Reply ( Id, ReplyDateTime, ... )
假設您已建立 Reply
類別與 DynamoDB 中對應 Reply
資料表之間的映射。下列 Java 程式碼使用 DynamoDBMapper
來尋找特定對話主旨在過去兩週的所有回覆。
範例
String forumName = "&DDB;"; String forumSubject = "&DDB; Thread 1"; String partitionKey = forumName + "#" + forumSubject; long twoWeeksAgoMilli = (new Date()).getTime() - (14L*24L*60L*60L*1000L); Date twoWeeksAgo = new Date(); twoWeeksAgo.setTime(twoWeeksAgoMilli); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); String twoWeeksAgoStr = df.format(twoWeeksAgo); Map<String, AttributeValue> eav = new HashMap<String, AttributeValue>(); eav.put(":v1", new AttributeValue().withS(partitionKey)); eav.put(":v2",new AttributeValue().withS(twoWeeksAgoStr.toString())); DynamoDBQueryExpression<Reply> queryExpression = new DynamoDBQueryExpression<Reply>() .withKeyConditionExpression("Id = :v1 and ReplyDateTime > :v2") .withExpressionAttributeValues(eav); List<Reply> latestReplies = mapper.query(Reply.class, queryExpression);
查詢會傳回 Reply
物件的集合。
query
方法預設會傳回「延遲載入」集合。它一開始只會傳回一頁的結果,然後視需要進行服務呼叫來取得下一頁。若要取得所有相符的項目,請逐一查看 latestReplies
集合。
請注意,在集合上呼叫 size()
方法將會載入所有結果,以提供準確的計數。這可能會導致大量佈建的輸送量消耗,而且在非常大的資料表上甚至可能耗盡 中的所有記憶體JVM。
若要查詢索引,您必須先將索引建模為映射器類別。假設Reply
資料表有一個名為 PostedBy-Message-Index 的全域次要索引。此索引的分割區索引鍵是 PostedBy
,而排序索引鍵是 Message
。索引中項目的類別定義將會如下。
@DynamoDBTable(tableName="Reply") public class PostedByMessage { private String postedBy; private String message; @DynamoDBIndexHashKey(globalSecondaryIndexName = "PostedBy-Message-Index", attributeName = "PostedBy") public String getPostedBy() { return postedBy; } public void setPostedBy(String postedBy) { this.postedBy = postedBy; } @DynamoDBIndexRangeKey(globalSecondaryIndexName = "PostedBy-Message-Index", attributeName = "Message") public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } // Additional properties go here. }
@DynamoDBTable
註釋指出此索引與 Reply
資料表建立關聯。@DynamoDBIndexHashKey
註釋表示索引的分割區索引鍵 (PostedBy),並@DynamoDBIndexRangeKey
表示索引的排序索引鍵 (訊息)。
您現在可以使用 DynamoDBMapper
來查詢索引,並擷取特定使用者所張貼的訊息子集。如果資料表和索引之間沒有衝突的映射,且映射器中已建立映射,則不需要指定索引名稱。映射器將根據主索引鍵和排序索引鍵推論。下列程式碼會查詢全域次要索引。因為全域次要索引支援最終一致讀取,但不支援強烈一致讀取,所以必須指定 withConsistentRead(false)
。
HashMap<String, AttributeValue> eav = new HashMap<String, AttributeValue>(); eav.put(":v1", new AttributeValue().withS("User A")); eav.put(":v2", new AttributeValue().withS("DynamoDB")); DynamoDBQueryExpression<PostedByMessage> queryExpression = new DynamoDBQueryExpression<PostedByMessage>() .withIndexName("PostedBy-Message-Index") .withConsistentRead(false) .withKeyConditionExpression("PostedBy = :v1 and begins_with(Message, :v2)") .withExpressionAttributeValues(eav); List<PostedByMessage> iList = mapper.query(PostedByMessage.class, queryExpression);
查詢會傳回 PostedByMessage
物件的集合。
queryPage
查詢資料表或次要索引,並傳回單頁的相符結果。與使用 query
方法相同,您必須指定分割區索引鍵值以及套用至排序索引鍵屬性的查詢篩選條件。不過,queryPage
只會傳回第一「頁」的資料;亦即,符合 1 MB 的資料量
scan
掃描整個資料表或次要索引。您可以選擇性地指定 FilterExpression
來篩選結果集。
假設您有一個存放論壇主題回覆的 Reply
資料表。每個對話主旨都可以有零個以上的回覆。Reply
資料表的主索引鍵包含 Id
和 ReplyDateTime
欄位;其中,Id
是分割區索引鍵,而 ReplyDateTime
是主索引鍵的排序索引鍵。
Reply ( Id, ReplyDateTime, ... )
如果您已將 Java 類別映射至 Reply
資料表,則可以使用 DynamoDBMapper
來掃描資料表。例如,下列 Java 程式碼會掃描整個 Reply
資料表,而且只會傳回特定一年的回覆。
範例
HashMap<String, AttributeValue> eav = new HashMap<String, AttributeValue>(); eav.put(":v1", new AttributeValue().withS("2015")); DynamoDBScanExpression scanExpression = new DynamoDBScanExpression() .withFilterExpression("begins_with(ReplyDateTime,:v1)") .withExpressionAttributeValues(eav); List<Reply> replies = mapper.scan(Reply.class, scanExpression);
scan
方法預設會傳回「延遲載入」集合。它一開始只會傳回一頁的結果,然後視需要進行服務呼叫來取得下一頁。若要取得所有相符的項目,請逐一查看 replies
集合。
請注意,在集合上呼叫 size()
方法將會載入所有結果,以提供準確的計數。這可能會導致大量佈建的輸送量消耗,而且在非常大的資料表上甚至可能耗盡 中的所有記憶體JVM。
若要掃描索引,您必須先將索引建模為映射器類別。假設 Reply
資料表有一個名為 PostedBy-Message-Index
的全域次要索引。此索引的分割區索引鍵是 PostedBy
,而排序索引鍵是 Message
。此索引的映射器類別顯示在 query 區段。它使用 @DynamoDBIndexHashKey
和 @DynamoDBIndexRangeKey
註釋來指定索引的分割區索引鍵和排序索引鍵。
下列程式碼範例掃描 PostedBy-Message-Index
。它不會使用掃描篩選條件,因此會將索引中的所有項目都傳回給您。
DynamoDBScanExpression scanExpression = new DynamoDBScanExpression() .withIndexName("PostedBy-Message-Index") .withConsistentRead(false); List<PostedByMessage> iList = mapper.scan(PostedByMessage.class, scanExpression); Iterator<PostedByMessage> indexItems = iList.iterator();
scanPage
掃描資料表或次要索引,並傳回單頁的相符結果。與使用 scan
方法相同,您可以選擇性地指定 FilterExpression
來篩選結果集。不過,scanPage
只會傳回第一「頁」的資料;亦即,符合 1 MB 內的資料量。
parallelScan
執行整個資料表或次要索引的平行掃描。您可以指定資料表的一些邏輯區段,以及掃描表達式來篩選結果。parallelScan
會將掃描任務分到多個工作者 (一個邏輯區段一個工作者);工作者會平行處理資料,並傳回結果。
下列 Java 程式碼範例會對 Product
資料表執行平行掃描。
int numberOfThreads = 4; Map<String, AttributeValue> eav = new HashMap<String, AttributeValue>(); eav.put(":n", new AttributeValue().withN("100")); DynamoDBScanExpression scanExpression = new DynamoDBScanExpression() .withFilterExpression("Price <= :n") .withExpressionAttributeValues(eav); List<Product> scanResult = mapper.parallelScan(Product.class, scanExpression, numberOfThreads);
batchSave
使用 AmazonDynamoDB.batchWriteItem
方法的一或多個呼叫,將物件儲存至一或多個資料表。此方法不提供交易保證。
下列 Java 程式碼會將兩個項目 (書籍) 儲存至 ProductCatalog
資料表。
Book book1 = new Book(); book1.setId(901); book1.setProductCategory("Book"); book1.setTitle("Book 901 Title"); Book book2 = new Book(); book2.setId(902); book2.setProductCategory("Book"); book2.setTitle("Book 902 Title"); mapper.batchSave(Arrays.asList(book1, book2));
batchLoad
使用一或多個資料表的主索引鍵,以從中擷取多個項目。
下列 Java 程式碼會從兩個不同的資料表擷取兩個項目。
ArrayList<Object> itemsToGet = new ArrayList<Object>(); ForumItem forumItem = new ForumItem(); forumItem.setForumName("Amazon DynamoDB"); itemsToGet.add(forumItem); ThreadItem threadItem = new ThreadItem(); threadItem.setForumName("Amazon DynamoDB"); threadItem.setSubject("Amazon DynamoDB thread 1 message text"); itemsToGet.add(threadItem); Map<String, List<Object>> items = mapper.batchLoad(itemsToGet);
batchDelete
使用 AmazonDynamoDB.batchWriteItem
方法的一或多個呼叫,刪除一或多個資料表中的物件。此方法不提供交易保證。
下列 Java 程式碼會刪除 ProductCatalog
資料表中的兩個項目 (書籍)。
Book book1 = mapper.load(Book.class, 901); Book book2 = mapper.load(Book.class, 902); mapper.batchDelete(Arrays.asList(book1, book2));
batchWrite
使用 AmazonDynamoDB.batchWriteItem
方法的一或多個呼叫,將物件儲存至一或多個資料表,並刪除物件。此方法未提供交易保證或支援版本控制 (條件式放置或刪除)。
下列 Java 程式碼會將新項目寫入至 Forum
資料表、將新項目寫入至 Thread
資料表,並刪除 ProductCatalog
資料表中的項目。
// Create a Forum item to save Forum forumItem = new Forum(); forumItem.setName("Test BatchWrite Forum"); // Create a Thread item to save Thread threadItem = new Thread(); threadItem.setForumName("AmazonDynamoDB"); threadItem.setSubject("My sample question"); // Load a ProductCatalog item to delete Book book3 = mapper.load(Book.class, 903); List<Object> objectsToWrite = Arrays.asList(forumItem, threadItem); List<Book> objectsToDelete = Arrays.asList(book3); mapper.batchWrite(objectsToWrite, objectsToDelete);
transactionWrite
使用 AmazonDynamoDB.transactWriteItems
方法的一個呼叫,將物件儲存至一或多個資料表,並從中刪除物件。
如需交易特定的例外狀況清單,請參閱TransactWriteItems 錯誤。
如需有關 DynamoDB 交易和所提供原子性、一致性、隔離和耐久性 (ACID) 保證的詳細資訊,請參閱 Amazon DynamoDB 交易。
注意
此方法不支援下列項目:
以下 Java 程式碼會以交易的方式,將新項目寫入每個 Forum
和 Thread
資料表。
Thread s3ForumThread = new Thread(); s3ForumThread.setForumName("S3 Forum"); s3ForumThread.setSubject("Sample Subject 1"); s3ForumThread.setMessage("Sample Question 1"); Forum s3Forum = new Forum(); s3Forum.setName("S3 Forum"); s3Forum.setCategory("Amazon Web Services"); s3Forum.setThreads(1); TransactionWriteRequest transactionWriteRequest = new TransactionWriteRequest(); transactionWriteRequest.addPut(s3Forum); transactionWriteRequest.addPut(s3ForumThread); mapper.transactionWrite(transactionWriteRequest);
transactionLoad
使用 AmazonDynamoDB.transactGetItems
方法的一個呼叫,載入一或多個資料表中的物件。
如需交易特定的例外狀況清單,請參閱TransactGetItems 錯誤。
如需 DynamoDB 交易和所提供原子性、一致性、隔離和耐久性 (ACID) 保證的詳細資訊,請參閱 Amazon DynamoDB 交易。
以下 Java 程式碼會以交易的方式,將從每個 Forum
和 Thread
資料表載入一個項目。
Forum dynamodbForum = new Forum(); dynamodbForum.setName("DynamoDB Forum"); Thread dynamodbForumThread = new Thread(); dynamodbForumThread.setForumName("DynamoDB Forum"); TransactionLoadRequest transactionLoadRequest = new TransactionLoadRequest(); transactionLoadRequest.addLoad(dynamodbForum); transactionLoadRequest.addLoad(dynamodbForumThread); mapper.transactionLoad(transactionLoadRequest);
count
評估指定的掃描表達式,並傳回相符項目的計數。不傳回任何項目資料。
generateCreateTable請求
剖析代表 DynamoDB 資料表的POJO類別,並傳回該資料表CreateTableRequest
的 。
createS3Link
建立 Amazon S3 中物件的連結。您必須指定儲存貯體名稱和索引鍵名稱,以唯一識別儲存貯體中的物件。
若要使用 createS3Link
,映射器類別必須定義 getter 和 setter 方法。下列程式碼範例透過將新的屬性和 getter/setter 方法新增至 CatalogItem
類別來說明這種情況。
@DynamoDBTable(tableName="ProductCatalog") public class CatalogItem { ... public S3Link productImage; .... @DynamoDBAttribute(attributeName = "ProductImage") public S3Link getProductImage() { return productImage; } public void setProductImage(S3Link productImage) { this.productImage = productImage; } ... }
下列 Java 程式碼定義要寫入至 Product
資料表的新項目。此項目包含產品映像的連結;映像資料會上傳至 Amazon S3。
CatalogItem item = new CatalogItem(); item.setId(150); item.setTitle("Book 150 Title"); String amzn-s3-demo-bucket = "amzn-s3-demo-bucket"; String myS3Key = "productImages/book_150_cover.jpg"; item.setProductImage(mapper.createS3Link(amzn-s3-demo-bucket, myS3Key)); item.getProductImage().uploadFrom(new File("/file/path/book_150_cover.jpg")); mapper.save(item);
S3Link
類別提供許多其他方法來操控 Amazon S3 中的物件。如需詳細資訊,請參閱 Javadocs for S3Link
。
getS3ClientCache
傳回基礎 S3ClientCache
來存取 Amazon S3。S3ClientCache
是 AmazonS3Client
物件的智慧映射。如果您有多個用戶端, S3ClientCache
可協助您依 AWS 區域整理用戶端,並可隨需建立新的 Amazon S3 用戶端。