介绍
- Amazon DynamoDB是一项完全托管的NoSQL数据库服务,可提供无缝的可扩展性和快速可预测的性能。
- Amazon DynamoDB自动将表的数据和流量分布在足够数量的服务器上,以处理客户指定的请求容量和存储的数据量,同时保持一致且快速的性能。
- 所有数据项都存储在固态磁盘(SSD)上,并自动跨区域中的多个可用区复制,以提供内置的高可用性和数据持久性。
- 您可以通过AWS管理控制台启动新的Amazon DynamoDB数据库表,在不停机或性能下降的情况下扩展或缩减对该表的请求容量,并获得对资源利用率和性能指标的可见性。
- 借助Amazon DynamoDB,您可以将操作和扩展分布式数据库的管理负担转移到AWS,因此您不必担心硬件设置,设置和配置,复制,软件修补或集群扩展。
- SDK: http : //aws.amazon.com/sdkforjava/
Amazon DynamoDB注释
- @DynamoDBTable
标识Amazon DynamoDB中的目标表。 例如,以下Java代码段定义了一个类Developer,并将其映射到Amazon DynamoDB中的People表。
- @DynamoDBTable(tableName="People")
- public class Developer { ...}
- @DynamoDBIgnore
向DynamoDBMapper实例指示应该忽略关联的属性。 将数据保存到表时,DynamoDBMapper不会将此属性保存到表中。
- @DynamoDBAttribute
将属性映射到表属性。 默认情况下,每个类属性都映射到具有相同名称的item属性。 但是,如果名称不同,则可以使用此标记将属性映射到属性。 在以下Java代码段中,DynamoDBAttribute将BookAuthors属性映射到表中的Authors属性名称。
- @DynamoDBAttribute(attributeName = "Authors")
- public List<String> getBookAuthors() { return BookAuthors; }
- public void setBookAuthors(List<String> BookAuthors) { this.BookAuthors = BookAuthors; }
将对象保存到表时,DynamoDBMapper使用作者作为属性名称。
- @DynamoDBHashKey
将类属性映射到表的hash属性。 该属性必须是受支持的String或Numeric类型之一,并且不能是集合类型。
假设您有一个表ProductCatalog,该表具有ID作为主键。 以下Java代码段定义了CatalogItem类,并使用@DynamoDBHashKey标记将其id属性映射到ProductCatalog表的主键。
- @DynamoDBTable(tableName="ProductCatalog")
- public class CatalogItem {
- private String Id;
- @DynamoDBHashKey(attributeName="Id")
- public String getId() {
- return Id;
- }
- public void setId(String Id) {
- this.Id = Id;
- }
- // Additional properties go here.
- }
- @DynamoDBRangeKey
将类属性映射到表的范围键属性。 如果主键是由哈希键和范围键属性组成的,则可以使用此标记将您的类字段映射到范围属性。 例如,假定您有一个“回复”表,其中存储有论坛主题的回复。 每个线程可以有很多回复。 因此,该表的主键是ThreadId和ReplyDateTime。 ThreadId是哈希属性,ReplyDateTime是范围属性。 以下Java代码段定义了Reply类,并将其映射到Reply表。 它同时使用@DynamoDBHashKey和@DynamoDBRangeKeytags来标识映射到主键的类属性。
- @DynamoDBTable(tableName="Reply")
- public class Reply {
- private String id;
- private String replyDateTime;
-
- @DynamoDBHashKey(attributeName="Id")
- public String getId() { return id; }
- public void setId(String id) { this.id = id; }
-
- @DynamoDBRangeKey(attributeName="ReplyDateTime")
- public String getReplyDateTime() { return replyDateTime; }
- public void setReplyDateTime(String replyDateTime) { this.replyDateTime = replyDateTime; }
-
- // Additional properties go here.
- }
- @DynamoDBAutoGeneratedKey
将哈希键或范围键属性标记为自动生成。 保存这些属性时,对象持久性模型将生成一个随机UUID。 只能将字符串属性标记为自动生成的键。
以下代码段演示了如何使用自动生成的密钥。
- @DynamoDBTable(tableName="AutoGeneratedKeysExample")
- public class AutoGeneratedKeys {
- private String id;
- private String payload;
-
- @DynamoDBHashKey(attributeName = "Id")
- @DynamoDBAutoGeneratedKey
- public String getId() { return id; }
- public void setId(String id) { this.id = id; }
-
- @DynamoDBAttribute(attributeName="payload")
- public String getPayload() { return this.payload };
- public String setPayload(String payload) { this.payload = payload };
-
- public static void saveItem() {
- AutoGeneratedKeys obj = new AutoGeneratedKeys();
- obj.setPayload("abc123");
-
- // id field is null at this point
- DynamoDBMapper mapper = new DynamoDBMapper(dynamoDBClient);
- mapper.save(obj);
-
- System.out.println("Object was saved with id " + obj.getId());
- }
- }
- @DynamoDBVersionAttribute
标识用于存储乐观锁定版本号的类属性。 DynamoDBMapper保存新项目时,会为此属性分配一个版本号,并在每次更新该项目时将其递增。 仅支持数字标量类型。
DynamoDBMapper类别
DynamoDBMapper类是Amazon DynamoDB的入口点。 它提供了与Amazon DynamoDB的连接,并使您能够访问各种表中的数据,对项目执行各种CRUD操作以及对表执行查询和扫描。 此类提供以下关键操作,供您使用Amazon DynamoDB。
- 救
- 将指定的对象保存到表中。
mapper.save(obj, new DynamoDBMapperConfig(DynamoDBMapperConfig.SaveBehavior.CLOBBER));
- 加载
- 从表中检索项目。
- CatalogItem item = mapper.load(CatalogItem.class, item.getId(),
- new DynamoDBMapperConfig(DynamoDBMapperConfig.ConsistentReads.CONSISTENT));
- 删除
- 从表中删除一个项目。
- 询问
- 启用表查询。
- String forumName = "Amazon DynamoDB";
- String forumSubject = "DynamoDB Thread 1";
- String hashKey = 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);
-
- Condition rangeKeyCondition = new Condition()
- .withComparisonOperator(ComparisonOperator.GT.toString())
- .withAttributeValueList(new AttributeValue().withS(twoWeeksAgoStr.toString()));
-
- Reply replyKey = new Reply();
- replyKey.setId(hashKey);
-
- DynamoDBQueryExpression<Reply> queryExpression = new DynamoDBQueryExpression<Reply>()
- .withHashKeyValues(replyKey)
- .withRangeKeyCondition("ReplyDateTime", rangeKeyCondition);
-
- List<Reply> latestReplies = mapper.query(Reply.class, queryExpression);
该查询返回Reply对象的集合。
- 扫描
- 扫描整个表。
- DynamoDBScanExpression scanExpression = new DynamoDBScanExpression();
-
- Map<String, Condition> scanFilter = new HashMap<String, Condition>();
- Condition scanCondition = new Condition()
- .withComparisonOperator(ComparisonOperator.EQ.toString())
- .withAttributeValueList(new AttributeValue().withN("0"));
-
- scanFilter.put("Answered", scanCondition);
-
- scanExpression.setScanFilter(scanFilter);
-
- List<Thread> unansweredThreads = mapper.scan(Thread.class, scanExpression);
- 扫描方法返回“延迟加载”集合。 它初仅返回一页结果,然后在需要时对下一页进行服务调用。 要获取所有匹配项,您仅需要遍历unansweredThreads集合。
- batchDelete
- 使用对AmazonDynamoDB.batchWriteItem方法的一个或多个调用从一个或多个表中删除对象。
- Book book1 = mapper.load(Book.class, 901);
- Book book2 = mapper.load(Book.class, 902);
- mapper.batchDelete(Arrays.asList(book1, book2));
- batchSave
- 使用对AmazonDynamoDB.batchWriteItem方法的一个或多个调用将对象保存到一个或多个表。
- Book book1 = new Book();
- book1.id = 901;
- book1.productCategory = "Book";
- book1.title = "Book 901 Title";
-
- Book book2 = new Book();
- book2.id = 902;
- book2.productCategory = "Book";
- book2.title = "Book 902 Title";
-
- mapper.batchSave(Arrays.asList(book1, book2));
- batchWrite
- 使用对AmazonDynamoDB.batchWriteItem方法的一个或多个调用,将对象保存到一个或多个表并从一个或多个表中删除对象。
- // Create a Forum item to save
- Forum forumItem = new Forum();
- forumItem.name = "Test BatchWrite Forum";
-
- // Create a Thread item to save
- Thread threadItem = new Thread();
- threadItem.forumName = "AmazonDynamoDB";
- threadItem.subject = "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);
- 计数
- 计算指定的扫描表达式并返回匹配项的计数。
- marshallIntoObject
- 一种将结果从低级API转换为域对象的实用程序方法。
支持的数据类型
Amazon DynamoDB支持以下原始数据类型和原始包装器类。
- 串
- 布尔,布尔
- 字节,字节
- 日期(作为ISO8601毫秒精度的字符串,转换为UTC)
- 日历(作为ISO8601毫秒精度的字符串,已转换为UTC)
- 好久好久
- 整数,整数
- 双倍
- 浮,浮
- 大十进制
- 大整数
Amazon DynamoDB支持Java Set集合类型。 如果映射的集合属性不是Set,则将引发异常。
下表总结了前面的Java类型如何映射到Amazon DynamoDB类型。
Java类型 | Amazon DynamoDB类型 |
所有数字类型 | N(数字类型) |
弦乐 | S(字符串类型) |
布尔值 | N(数字类型),0或1。 |
字节缓冲区 | B(二进制类型) |
日期 | S(字符串类型)。 日期值存储为ISO-8601格式的字符串。 |
设置收集类型 | SS(字符串集)类型,NS(数字集)类型或BS(二进制集)类型。 |
Java示例:CRUD操作
CatalogItem.java
- import java.util.Set;
- import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
- import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
- import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;
- @DynamoDBTable(tableName="ProductCatalog")
- public class CatalogItem {
- private Integer id;
- private String title;
- private String ISBN;
- private Set bookAuthors;
-
- @DynamoDBHashKey(attributeName="Id")
- public Integer getId() { return id; }
- public void setId(Integer id) { this.id = id; }
-
- @DynamoDBAttribute(attributeName="Title")
- public String getTitle() { return title; }
- public void setTitle(String title) { this.title = title; }
-
- @DynamoDBAttribute(attributeName="ISBN")
- public String getISBN() { return ISBN; }
- public void setISBN(String ISBN) { this.ISBN = ISBN;}
-
- @DynamoDBAttribute(attributeName = "Authors")
- public Set getBookAuthors() { return bookAuthors; }
- public void setBookAuthors(Set bookAuthors) { this.bookAuthors = bookAuthors; }
-
- @Override
- public String toString() {
- return "Book [ISBN=" + ISBN + ", bookAuthors=" + bookAuthors
- + ", id=" + id + ", title=" + title + "]";
- }
- }
ObjectPersistenceCRUDExample.java
- import java.io.IOException;
- import java.util.Arrays;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.Map;
- import java.util.Random;
-
- import com.amazonaws.AmazonClientException;
- import com.amazonaws.AmazonServiceException;
- import com.amazonaws.auth.AWSCredentials;
- import com.amazonaws.auth.ClasspathPropertiesFileCredentialsProvider;
- import com.amazonaws.regions.Region;
- import com.amazonaws.regions.Regions;
- import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
- import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
- import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig;
- import com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
- import com.amazonaws.services.dynamodbv2.model.AttributeValue;
- import com.amazonaws.services.dynamodbv2.model.ComparisonOperator;
- import com.amazonaws.services.dynamodbv2.model.Condition;
- import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
- import com.amazonaws.services.dynamodbv2.model.DescribeTableRequest;
- import com.amazonaws.services.dynamodbv2.model.KeySchemaElement;
- import com.amazonaws.services.dynamodbv2.model.KeyType;
- import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
- import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType;
- import com.amazonaws.services.dynamodbv2.model.ScanRequest;
- import com.amazonaws.services.dynamodbv2.model.ScanResult;
- import com.amazonaws.services.dynamodbv2.model.TableDescription;
- import com.amazonaws.services.dynamodbv2.model.TableStatus;
-
- public class ObjectPersistenceCRUDExample {
- static AmazonDynamoDBClient client;
- private DynamoDBMapper mapper;
- private static int PRODUCT_ID;
-
- public static void main(String[] args) throws IOException {
- ObjectPersistenceCRUDExample demo = new ObjectPersistenceCRUDExample();
- demo.init();
- demo.createTable("ProductCatalog");
- for (int i = ; i < 100; i++) {
- System.out.println(i);
- PRODUCT_ID = PRODUCT_ID + i;
- demo.insert();
- }
- demo.getAllRows();
- CatalogItem itemRetrieved = demo.load(PRODUCT_ID);
- demo.update(itemRetrieved);
- CatalogItem updatedItem = demo.load(PRODUCT_ID);
- demo.delete(updatedItem);
- demo.load(updatedItem.getId());
- System.out.println("Example complete!");
- }
-
- private void init() {
- PRODUCT_ID = new Random().nextInt(1000);
- AWSCredentials credentials = new ClasspathPropertiesFileCredentialsProvider()
- .getCredentials();
- client = new AmazonDynamoDBClient(credentials);
- Region usWest2 = Region.getRegion(Regions.US_WEST_2);
- client.setRegion(usWest2);
- mapper = new DynamoDBMapper(client);
- }
-
- private void createTable(String tableName) {
- try {
- CreateTableRequest createTableRequest = new CreateTableRequest()
- .withTableName(tableName);
- createTableRequest.withKeySchema(new KeySchemaElement()
- .withAttributeName("Id").withKeyType(KeyType.HASH));
- createTableRequest
- .withAttributeDefinitions(new AttributeDefinition()
- .withAttributeName("Id").withAttributeType(
- ScalarAttributeType.N));
- createTableRequest
- .withProvisionedThroughput(new ProvisionedThroughput()
- .withReadCapacityUnits(10L).withWriteCapacityUnits(
- 10L));
- TableDescription createdTableDescription = client.createTable(
- createTableRequest).getTableDescription();
- System.out.println("Created Table: " + createdTableDescription);
- // Wait for it to become active
- waitForTableToBecomeAvailable(tableName);
- } catch (AmazonServiceException e) {
- e.printStackTrace();
- } catch (AmazonClientException e) {
- e.printStackTrace();
- }
- }
-
- private void waitForTableToBecomeAvailable(String tableName) {
- System.out.println("Waiting for " + tableName + " to become ACTIVE...");
- long startTime = System.currentTimeMillis();
- long endTime = startTime + (10 * 60 * 1000);
- while (System.currentTimeMillis() < endTime) {
- try {
- Thread.sleep(1000 * 20);
- } catch (Exception e) {
- }
- try {
- DescribeTableRequest request = new DescribeTableRequest()
- .withTableName(tableName);
- TableDescription tableDescription = client.describeTable(
- request).getTable();
- String tableStatus = tableDescription.getTableStatus();
- System.out.println(" - current state: " + tableStatus);
- if (tableStatus.equals(TableStatus.ACTIVE.toString()))
- return;
- } catch (AmazonServiceException ase) {
- if (ase.getErrorCode().equalsIgnoreCase(
- "ResourceNotFoundException") == false)
- throw ase;
- }
- }
- throw new RuntimeException("Table " + tableName + " never went active");
- }
-
- private void insert() {
- CatalogItem item = new CatalogItem();
- item.setId(PRODUCT_ID);
- item.setTitle("Book PRODUCT_ID");
- item.setISBN("611-1111111111");
- item.setBookAuthors(new HashSet(Arrays.asList("Author1",
- "Author2")));
- // Save the item (book).
- mapper.save(item);
- }
-
- private void update(CatalogItem itemRetrieved) {
- itemRetrieved.setISBN("622-2222222222");
- itemRetrieved.setBookAuthors(new HashSet(Arrays.asList(
- "Author1", "Author3")));
- mapper.save(itemRetrieved);
- System.out.println("Item updated:");
- System.out.println(itemRetrieved);
- }
-
- private void delete(CatalogItem updatedItem) {
- // Delete the item.
- mapper.delete(updatedItem);
- }
-
- private CatalogItem load(int id) {
- // Retrieve the updated item.
- DynamoDBMapperConfig config = new DynamoDBMapperConfig(
- DynamoDBMapperConfig.ConsistentReads.CONSISTENT);
- CatalogItem updatedItem = mapper.load(CatalogItem.class, id, config);
- if (updatedItem == null) {
- System.out.println("Done - Sample item is deleted.");
- } else {
- System.out.println("Retrieved item:");
- System.out.println(updatedItem);
- }
- return updatedItem;
- }
-
- private void getAllRows() {
- ScanRequest scanRequest = new ScanRequest()
- .withTableName("ProductCatalog");
- scanRequest.setLimit(10);
- HashMap scanFilter = new HashMap();
- Condition condition = new Condition().withComparisonOperator(
- ComparisonOperator.EQ.toString()).withAttributeValueList(
- new AttributeValue().withS("611-1111111111"));
- scanFilter.put("ISBN", condition);
- Condition condition2 = new Condition().withComparisonOperator(
- ComparisonOperator.LE.toString()).withAttributeValueList(
- new AttributeValue().withN("1000"));
- scanFilter.put("Id", condition2);
- scanRequest.withScanFilter(scanFilter);
- try {
- System.out.println("Scan Request: " + scanRequest);
- ScanResult scanResponse = client.scan(scanRequest);
- for (Map item : scanResponse.getItems()) {
- System.out.println(item.get("Id").getN() + " , " +
- item.get("ISBN").getS() + " , " +
- item.get("Authors").getSS() + " , " +
- item.get("Title").getS());
- }
- System.out.println("Scan Response: " + scanResponse);
- System.out.println("Count: " + scanResponse.getCount());
- System.out.println("Scanned Count: "
- + scanResponse.getScannedCount());
- System.out.println("Items: " + scanResponse.getItems());
- } catch (AmazonServiceException e) {
- e.printStackTrace();
- } catch (AmazonClientException e) {
- e.printStackTrace();
- }
- }
- }