com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTableMapper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aws-java-sdk-dynamodb Show documentation
Show all versions of aws-java-sdk-dynamodb Show documentation
The AWS Java SDK for Amazon DynamoDB module holds the client classes that are used for communicating with Amazon DynamoDB Service
/*
* Copyright 2016-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://aws.amazon.com/apache2.0
*
* This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
* OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and
* limitations under the License.
*/
package com.amazonaws.services.dynamodbv2.datamodeling;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBDeleteExpression;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBSaveExpression;
import com.amazonaws.services.dynamodbv2.model.ConditionalCheckFailedException;
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
import com.amazonaws.services.dynamodbv2.model.DeleteTableRequest;
import com.amazonaws.services.dynamodbv2.model.ExpectedAttributeValue;
import com.amazonaws.services.dynamodbv2.model.GlobalSecondaryIndex;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodbv2.model.ResourceInUseException;
import com.amazonaws.services.dynamodbv2.model.ResourceNotFoundException;
import com.amazonaws.services.dynamodbv2.model.TableDescription;
import com.amazonaws.services.s3.model.Region;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* A wrapper for {@code DynamoDBMapper} which operates only on a specified
* class/table. All calls are forwarded to the underlying
* {@code DynamoDBMapper} which was used to create this table mapper.
*
* A minimal example using get annotations,
*
* @DynamoDBTable(tableName="TestTable")
* public class TestClass {
* private Long key;
* private String rangeKey;
* private Double amount;
* private Long version;
*
* @DynamoDBHashKey
* public Long getKey() { return key; }
* public void setKey(Long key) { this.key = key; }
*
* @DynamoDBRangeKey
* public String getRangeKey() { return rangeKey; }
* public void setRangeKey(String rangeKey) { this.rangeKey = rangeKey; }
*
* @DynamoDBAttribute(attributeName="amount")
* public Double getAmount() { return amount; }
* public void setAmount(Double amount) { this.amount = amount; }
*
* @DynamoDBVersionAttribute
* public Long getVersion() { return version; }
* public void setVersion(Long version) { this.version = version; }
* }
*
*
* Initialize the DynamoDB mapper,
*
* AmazonDynamoDB dbClient = new AmazonDynamoDBClient();
* DynamoDBMapper dbMapper = new DynamoDBMapper(dbClient);
*
*
* Then, create a new table mapper with hash and range key,
*
* DynamoDBTableMapper<TestClass,Long,String> mapper = dbMapper.newTableMapper(TestClass.class);
*
*
* Or, if the table does not have a range key,
*
* DynamoDBTableMapper<TestClass,Long,?> table = dbMapper.newTableMapper(TestClass.class);
*
*
* If you don't have your DynamoDB table set up yet, you can use,
*
* table.createTableIfNotExists(new ProvisionedThroughput(25L, 25L));
*
*
* Save instances of annotated classes and retrieve them,
*
* TestClass object = new TestClass();
* object.setKey(1234L);
* object.setRangeKey("ABCD");
* object.setAmount(101D);
*
* try {
* table.saveIfNotExists(object);
* } catch (ConditionalCheckFailedException e) {
* // handle already existing
* }
*
*
* Execute a query operation,
*
* int limit = 10;
* List<TestClass> objects = new ArrayList<TestClass>(limit);
*
* DynamoDBQueryExpression<TestClass> query = new DynamoDBQueryExpression()
* .withRangeKeyCondition(table.rangeKey().name(), table.rangeKey().ge("ABAA"))
* .withQueryFilterEntry("amount", table.field("amount").gt(100D))
* .withHashKeyValues(1234L)
* .withConsistentReads(true);
*
* QueryResultPage<TestClass> results = new QueryResultPage<TestClass>();
*
* do {
* if (results.getLastEvaluatedKey() != null) {
* query.setExclusiveStartKey(results.getLastEvaluatedKey());
* }
* query.setLimit(limit - objects.size());
* results = mapper.query(query);
* for (TestClass object : results.getResults()) {
* objects.add(object);
* }
* } while (results.getLastEvaluatedKey() != null && objects.size() < limit)
*
*
* @param The object type which this mapper operates.
* @param The hash key value type.
* @param The range key value type; use ?
if no range key.
*
* @see com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper
* @see com.amazonaws.services.dynamodbv2.AmazonDynamoDB
*/
public final class DynamoDBTableMapper {
private static final Log LOG = LogFactory.getLog(DynamoDBTableMapper.class);
private final DynamoDBMapperTableModel model;
private final DynamoDBMapperFieldModel hk;
private final DynamoDBMapperFieldModel rk;
private final DynamoDBMapperConfig config;
private final DynamoDBMapper mapper;
private final AmazonDynamoDB db;
/**
* Constructs a new table mapper for the given class.
* @param model The field model factory.
* @param mapper The DynamoDB mapper.
* @param db The service object to use for all service calls.
*/
protected DynamoDBTableMapper(AmazonDynamoDB db, DynamoDBMapper mapper, final DynamoDBMapperConfig config, final DynamoDBMapperTableModel model) {
this.rk = model.rangeKeyIfExists();
this.hk = model.hashKey();
this.model = model;
this.config = config;
this.mapper = mapper;
this.db = db;
}
/**
* Gets the field model for a given attribute.
* @param The field model's value type.
* @param attributeName The attribute name.
* @return The field model.
*/
public DynamoDBMapperFieldModel field(String attributeName) {
return this.model.field(attributeName);
}
/**
* Gets the hash key field model for the specified type.
* @param The hash key type.
* @return The hash key field model.
* @throws DynamoDBMappingException If the hash key is not present.
*/
public DynamoDBMapperFieldModel hashKey() {
return this.model.hashKey();
}
/**
* Gets the range key field model for the specified type.
* @param The range key type.
* @return The range key field model.
* @throws DynamoDBMappingException If the range key is not present.
*/
public DynamoDBMapperFieldModel rangeKey() {
return this.model.rangeKey();
}
/**
* Retrieves multiple items from the table using their primary keys.
* @param itemsToGet The items to get.
* @return The list of objects.
* @see com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper#batchLoad
*/
public List batchLoad(Iterable itemsToGet) {
final Map> results = mapper.batchLoad(itemsToGet);
if (results.isEmpty()) {
return Collections.emptyList();
}
return (List)results.get(mapper.getTableName(model.targetType(), config));
}
/**
* Saves the objects given using one or more calls to the batchWriteItem API.
* @param objectsToSave The objects to save.
* @return The list of failed batches.
* @see com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper#batchSave
*/
public List batchSave(Iterable objectsToSave) {
return mapper.batchWrite(objectsToSave, (Iterable)Collections.emptyList());
}
/**
* Deletes the objects given using one or more calls to the batchWtiteItem API.
* @param objectsToDelete The objects to delete.
* @return The list of failed batches.
* @see com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper#batchDelete
*/
public List batchDelete(Iterable objectsToDelete) {
return mapper.batchWrite((Iterable)Collections.emptyList(), objectsToDelete);
}
/**
* Saves and deletes the objects given using one or more calls to the
* batchWriteItem API.
* @param objectsToWrite The objects to write.
* @param objectsToDelete The objects to delete.
* @return The list of failed batches.
* @see com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper#batchWrite
*/
public List batchWrite(Iterable objectsToWrite, Iterable objectsToDelete) {
return mapper.batchWrite(objectsToWrite, objectsToDelete);
}
/**
* Transactionally writes objects specified by transactionWriteRequest by calling
* {@link com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper#transactionWrite(TransactionWriteRequest)} API.
* @param transactionWriteRequest List of objects to write
* @see com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper#transactionWrite(TransactionWriteRequest)
*/
public void transactionWrite(TransactionWriteRequest transactionWriteRequest) {
for (TransactionWriteRequest.TransactionWriteOperation transactionWriteOperation : transactionWriteRequest.getTransactionWriteOperations()) {
if (!model.targetType().equals(transactionWriteOperation.getObject().getClass())) {
throw new DynamoDBMappingException("Input object is of the classType: " + transactionWriteOperation.getObject().getClass()
+ " but tableMapper is declared with classType: " + model.targetType());
}
}
mapper.transactionWrite(transactionWriteRequest);
}
/**
* Transactionally loads objects specified by transactionLoadRequest by calling
* {@link com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper#transactionLoad(TransactionLoadRequest)} API.
* @param transactionLoadRequest List of objects to load
* @return List of objects
* @see com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper#transactionLoad(TransactionLoadRequest)
*/
public List