Map items in DynamoDB tables - AWS SDK for Java
AWS services or capabilities described in AWS documentation might vary by Region. To see the differences applicable to the China Regions, see Getting Started with AWS services in China.

At Amazon Web Services (AWS), we’re focused on finding ways to improve our products and provide a better customer experience. To do that, we need your feedback. Please take 5 minutes of your time to share insights regarding your experience with Java Spring and your need for Spring integration with AWS.

Click here to take a quick survey

This survey is hosted by an external company (Qualtrics), so the link above does not lead to our website. Please note that AWS will own the data gathered via this survey, and will not share the information/results collected with survey respondents. AWS handles your information as described in the AWS Privacy Notice.

Map items in DynamoDB tables

The Amazon DynamoDB enhanced client is a high-level library that is part of the AWS SDK for Java version 2 (v2). It offers a straightforward way to map client-side classes to DynamoDB tables. You define the relationships between tables and their corresponding model classes in your code. Then you can intuitively perform various create, read, update, or delete (CRUD) operations on tables or items in DynamoDB.

The AWS SDK for Java v2 includes a set of annotations that you can use with a Java bean to quickly generate a TableSchema for mapping your classes to tables. Alternatively, if you declare each TableSchema explicitly, you don’t need to include annotations in your classes.

To work with items in a DynamoDB table using the enhanced client, first create a DynamoDbEnhancedClient from an existing DynamoDbClient object.

Region region = Region.US_EAST_1; DynamoDbClient ddb = DynamoDbClient.builder() .region(region) .build(); DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder() .dynamoDbClient(ddb) .build(); createDynamoDBTable(enhancedClient);

Create a table using the enhanced client

To easily create a TableSchema using the enhanced client, start by creating a Java data class that includes a default public constructor and standardized names of getters and setters for each property in the class. Include a class-level annotation to indicate it is a DynamoDbBean and, at a minimum, include a DynamoDbPartitionKey annotation on the getter or setter for the primary key of the table record.

Once this data class has been defined, call TableSchema’s fromBean() with that data class to create the table schema.

See the code snippet below for an example of how to do this.

Imports

import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient; import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable; import software.amazon.awssdk.enhanced.dynamodb.TableSchema; import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean; import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey; import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneOffset;

Code

// Puts an item into a DynamoDB table public static void putRecord(DynamoDbEnhancedClient enhancedClient) { try { DynamoDbTable<Customer> custTable = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class)); // Create an Instant LocalDate localDate = LocalDate.parse("2020-04-07"); LocalDateTime localDateTime = localDate.atStartOfDay(); Instant instant = localDateTime.toInstant(ZoneOffset.UTC); // Populate the Table Customer custRecord = new Customer(); custRecord.setCustName("Susan Blue"); custRecord.setId("id103"); custRecord.setEmail("sblue@noserver.com"); custRecord.setRegistrationDate(instant) ; // Put the customer data into a DynamoDB table custTable.putItem(custRecord); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } System.out.println("done"); } @DynamoDbBean public static class Customer { private String id; private String name; private String email; private Instant regDate; @DynamoDbPartitionKey public String getId() { return this.id; }; public void setId(String id) { this.id = id; } @DynamoDbSortKey public String getCustName() { return this.name; } public void setCustName(String name) { this.name = name; } public String getEmail() { return this.email; } public void setEmail(String email) { this.email = email; } public Instant getRegistrationDate() { return regDate; } public void setRegistrationDate(Instant registrationDate) { this.regDate = registrationDate; } }

See the complete example on GitHub.

Retrieve (get) an item from a table

To get an item from a DynamoDB table, create a DynamoDbTable object and call getItem() with a GetItemEnhancedRequest object to get the actual item.

For example, the following code snippet demonstrates one way to use the enhanced client to get information from an item in a DynamoDB table.

Imports

import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient; import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable; import software.amazon.awssdk.enhanced.dynamodb.Key; import software.amazon.awssdk.enhanced.dynamodb.TableSchema; import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean; import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey; import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import java.time.Instant;

Code

public static String getItem(DynamoDbEnhancedClient enhancedClient) { try { //Create a DynamoDbTable object DynamoDbTable<Customer> mappedTable = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class)); //Create a KEY object Key key = Key.builder() .partitionValue("id110") .sortValue("Fred Pink") .build(); // Get the item by using the key Customer result = mappedTable.getItem(r->r.key(key)); return "The record id is "+result.getId(); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); }

See the complete example on GitHub.

Batch create (put) and delete items

You can batch a series of put requests (PutItemEnhancedRequest) and delete requests (DeleteItemEnhancedRequest) to one or more tables, and then send all of the changes in a single request.

In the following code snippet, a DynamoDbTable object is created, two items are queued up to be added to the table, and then the items are written to the table in a single call. Include multiple entries of addDeleteItem() and addPutItem() (part of WriteBatch.Builder) in each batch, as needed. To queue up changes to a different table, add another instance of WriteBatch.builder() and provide a corresponding DynamoDbTable object in mappedTableResource().

Imports

import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient; import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable; import software.amazon.awssdk.enhanced.dynamodb.TableSchema; import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean; import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey; import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey; import software.amazon.awssdk.enhanced.dynamodb.model.BatchWriteItemEnhancedRequest; import software.amazon.awssdk.enhanced.dynamodb.model.WriteBatch; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneOffset;

Code

public static void putBatchRecords(DynamoDbEnhancedClient enhancedClient) { try { DynamoDbTable<Customer> mappedTable = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class)); LocalDate localDate = LocalDate.parse("2020-04-07"); LocalDateTime localDateTime = localDate.atStartOfDay(); Instant instant = localDateTime.toInstant(ZoneOffset.UTC); Customer record2 = new Customer(); record2.setCustName("Fred Pink"); record2.setId("id110"); record2.setEmail("fredp@noserver.com"); record2.setRegistrationDate(instant) ; Customer record3 = new Customer(); record3.setCustName("Susan Pink"); record3.setId("id120"); record3.setEmail("spink@noserver.com"); record3.setRegistrationDate(instant) ; // Create a BatchWriteItemEnhancedRequest object BatchWriteItemEnhancedRequest batchWriteItemEnhancedRequest = BatchWriteItemEnhancedRequest.builder() .writeBatches( WriteBatch.builder(Customer.class) .mappedTableResource(mappedTable) .addPutItem(r -> r.item(record2)) .addPutItem(r -> r.item(record3)) .build()) .build(); // Add these two items to the table enhancedClient.batchWriteItem(batchWriteItemEnhancedRequest); System.out.println("done"); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } } @DynamoDbBean public static class Customer { private String id; private String name; private String email; private Instant regDate; @DynamoDbPartitionKey public String getId() { return this.id; }; public void setId(String id) { this.id = id; } @DynamoDbSortKey public String getCustName() { return this.name; } public void setCustName(String name) { this.name = name; } public String getEmail() { return this.email; } public void setEmail(String email) { this.email = email; } public Instant getRegistrationDate() { return regDate; } public void setRegistrationDate(Instant registrationDate) { this.regDate = registrationDate; } }

See the complete example on GitHub.

Use a filtered query to get items from a table

You can get items from a table based on filterable queries, and then perform operations (for example, return item values) on one or more of the items in the query results.

In the following code snippet, you build a filter by first defining the value or values you’re searching for as an AttributeValue object. Then you put this into a HashMap and build an Expression from the classname:HashMap. Build a QueryConditional object to specify the primary key to match against in the query, and then execute the query on your DynamoDbTable object.

Note

The QueryConditional interface has several methods you can use to build your queries, including common conditional statements like greater than, less than, and in between.

Imports

import java.time.Instant; import java.util.Map; import java.util.Iterator; import java.util.HashMap; import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient; import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable; import software.amazon.awssdk.enhanced.dynamodb.Expression; import software.amazon.awssdk.enhanced.dynamodb.Key; import software.amazon.awssdk.enhanced.dynamodb.TableSchema; import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean; import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey; import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.enhanced.dynamodb.model.QueryConditional; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;

Code

public static void queryTableFilter(DynamoDbEnhancedClient enhancedClient) { try{ DynamoDbTable<EnhancedQueryRecords.Customer> mappedTable = enhancedClient.table("Customer", TableSchema.fromBean(EnhancedQueryRecords.Customer.class)); AttributeValue att = AttributeValue.builder() .s("sblue@noserver.com") .build(); Map<String, AttributeValue> expressionValues = new HashMap<>(); expressionValues.put(":value", att); Expression expression = Expression.builder() .expression("email = :value") .expressionValues(expressionValues) .build(); // Create a QueryConditional object that is used in the query operation QueryConditional queryConditional = QueryConditional .keyEqualTo(Key.builder().partitionValue("id103") .build()); // Get items in the Customer table and write out the ID value Iterator<EnhancedQueryRecords.Customer> results = mappedTable.query(r -> r.queryConditional(queryConditional).filterExpression(expression)).items().iterator(); while (results.hasNext()) { EnhancedQueryRecords.Customer rec = results.next(); System.out.println("The record id is "+rec.getId()); } } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } System.out.println("Done");

See the complete example on GitHub.

Retrieve (get) all items from a table

When you want to get all of the records in a given DynamoDB table, use the scan() method of your DynamoDbTable object and the items() method to create a set of results against which you can execute various item operations. For example, the following code snippet prints out the ID value of each item in the Record table.

Imports

import java.time.Instant; import java.util.Iterator; import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient; import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable; import software.amazon.awssdk.enhanced.dynamodb.TableSchema; import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean; import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey; import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;

Code

public static void scan( DynamoDbEnhancedClient enhancedClient) { try{ // Create a DynamoDbTable object DynamoDbTable<Customer> custTable = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class)); Iterator<Customer> results = custTable.scan().items().iterator(); while (results.hasNext()) { Customer rec = results.next(); System.out.println("The record id is "+rec.getId()); } } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } System.out.println("Done"); }

See the complete example on GitHub.

For more information, see Working with items in DynamoDB in the Amazon DynamoDB Developer Guide.