0
# Amazon DynamoDB Service APIs
1
2
Amazon DynamoDB is a fully managed NoSQL database service that provides fast and predictable performance. The AWS SDK for Java provides three levels of abstraction for working with DynamoDB: low-level service client, Document API, and Object Mapper.
3
4
## Package
5
6
**Service Package**: `com.amazonaws.services.dynamodbv2`
7
**Model Package**: `com.amazonaws.services.dynamodbv2.model`
8
**Document API**: `com.amazonaws.services.dynamodbv2.document`
9
**Object Mapper**: `com.amazonaws.services.dynamodbv2.datamodeling`
10
**Maven Artifact**: `aws-java-sdk-dynamodb`
11
12
## Client Creation
13
14
```java { .api }
15
package com.amazonaws.services.dynamodbv2;
16
17
// DynamoDB client builder
18
class AmazonDynamoDBClientBuilder extends AwsSyncClientBuilder<AmazonDynamoDBClientBuilder, AmazonDynamoDB> {
19
static AmazonDynamoDBClientBuilder standard();
20
static AmazonDynamoDB defaultClient();
21
AmazonDynamoDBClientBuilder enableEndpointDiscovery();
22
AmazonDynamoDBClientBuilder disableEndpointDiscovery();
23
AmazonDynamoDB build();
24
}
25
```
26
27
### Usage
28
29
```java
30
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
31
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
32
import com.amazonaws.regions.Regions;
33
34
// Create default DynamoDB client
35
AmazonDynamoDB dynamoDB = AmazonDynamoDBClientBuilder.defaultClient();
36
37
// Create DynamoDB client with specific region
38
AmazonDynamoDB dynamoDB = AmazonDynamoDBClientBuilder.standard()
39
.withRegion(Regions.US_EAST_1)
40
.build();
41
```
42
43
## Low-Level API
44
45
### Main Service Interface
46
47
```java { .api }
48
package com.amazonaws.services.dynamodbv2;
49
50
// Main DynamoDB interface (thread-safe)
51
interface AmazonDynamoDB {
52
// Table operations
53
CreateTableResult createTable(CreateTableRequest createTableRequest);
54
CreateTableResult createTable(List<AttributeDefinition> attributeDefinitions,
55
String tableName,
56
List<KeySchemaElement> keySchema,
57
ProvisionedThroughput provisionedThroughput);
58
DescribeTableResult describeTable(String tableName);
59
DescribeTableResult describeTable(DescribeTableRequest describeTableRequest);
60
UpdateTableResult updateTable(UpdateTableRequest updateTableRequest);
61
DeleteTableResult deleteTable(String tableName);
62
DeleteTableResult deleteTable(DeleteTableRequest deleteTableRequest);
63
ListTablesResult listTables();
64
ListTablesResult listTables(String exclusiveStartTableName, Integer limit);
65
66
// Item operations
67
PutItemResult putItem(String tableName, Map<String, AttributeValue> item);
68
PutItemResult putItem(String tableName, Map<String, AttributeValue> item,
69
String returnValues);
70
PutItemResult putItem(PutItemRequest putItemRequest);
71
GetItemResult getItem(String tableName, Map<String, AttributeValue> key);
72
GetItemResult getItem(String tableName, Map<String, AttributeValue> key,
73
Boolean consistentRead);
74
GetItemResult getItem(GetItemRequest getItemRequest);
75
UpdateItemResult updateItem(String tableName, Map<String, AttributeValue> key,
76
Map<String, AttributeValueUpdate> attributeUpdates);
77
UpdateItemResult updateItem(UpdateItemRequest updateItemRequest);
78
DeleteItemResult deleteItem(String tableName, Map<String, AttributeValue> key);
79
DeleteItemResult deleteItem(String tableName, Map<String, AttributeValue> key,
80
String returnValues);
81
DeleteItemResult deleteItem(DeleteItemRequest deleteItemRequest);
82
83
// Query and scan
84
QueryResult query(QueryRequest queryRequest);
85
ScanResult scan(String tableName, List<String> attributesToGet);
86
ScanResult scan(String tableName, Map<String, Condition> scanFilter);
87
ScanResult scan(ScanRequest scanRequest);
88
89
// Batch operations
90
BatchGetItemResult batchGetItem(Map<String, KeysAndAttributes> requestItems);
91
BatchGetItemResult batchGetItem(BatchGetItemRequest batchGetItemRequest);
92
BatchWriteItemResult batchWriteItem(Map<String, List<WriteRequest>> requestItems);
93
BatchWriteItemResult batchWriteItem(BatchWriteItemRequest batchWriteItemRequest);
94
95
// Transactions
96
TransactGetItemsResult transactGetItems(TransactGetItemsRequest transactGetItemsRequest);
97
TransactWriteItemsResult transactWriteItems(TransactWriteItemsRequest transactWriteItemsRequest);
98
99
// PartiQL
100
ExecuteStatementResult executeStatement(ExecuteStatementRequest executeStatementRequest);
101
BatchExecuteStatementResult batchExecuteStatement(BatchExecuteStatementRequest batchExecuteStatementRequest);
102
103
// Waiters
104
AmazonDynamoDBWaiters waiters();
105
}
106
```
107
108
### AttributeValue
109
110
```java { .api }
111
package com.amazonaws.services.dynamodbv2.model;
112
113
// Represents a DynamoDB attribute value
114
class AttributeValue {
115
AttributeValue();
116
AttributeValue(String s);
117
118
// String
119
AttributeValue withS(String s);
120
String getS();
121
122
// Number (stored as string)
123
AttributeValue withN(String n);
124
String getN();
125
126
// Binary
127
AttributeValue withB(ByteBuffer b);
128
ByteBuffer getB();
129
130
// String Set
131
AttributeValue withSS(Collection<String> ss);
132
List<String> getSS();
133
134
// Number Set
135
AttributeValue withNS(Collection<String> ns);
136
List<String> getNS();
137
138
// Binary Set
139
AttributeValue withBS(Collection<ByteBuffer> bs);
140
List<ByteBuffer> getBS();
141
142
// Map
143
AttributeValue withM(Map<String, AttributeValue> m);
144
Map<String, AttributeValue> getM();
145
146
// List
147
AttributeValue withL(Collection<AttributeValue> l);
148
List<AttributeValue> getL();
149
150
// Null
151
AttributeValue withNULL(Boolean nul);
152
Boolean isNULL();
153
154
// Boolean
155
AttributeValue withBOOL(Boolean bool);
156
Boolean getBOOL();
157
}
158
```
159
160
### Low-Level Usage
161
162
```java
163
import com.amazonaws.services.dynamodbv2.model.*;
164
import java.util.HashMap;
165
import java.util.Map;
166
167
// Put item
168
Map<String, AttributeValue> item = new HashMap<>();
169
item.put("id", new AttributeValue().withS("123"));
170
item.put("name", new AttributeValue().withS("John Doe"));
171
item.put("age", new AttributeValue().withN("30"));
172
item.put("active", new AttributeValue().withBOOL(true));
173
174
PutItemRequest putRequest = new PutItemRequest()
175
.withTableName("Users")
176
.withItem(item);
177
dynamoDB.putItem(putRequest);
178
179
// Get item
180
Map<String, AttributeValue> key = new HashMap<>();
181
key.put("id", new AttributeValue().withS("123"));
182
183
GetItemRequest getRequest = new GetItemRequest()
184
.withTableName("Users")
185
.withKey(key)
186
.withConsistentRead(true);
187
188
GetItemResult result = dynamoDB.getItem(getRequest);
189
Map<String, AttributeValue> retrievedItem = result.getItem();
190
191
// Query with expression
192
QueryRequest queryRequest = new QueryRequest()
193
.withTableName("Users")
194
.withKeyConditionExpression("id = :v_id")
195
.withExpressionAttributeValues(
196
Map.of(":v_id", new AttributeValue().withS("123")));
197
198
QueryResult queryResult = dynamoDB.query(queryRequest);
199
for (Map<String, AttributeValue> item : queryResult.getItems()) {
200
// Process item
201
}
202
203
// Update item
204
UpdateItemRequest updateRequest = new UpdateItemRequest()
205
.withTableName("Users")
206
.withKey(key)
207
.withUpdateExpression("SET age = :val")
208
.withExpressionAttributeValues(
209
Map.of(":val", new AttributeValue().withN("31")))
210
.withReturnValues(ReturnValue.ALL_NEW);
211
212
UpdateItemResult updateResult = dynamoDB.updateItem(updateRequest);
213
214
// Delete item
215
DeleteItemRequest deleteRequest = new DeleteItemRequest()
216
.withTableName("Users")
217
.withKey(key);
218
dynamoDB.deleteItem(deleteRequest);
219
```
220
221
## Document API (Higher-Level)
222
223
The Document API provides a simpler, more intuitive interface than the low-level API.
224
225
```java { .api }
226
package com.amazonaws.services.dynamodbv2.document;
227
228
// Entry point for Document API
229
class DynamoDB {
230
DynamoDB(AmazonDynamoDB client);
231
232
// Table operations
233
Table getTable(String tableName);
234
Table createTable(CreateTableRequest createTableRequest);
235
TableCollection<ListTablesResult> listTables();
236
237
// Batch operations
238
BatchGetItemOutcome batchGetItem(TableKeysAndAttributes... tableKeysAndAttributes);
239
BatchGetItemOutcome batchGetItem(BatchGetItemSpec batchGetItemSpec);
240
BatchWriteItemOutcome batchWriteItem(TableWriteItems... tableWriteItems);
241
BatchWriteItemOutcome batchWriteItem(BatchWriteItemSpec batchWriteItemSpec);
242
243
// Lifecycle
244
void shutdown();
245
}
246
247
// Represents a DynamoDB table
248
class Table {
249
// Metadata
250
String getTableName();
251
TableDescription describe();
252
TableDescription getDescription();
253
Index getIndex(String indexName);
254
255
// Item operations
256
PutItemOutcome putItem(Item item);
257
PutItemOutcome putItem(Item item, String conditionExpression,
258
Map<String, String> nameMap, Map<String, Object> valueMap);
259
PutItemOutcome putItem(PutItemSpec putItemSpec);
260
GetItemOutcome getItemOutcome(KeyAttribute... primaryKeyComponents);
261
GetItemOutcome getItemOutcome(PrimaryKey primaryKey);
262
GetItemOutcome getItemOutcome(GetItemSpec spec);
263
Item getItem(KeyAttribute... primaryKeyComponents);
264
Item getItem(PrimaryKey primaryKey);
265
Item getItem(GetItemSpec spec);
266
UpdateItemOutcome updateItem(PrimaryKey primaryKey, AttributeUpdate... attributeUpdates);
267
UpdateItemOutcome updateItem(UpdateItemSpec updateItemSpec);
268
DeleteItemOutcome deleteItem(KeyAttribute... primaryKeyComponents);
269
DeleteItemOutcome deleteItem(PrimaryKey primaryKey);
270
DeleteItemOutcome deleteItem(DeleteItemSpec deleteItemSpec);
271
272
// Query and scan
273
ItemCollection<QueryOutcome> query(QuerySpec spec);
274
ItemCollection<ScanOutcome> scan(ScanSpec spec);
275
276
// Table management
277
TableDescription updateTable(UpdateTableSpec updateTableSpec);
278
DeleteTableResult delete();
279
Table waitForActive();
280
Table waitForAllActiveOrDelete();
281
}
282
283
// Represents a DynamoDB item
284
class Item {
285
// Type-specific getters
286
String getString(String attrName);
287
BigDecimal getNumber(String attrName);
288
int getInt(String attrName);
289
long getLong(String attrName);
290
boolean getBoolean(String attrName);
291
byte[] getBinary(String attrName);
292
Set<String> getStringSet(String attrName);
293
Set<BigDecimal> getNumberSet(String attrName);
294
Map<String, Object> getMap(String attrName);
295
List<Object> getList(String attrName);
296
297
// Fluent setters
298
Item withString(String attrName, String value);
299
Item withNumber(String attrName, Number value);
300
Item withInt(String attrName, int value);
301
Item withLong(String attrName, long value);
302
Item withBoolean(String attrName, boolean value);
303
Item withBinary(String attrName, byte[] value);
304
Item withStringSet(String attrName, Set<String> value);
305
Item withNumberSet(String attrName, Set<Number> value);
306
Item withMap(String attrName, Map<String, Object> value);
307
Item withList(String attrName, List<Object> value);
308
Item withPrimaryKey(KeyAttribute... components);
309
Item withPrimaryKey(String hashKeyName, Object hashKeyValue);
310
Item withPrimaryKey(String hashKeyName, Object hashKeyValue,
311
String rangeKeyName, Object rangeKeyValue);
312
313
// Utility methods
314
boolean isNull(String attrName);
315
boolean isPresent(String attrName);
316
Map<String, Object> asMap();
317
String toJSON();
318
String toJSONPretty();
319
}
320
```
321
322
### Document API Usage
323
324
```java
325
import com.amazonaws.services.dynamodbv2.document.*;
326
import com.amazonaws.services.dynamodbv2.document.spec.*;
327
328
// Create DynamoDB Document API
329
DynamoDB dynamoDB = new DynamoDB(dynamoDBClient);
330
331
// Get table reference
332
Table table = dynamoDB.getTable("Users");
333
334
// Put item
335
Item item = new Item()
336
.withPrimaryKey("id", "123")
337
.withString("name", "John Doe")
338
.withNumber("age", 30)
339
.withBoolean("active", true)
340
.withStringSet("tags", Set.of("vip", "premium"));
341
342
PutItemOutcome outcome = table.putItem(item);
343
344
// Get item
345
Item retrievedItem = table.getItem("id", "123");
346
String name = retrievedItem.getString("name");
347
int age = retrievedItem.getInt("age");
348
boolean active = retrievedItem.getBoolean("active");
349
350
// Get item with projection
351
GetItemSpec spec = new GetItemSpec()
352
.withPrimaryKey("id", "123")
353
.withProjectionExpression("name, age")
354
.withConsistentRead(true);
355
Item item = table.getItem(spec);
356
357
// Update item
358
UpdateItemSpec updateSpec = new UpdateItemSpec()
359
.withPrimaryKey("id", "123")
360
.withUpdateExpression("SET age = :val")
361
.withValueMap(Map.of(":val", 31))
362
.withReturnValues(ReturnValue.ALL_NEW);
363
UpdateItemOutcome updateOutcome = table.updateItem(updateSpec);
364
365
// Query
366
QuerySpec querySpec = new QuerySpec()
367
.withKeyConditionExpression("id = :v_id")
368
.withValueMap(Map.of(":v_id", "123"));
369
370
ItemCollection<QueryOutcome> items = table.query(querySpec);
371
for (Item item : items) {
372
System.out.println(item.toJSON());
373
}
374
375
// Scan with filter
376
ScanSpec scanSpec = new ScanSpec()
377
.withFilterExpression("age > :min_age")
378
.withValueMap(Map.of(":min_age", 25));
379
380
ItemCollection<ScanOutcome> items = table.scan(scanSpec);
381
for (Item item : items) {
382
System.out.println(item.getString("name"));
383
}
384
385
// Delete item
386
DeleteItemSpec deleteSpec = new DeleteItemSpec()
387
.withPrimaryKey("id", "123")
388
.withConditionExpression("attribute_exists(id)")
389
.withReturnValues(ReturnValue.ALL_OLD);
390
DeleteItemOutcome deleteOutcome = table.deleteItem(deleteSpec);
391
```
392
393
## Object Mapper (ORM-Style)
394
395
The Object Mapper provides annotation-based mapping of Java POJOs to DynamoDB tables.
396
397
```java { .api }
398
package com.amazonaws.services.dynamodbv2.datamodeling;
399
400
// DynamoDB Mapper (thread-safe)
401
class DynamoDBMapper {
402
DynamoDBMapper(AmazonDynamoDB dynamoDB);
403
DynamoDBMapper(AmazonDynamoDB dynamoDB, DynamoDBMapperConfig config);
404
405
// CRUD operations
406
<T> T load(Class<T> clazz, Object hashKey);
407
<T> T load(Class<T> clazz, Object hashKey, Object rangeKey);
408
<T> T load(T keyObject);
409
<T> T load(T keyObject, DynamoDBMapperConfig config);
410
<T> void save(T object);
411
<T> void save(T object, DynamoDBSaveExpression saveExpression, DynamoDBMapperConfig config);
412
<T> void delete(T object);
413
<T> void delete(T object, DynamoDBDeleteExpression deleteExpression, DynamoDBMapperConfig config);
414
415
// Batch operations
416
Map<String, List<Object>> batchLoad(Iterable<?> itemsToGet);
417
Map<String, List<Object>> batchLoad(Iterable<?> itemsToGet, DynamoDBMapperConfig config);
418
List<FailedBatch> batchWrite(Iterable<?> objectsToWrite, Iterable<?> objectsToDelete);
419
List<FailedBatch> batchWrite(Iterable<?> objectsToWrite, Iterable<?> objectsToDelete,
420
DynamoDBMapperConfig config);
421
422
// Query operations
423
<T> PaginatedQueryList<T> query(Class<T> clazz, DynamoDBQueryExpression<T> queryExpression);
424
<T> PaginatedQueryList<T> query(Class<T> clazz, DynamoDBQueryExpression<T> queryExpression,
425
DynamoDBMapperConfig config);
426
<T> QueryResultPage<T> queryPage(Class<T> clazz, DynamoDBQueryExpression<T> queryExpression);
427
428
// Scan operations
429
<T> PaginatedScanList<T> scan(Class<T> clazz, DynamoDBScanExpression scanExpression);
430
<T> PaginatedScanList<T> scan(Class<T> clazz, DynamoDBScanExpression scanExpression,
431
DynamoDBMapperConfig config);
432
<T> PaginatedParallelScanList<T> parallelScan(Class<T> clazz,
433
DynamoDBScanExpression scanExpression,
434
int totalSegments);
435
<T> ScanResultPage<T> scanPage(Class<T> clazz, DynamoDBScanExpression scanExpression);
436
437
// Count operations
438
int count(Class<?> clazz, DynamoDBScanExpression scanExpression);
439
<T> int count(Class<T> clazz, DynamoDBQueryExpression<T> queryExpression);
440
441
// Transaction operations
442
void transactionWrite(TransactionWriteRequest transactionWriteRequest,
443
DynamoDBMapperConfig config);
444
List<Object> transactionLoad(TransactionLoadRequest transactionLoadRequest,
445
DynamoDBMapperConfig config);
446
447
// Table generation
448
<T> CreateTableRequest generateCreateTableRequest(Class<T> clazz);
449
<T> DeleteTableRequest generateDeleteTableRequest(Class<T> clazz);
450
}
451
```
452
453
### Annotations
454
455
```java { .api }
456
package com.amazonaws.services.dynamodbv2.datamodeling;
457
458
// Mark class as DynamoDB table
459
@interface DynamoDBTable {
460
String tableName();
461
}
462
463
// Mark property as hash key (partition key)
464
@interface DynamoDBHashKey {
465
String attributeName() default "";
466
}
467
468
// Mark property as range key (sort key)
469
@interface DynamoDBRangeKey {
470
String attributeName() default "";
471
}
472
473
// Mark property as attribute
474
@interface DynamoDBAttribute {
475
String attributeName() default "";
476
}
477
478
// Mark property for optimistic locking (version check)
479
@interface DynamoDBVersionAttribute {
480
String attributeName() default "";
481
}
482
483
// Ignore property
484
@interface DynamoDBIgnore {
485
}
486
487
// Auto-generate UUID for key
488
@interface DynamoDBAutoGeneratedKey {
489
}
490
491
// Auto-generate timestamp
492
@interface DynamoDBAutoGeneratedTimestamp {
493
String strategy() default "CREATE";
494
}
495
496
// Mark properties for secondary indexes
497
@interface DynamoDBIndexHashKey {
498
String globalSecondaryIndexName() default "";
499
String[] globalSecondaryIndexNames() default {};
500
}
501
502
@interface DynamoDBIndexRangeKey {
503
String globalSecondaryIndexName() default "";
504
String[] globalSecondaryIndexNames() default {};
505
String localSecondaryIndexName() default "";
506
}
507
508
// Custom type conversion
509
@interface DynamoDBTypeConverted {
510
Class<? extends DynamoDBTypeConverter<?, ?>> converter();
511
}
512
513
// Mark class as document (nested object)
514
@interface DynamoDBDocument {
515
}
516
```
517
518
### Object Mapper Usage
519
520
```java
521
import com.amazonaws.services.dynamodbv2.datamodeling.*;
522
523
// Define POJO with annotations
524
@DynamoDBTable(tableName = "Users")
525
public class User {
526
private String id;
527
private String name;
528
private int age;
529
private boolean active;
530
private Long version;
531
532
@DynamoDBHashKey(attributeName = "id")
533
public String getId() { return id; }
534
public void setId(String id) { this.id = id; }
535
536
@DynamoDBAttribute(attributeName = "name")
537
public String getName() { return name; }
538
public void setName(String name) { this.name = name; }
539
540
@DynamoDBAttribute(attributeName = "age")
541
public int getAge() { return age; }
542
public void setAge(int age) { this.age = age; }
543
544
@DynamoDBAttribute(attributeName = "active")
545
public boolean isActive() { return active; }
546
public void setActive(boolean active) { this.active = active; }
547
548
@DynamoDBVersionAttribute
549
public Long getVersion() { return version; }
550
public void setVersion(Long version) { this.version = version; }
551
}
552
553
// Create mapper
554
DynamoDBMapper mapper = new DynamoDBMapper(dynamoDBClient);
555
556
// Save object
557
User user = new User();
558
user.setId("123");
559
user.setName("John Doe");
560
user.setAge(30);
561
user.setActive(true);
562
mapper.save(user);
563
564
// Load object
565
User loadedUser = mapper.load(User.class, "123");
566
System.out.println(loadedUser.getName());
567
568
// Update object
569
loadedUser.setAge(31);
570
mapper.save(loadedUser);
571
572
// Delete object
573
mapper.delete(loadedUser);
574
575
// Query with expression
576
User hashKeyValues = new User();
577
hashKeyValues.setId("123");
578
579
DynamoDBQueryExpression<User> queryExpression = new DynamoDBQueryExpression<User>()
580
.withHashKeyValues(hashKeyValues);
581
582
PaginatedQueryList<User> queryResult = mapper.query(User.class, queryExpression);
583
for (User u : queryResult) {
584
System.out.println(u.getName());
585
}
586
587
// Scan with filter
588
DynamoDBScanExpression scanExpression = new DynamoDBScanExpression()
589
.withFilterExpression("age > :min_age")
590
.withExpressionAttributeValues(Map.of(":min_age", new AttributeValue().withN("25")));
591
592
PaginatedScanList<User> scanResult = mapper.scan(User.class, scanExpression);
593
for (User u : scanResult) {
594
System.out.println(u.getName());
595
}
596
597
// Batch save
598
List<User> users = Arrays.asList(user1, user2, user3);
599
List<FailedBatch> failures = mapper.batchWrite(users, Collections.emptyList());
600
601
// Batch load
602
List<User> keysToLoad = Arrays.asList(keyUser1, keyUser2);
603
Map<String, List<Object>> results = mapper.batchLoad(keysToLoad);
604
605
// Create table from annotated class
606
CreateTableRequest tableRequest = mapper.generateCreateTableRequest(User.class);
607
tableRequest.setProvisionedThroughput(new ProvisionedThroughput(5L, 5L));
608
dynamoDBClient.createTable(tableRequest);
609
```
610
611
## Best Practices
612
613
### Data Modeling
614
- **Choose appropriate primary key**: Hash key for uniform distribution, range key for sorting
615
- **Use sparse indexes**: Save storage by only indexing items with specific attributes
616
- **Denormalize data**: Optimize for read patterns, duplicate data where necessary
617
- **Use composite keys**: Combine multiple attributes in sort keys for flexible queries
618
619
### Performance
620
- **Use batch operations**: batchGetItem and batchWriteItem reduce API calls
621
- **Enable auto-scaling**: Automatically adjust throughput based on demand
622
- **Use DynamoDB Streams**: Track changes without polling
623
- **Query over scan**: Queries are more efficient, use indexes when possible
624
625
### Consistency
626
- **Choose read consistency**: Eventually consistent reads (default) vs strongly consistent reads
627
- **Use conditional writes**: Prevent race conditions with condition expressions
628
- **Implement optimistic locking**: Use @DynamoDBVersionAttribute to detect concurrent modifications
629
630
### Cost Optimization
631
- **Use on-demand pricing**: For unpredictable workloads
632
- **Archive old data**: Use TTL or move to S3
633
- **Use projections**: Retrieve only needed attributes
634
- **Monitor capacity**: Avoid throttling by staying within limits
635