| « PreviousNext » | |
![]() ![]() ![]() | Did this page help you? Yes | No | Tell us about it... |
Topics
The AWS SDK for Java provides a high-level API, the Object Persistence model, which enables
you to map your client-side classes to the Amazon DynamoDB tables. The individual object instances
then map to items in a table. The Object Persistence model provides the
DynamoDBMapper class that provides an entry point to Amazon DynamoDB. This class
provides you with a connection to the Amazon DynamoDB database and enables you to access your tables,
perform various create, read, update and delete (CRUD) operations, and execute queries.
To map your classes to tables, the Object Persistence model provides a set of annotation types.
Note
The Object Persistence model enables you to perform data operations such as save items, update items, delete items, and query the tables. However, the model does not provide API to create, update, or delete tables. Only the low-level API enables you to create, update, and delete tables. For more information, see Working with Tables Using the AWS SDK for Java Low-Level API.
For example, consider a ProductCatalog table that has Id as the hash primary key.
ProductCatalog(Id, ...)
You can map a class in your client application to the ProductCatalog table as shown in the
following Java code example. The code snippet defines a CatalogItem class and
uses the annotations that are defined by Amazon DynamoDB to establish the mapping.
@DynamoDBTable(tableName="ProductCatalog")
public class CatalogItem {
private Integer id;
private String title;
private String ISBN;
private Set<String> bookAuthors;
private String someProp;
@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<String> getBookAuthors() { return bookAuthors; }
public void setBookAuthors(Set<String> bookAuthors) { this.bookAuthors = bookAuthors; }
@DynamoDBIgnore
public String getSomeProp() { return someProp;}
public void setSomeProp(String someProp) {this.someProp = someProp;}
}
In the preceding code snippet, the @DynamoDBTable annotation type maps the
CatalogItem class to the ProductCatalog table. You can store individual
class instances as items in the table. In the class definition, the
@DynamoDBHashKey annotation type maps the Id property to the primary key.
By default, the class properties map to the same name attributes in the table. The
properties Title and ISBN map to the same name attributes in the
table. If you define a class property name that does not match a corresponding item
attribute name, then you must explicitly add the @DynamoDBAttribute annotation
type to specify the mapping. In the preceding example, the @DynamoDBAttribute
annotation type is added to each property to ensure that the property names match exactly
with the tables created in the Getting Started section, and to be
consistent with the attribute names used in other code examples in this guide.
Your class definition can have properties that don't map to any attributes in the table.
You identify these properties by adding the @DynamoDBIgnore annotation type. In
the preceding example, the SomeProp property is marked with the
@DynamoDBIgnore annotation type. When you upload a CatalogItem
instance to the table, the DynamoDBContext does not include
SomeProp property and also it does not return this attribute when you
retrieve an item from the table.
In addition to mapping properties of the Java types such as integer and string, you can use the Object Persistence model to map any arbitrary data as long as you provide an appropriate converter to map it to the Amazon DynamoDB types. To learn about mapping arbitrary types, see Mapping Arbitrary Data Using the AWS SDK for Java Object Persistence Model.
The Object Persistence model also supports optimistic locking using a version field in the
class. The @DynamoDBVersionAttribute annotation type on a property identifies
it as a version field. For more information about using versioning, see Optimistic Locking With Version Number
Using the AWS SDK for Java Object Persistence Model.
The following table lists the annotations that Amazon DynamoDB offers for you to map your classes and properties to tables and attributes.
Note
In the following table, only the DynamoDBTable and the
DynamoDBHashKey are the required tags.
| Declarative Tag (Annotation) | Description |
|---|---|
@DynamoDBTable
|
Identifies the target table in Amazon DynamoDB. For example, the
following Java code snippet defines a class
@DynamoDBTable(tableName="People")
public class Developer { ...}
This annotation can be inherited or overridden.
|
@DynamoDBIgnore
|
Indicates to the |
@DynamoDBAttribute
|
Maps a property to a table attribute. By default, each class
property maps to an item attribute with the same name. However,
if the names are not the same, using this tag you can map a
property to the attribute. In the following Java snippet, the
@DynamoDBAttribute(attributeName = "Authors")
public List<String> getBookAuthors() { return BookAuthors; }
public void setBookAuthors(List<String> BookAuthors) { this.BookAuthors = BookAuthors; }
The |
@DynamoDBHashKey |
Maps a class property to the hash attribute of the table. The property must be one of the supported String or Numeric type and cannot be a collection type. Assume that you have a table, ProductCatalog, that has Id as
the primary key. The following Java code snippet defines a
@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 |
Maps a class property to the range key attribute of the table.
If the primary key is made of both the hash and range key
attributes, you can use this tag to map your class field to the
range attribute. For example, assume that you have a Reply table
that stores replies for forum threads. Each thread can have many
replies. So the primary key of this table is both the ThreadId
and ReplyDateTime. The ThreadId is the hash attribute and
ReplyDateTime is the range attribute. The following Java code
snippet defines a @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 | Marks a hash key or range key property as being auto-generated. The Object Persistence Model will generate a random UUID when saving these attributes. Only String properties can be marked as auto-generated keys. The following snippet demonstrates using auto-generated keys. @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 | Identifies a class property for storing an optimistic locking
version number. DynamoDBMapper assigns a version number
to this property when it saves a new item, and increments it each
time you update the item. Only number scalar types are supported.
For more information about data type, see Amazon DynamoDB Data Types. For more information about versioning, see Optimistic Locking With Version Number
Using the AWS SDK for Java Object Persistence Model. |
The DynamoDBMapper class is the entry point to Amazon DynamoDB. It
provides a connection to Amazon DynamoDB and enables you to access your data in various tables,
perform various CRUD operations on items, and execute queries and scans against tables.
This class provides the following key operations for you to work with Amazon DynamoDB.
| Method | Description |
|---|---|
save
|
Saves the specified object to the table. The object that you
wish to save is the only required parameter for this method. You
can provide optional configuration parameters using the
If an item that has the same primary key does not exist, this
method creates a new item in the table. If an item that has the
same primary key exists, it updates the existing item. String
hash and range keys annotated with
By default, only attributes corresponding to mapped class
properties are updated; any additional existing attributes on an
item are unaffected. However, if you specify
mapper.save(obj, new DynamoDBMapperConfig(DynamoDBMapperConfig.SaveBehavior.CLOBBER)); If you have versioning enabled, then the client-side and
server-side item versions must match. However, the version does
not need to match if the |
load
|
Retrieves an item from a table. You must provide the
primary key of the item that you wish to retrieve. You can
provide optional configuration parameters using the
CatalogItem item = mapper.load(CatalogItem.class, item.getId(),
new DynamoDBMapperConfig(DynamoDBMapperConfig.ConsistentReads.CONSISTENT));
By default, Amazon DynamoDB returns the item that has values that are eventually consistent. For information about the eventual consistency model of Amazon DynamoDB, see Data Read and Consistency Considerations. |
delete |
Deletes an item from the table. You must pass in an object instance of the mapped class. If you have versioning enabled, then the client-side and
server-side item versions must match. However, the version does
not need to match if the |
query |
Enables the querying of a table. You can query a table only if its primary key is made of both a hash and a range attribute. This method requires you to provide a hash attribute value and a query filter that is applied on the range attribute. A filter expression includes a condition and a value. Assume that you have a table, Reply, that stores forum thread replies. Each thread subject can have 0 or more replies. The primary key of the Reply table consists of the Id and ReplyDateTime fields, where Id is the hash attribute and ReplyDateTime is the range attribute of the primary key.
Reply ( Id, ReplyDateTime, ... )
Now, assume that you created an Object Persistence model that includes a Reply class that maps to the table. The following Java code snippet uses the
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);
The query returns a collection of
Note If your table's primary key is made of only a hash
attribute, then you cannot use the
The |
scan |
Scans an entire table. You can specify optional condition
filters items based on one or more Assume that you have a table, Thread, that stores forum thread information including Subject (part of the composite primary key) and if the thread is answered.
Thread ( ForumName, Subject, ..., Answered )
If you have an Object Persistence model for this table, then
you can use the
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);
The |
batchDelete |
Deletes objects from one or more tables using one or more
calls to the The following Java code snippet deletes two items (books) from the ProductCatalog table.
Book book1 = mapper.load(Book.class, 901); Book book2 = mapper.load(Book.class, 902); mapper.batchDelete(Arrays.asList(book1, book2));
|
batchSave |
Saves objects to one or more tables using one or more calls to
the The following Java code snippet saves two items (books) to the ProductCatalog table.
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 |
Saves objects to and deletes objects from one or more tables
using one or more calls to the
The following Java code snippet writes a new item to the Forum table, writes a new item to the Thread table, and deletes an item from the ProductCatalog table.
// 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);
|
count |
Evaluates the specified scan expression and returns the count of matching items. No item data is returned. |
marshallIntoObject |
Utility method to transform a result from the low-level API into a domain object. |
The Object Persistence model provides the DynamoDBMapper for you to
communicate with Amazon DynamoDB. When you create a mapper instance, you can specify optional
configuration information using the DynamoDBMapperConfig class. You can
specify the following arguments for an instance of
DynamoDBMapperConfig:
A DynamoDBMapperConfig.SaveBehavior enumeration value -
Specifies how DynamoDBMapper should deal with attributes during
save operations. Specifying the value
DynamoDBMapperConfig.SaveBehavior.UPDATE will not affect
unmodeled attributes on a save operation. All modeled attributes are
updated. Primitive number types (byte, int, long) are set to 0. Object types
are set to null. Specifying the value
DynamoDBMapperConfig.SaveBehavior.CLOBBER will clear and
replace all attributes, included unmodeled ones, (delete and recreate) on
save. Versioned field constraints will also be disregarded. If you do not
specify configuration information for your mapper instance, then the default
DynamoDBMapperConfig.SaveBehavior.UPDATE is used.
A DynamoDBMapperConfig.ConsistentReads enumeration value - If
you specify DynamoDBMapperConfig.ConsistentReads.CONSISTENT ,
then the DynamoDBMapper includes a strongly consistent read
request. When retrieving data using the load,
query, or scan operations, you can optionally
add this parameter. Strongly consistent reads have implications for
performance and billing; see the product detail page for more information.
Instead of strongly consistent reads, you can specify eventual consistency
with the DynamoDBMapperConfig.ConsistentReads.EVENTUAL
enumeration value. If you do not specify configuration information for your
mapper instance, then the default
DynamoDBMapperConfig.ConsistentReads.EVENTUAL is
used.
A DynamoDBMapperConfig.TableNameOverride object - Instructs
DynamoDBMapper to ignore the table name specified by a
class's DynamoDBTable annotation and use a different one you
supply. This is useful when partitioning your data into multiple tables at
run time.
You can override the default configuration object for DynamoDBMapper per
operation, as needed.
This section describes the supported primitive Java data types, collections, and arbitrary data types.
Amazon DynamoDB supports the following primitive data types and primitive wrapper classes.
String
Boolean, boolean
Byte, byte
Date (as ISO8601 millisecond-precision string, shifted to
UTC)
Calendar (as ISO8601 millisecond-precision string, shifted to
UTC)
Long, long
Integer, int
Double, double
Float, float
BigDecimal
BigInteger
Amazon DynamoDB supports the Java Set collection types. If your mapped collection property is not a Set, then an exception is thrown.
The following table summarizes how the preceding Java types map to the Amazon DynamoDB types.
| Java type | Amazon DynamoDB type |
|---|---|
|
All number types |
|
|
Strings |
|
| boolean | N (number type), 0 or 1. |
| ByteBuffer | B (binary type) |
| Date | S (string type). The Date values are stored as
ISO-8601 formatted strings. |
| Set collection types | SS (string set) type, NS (number set)
type, or BS (binary set) type. |
In addition, Amazon DynamoDB supports arbitrary data types. For example, you can define your own
complex types on the client. You use the DynamoDBMarshaller class and the
@DynamoDBMarhsalling annotation type for the complex type to describe
the mapping (Mapping Arbitrary Data Using the
AWS SDK for Java Object Persistence Model).