Trabalhar com itens: Java
Você pode usar a API de documentos do AWS SDK for Java para realizar operações create, read, update e delete (CRUD) típicas nos itens do Amazon DynamoDB em uma tabela.
nota
O SDK for Java também fornece um modelo de persistência de objetos que permite que você mapeie suas classes do lado do cliente para tabelas do DynamoDB. Essa abordagem pode reduzir a quantidade de código que você precisa escrever. Para ter mais informações, consulte Java 1.x: DynamoDBMapper.
Esta seção contém exemplos de Java para executar várias ações de itens da API de documento do Java e vários exemplos funcionais completos.
Tópicos
- Colocar um item
- Obter um item
- Gravação em lote: colocar e excluir vários itens
- Obtenção em lote: obter vários itens
- Atualizar um item
- Excluir um item
- Exemplo: operações CRUD usando a API de documento do AWS SDK for Java
- Exemplo: operações em lote usando a API de documento do AWS SDK for Java
- Exemplo: tratar atributos do tipo binário usando a API de documento do AWS SDK for Java
Colocar um item
O método putItem
armazena um item em uma tabela. Se o item existe, ele substitui o item inteiro. Em vez de substituir o item inteiro, se você quiser atualizar apenas atributos específicos, use o método updateItem
. Para ter mais informações, consulte Atualizar um item.
Especificar parâmetros opcionais
Além dos parâmetros obrigatórios, você também pode especificar parâmetros opcionais para o método putItem
. Por exemplo, o seguinte exemplo de código Java usa um parâmetro opcional para especificar uma condição para fazer upload do item. Se a condição que você especificar não for atendida, o AWS SDK for Java lançará uma ConditionalCheckFailedException
. O exemplo de código especifica os seguintes parâmetros opcionais no método putItem
:
-
Uma
ConditionExpression
que define as condições para a solicitação. O código define a condição de que o item existente com a mesma chave primária será substituído somente se tiver um atributo ISBN igual a um valor específico. -
Um mapa para
ExpressionAttributeValues
que é usado na condição. Nesse caso, existe apenas uma substituição obrigatória: o espaço reservado:val
na expressão de condição é substituído em tempo de execução pelo valor de ISBN real a ser verificado.
O exemplo a seguir adiciona um novo item de livro usando esses parâmetros opcionais.
exemplo
Item item = new Item() .withPrimaryKey("Id", 104) .withString("Title", "Book 104 Title") .withString("ISBN", "444-4444444444") .withNumber("Price", 20) .withStringSet("Authors", new HashSet<String>(Arrays.asList("Author1", "Author2"))); Map<String, Object> expressionAttributeValues = new HashMap<String, Object>(); expressionAttributeValues.put(":val", "444-4444444444"); PutItemOutcome outcome = table.putItem( item, "ISBN = :val", // ConditionExpression parameter null, // ExpressionAttributeNames parameter - we're not using it for this example expressionAttributeValues);
PutItem e documentos JSON
Você pode armazenar um documento JSON como um atributo em uma tabela do DynamoDB. Para fazer isso, use o método withJSON
de Item
. Esse método analisa o documento JSON e mapeia cada elemento em um tipo de dados nativo do DynamoDB.
Suponha que você quisesse armazenar o seguinte documento JSON que contém os fornecedores que podem atender a pedidos de um determinado produto.
exemplo
{ "V01": { "Name": "Acme Books", "Offices": [ "Seattle" ] }, "V02": { "Name": "New Publishers, Inc.", "Offices": ["London", "New York" ] }, "V03": { "Name": "Better Buy Books", "Offices": [ "Tokyo", "Los Angeles", "Sydney" ] } }
Você pode usar o método withJSON
para armazenar essas informações na tabela ProductCatalog
, em um atributo Map
chamado VendorInfo
. O exemplo de código Java a seguir demonstra como fazer isso.
// Convert the document into a String. Must escape all double-quotes. String vendorDocument = "{" + " \"V01\": {" + " \"Name\": \"Acme Books\"," + " \"Offices\": [ \"Seattle\" ]" + " }," + " \"V02\": {" + " \"Name\": \"New Publishers, Inc.\"," + " \"Offices\": [ \"London\", \"New York\"" + "]" + "}," + " \"V03\": {" + " \"Name\": \"Better Buy Books\"," + "\"Offices\": [ \"Tokyo\", \"Los Angeles\", \"Sydney\"" + " ]" + " }" + " }"; Item item = new Item() .withPrimaryKey("Id", 210) .withString("Title", "Book 210 Title") .withString("ISBN", "210-2102102102") .withNumber("Price", 30) .withJSON("VendorInfo", vendorDocument); PutItemOutcome outcome = table.putItem(item);
Obter um item
Para recuperar um único item, use o método getItem
de um objeto Table
. Siga estas etapas:
-
Crie uma instância da classe
DynamoDB
. -
Crie uma instância da classe
Table
para representar a tabela com a qual você deseja trabalhar. -
Chame o método
getItem
de instância deTable
. Você deve especificar a chave primária do item que deseja recuperar.
O exemplo de código Java a seguir demonstra as etapas anteriores. O código obtém o item que tem a chave de partição especificada.
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build(); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("ProductCatalog"); Item item = table.getItem("Id", 210);
Especificar parâmetros opcionais
Além dos parâmetros obrigatórios, você também pode especificar parâmetros opcionais do método getItem
. Por exemplo, o seguinte exemplo de código Java usa um método opcional para recuperar somente uma lista específica de atributos e para especificar leituras fortemente consistentes. (Para saber mais sobre a consistência de leitura, consulte Consistência de leitura do DynamoDB.)
Você pode usar uma ProjectionExpression
para recuperar somente atributos ou elementos específicos, em vez de todo o item. A ProjectionExpression
pode especificar atributos aninhados ou de alto nível, usando caminhos de documentos. Para ter mais informações, consulte Usar expressões de projeção no DynamoDB.
Os parâmetros do método getItem
não permitem que você especifique consistência de leitura. No entanto, você pode criar uma GetItemSpec
que dá acesso total a todas as entradas para a operação GetItem
de baixo nível. O exemplo de código a seguir cria uma GetItemSpec
e usa essa especificação como entrada para o método getItem
.
exemplo
GetItemSpec spec = new GetItemSpec() .withPrimaryKey("Id", 206) .withProjectionExpression("Id, Title, RelatedItems[0], Reviews.FiveStar") .withConsistentRead(true); Item item = table.getItem(spec); System.out.println(item.toJSONPretty());
Para imprimir um Item
em um formato legível, use o método toJSONPretty
. A saída do exemplo anterior é semelhante à seguinte.
{ "RelatedItems" : [ 341 ], "Reviews" : { "FiveStar" : [ "Excellent! Can't recommend it highly enough! Buy it!", "Do yourself a favor and buy this" ] }, "Id" : 123, "Title" : "20-Bicycle 123" }
GetItem e documentos JSON
Na seção PutItem e documentos JSON, você armazenou um documento JSON em um atributo Map
chamado VendorInfo
. Você pode usar o método getItem
para recuperar o documento inteiro no formato JSON. Ou pode usar a notação do caminho do documento para recuperar apenas alguns dos elementos no documento. O exemplo de código Java a seguir demonstra essas técnicas.
GetItemSpec spec = new GetItemSpec() .withPrimaryKey("Id", 210); System.out.println("All vendor info:"); spec.withProjectionExpression("VendorInfo"); System.out.println(table.getItem(spec).toJSON()); System.out.println("A single vendor:"); spec.withProjectionExpression("VendorInfo.V03"); System.out.println(table.getItem(spec).toJSON()); System.out.println("First office location for this vendor:"); spec.withProjectionExpression("VendorInfo.V03.Offices[0]"); System.out.println(table.getItem(spec).toJSON());
A saída do exemplo anterior é semelhante à seguinte.
All vendor info: {"VendorInfo":{"V03":{"Name":"Better Buy Books","Offices":["Tokyo","Los Angeles","Sydney"]},"V02":{"Name":"New Publishers, Inc.","Offices":["London","New York"]},"V01":{"Name":"Acme Books","Offices":["Seattle"]}}} A single vendor: {"VendorInfo":{"V03":{"Name":"Better Buy Books","Offices":["Tokyo","Los Angeles","Sydney"]}}} First office location for a single vendor: {"VendorInfo":{"V03":{"Offices":["Tokyo"]}}}
nota
Você pode usar o método toJSON
para converter qualquer item (ou seus atributos) em uma string formatada para JSON. O exemplo de código a seguir recupera vários atributos aninhados e de alto nível e imprime os resultados como JSON.
GetItemSpec spec = new GetItemSpec() .withPrimaryKey("Id", 210) .withProjectionExpression("VendorInfo.V01, Title, Price"); Item item = table.getItem(spec); System.out.println(item.toJSON());
A saída é semelhante à seguinte.
{"VendorInfo":{"V01":{"Name":"Acme Books","Offices":["Seattle"]}},"Price":30,"Title":"Book 210 Title"}
Gravação em lote: colocar e excluir vários itens
Gravação em lote se refere a inserir e excluir vários itens em um lote. O método batchWriteItem
permite que você insira e exclua vários itens de uma ou mais tabelas em uma única chamada. Veja a seguir as etapas para inserir ou excluir vários itens usando a API de documento do AWS SDK for Java.
-
Crie uma instância da classe
DynamoDB
. -
Crie uma instância da classe
TableWriteItems
que descreve todas as operações Put e Delete de uma tabela. Se você quiser gravar em várias tabelas com uma única operação de gravação em lote, crie uma instância deTableWriteItems
por tabela. -
Chame o método
batchWriteItem
fornecendo os objetosTableWriteItems
que você criou na etapa anterior. -
Processe a resposta. Você deve verificar se há itens de solicitação não processados retornados na resposta. Isso poderá acontecer se você atingir a cota de throughput provisionado ou por algum outro erro temporário. Além disso, o DynamoDB limita o tamanho da solicitação e o número de operações que você pode especificar em uma solicitação. Se você exceder esses limites, o DynamoDB rejeitará a solicitação. Para ter mais informações, consulte Service quotas, conta e cotas de tabela no Amazon DynamoDB.
O exemplo de código Java a seguir demonstra as etapas anteriores. O exemplo executa uma operação batchWriteItem
em duas tabelas: Forum
e Thread
. Os objetos TableWriteItems
correspondentes definem as seguintes ações:
-
Inserir um item na tabela
Forum
. -
Inserir e excluir um item na tabela
Thread
.
O código chama batchWriteItem
para executar a operação.
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build(); DynamoDB dynamoDB = new DynamoDB(client); TableWriteItems forumTableWriteItems = new TableWriteItems("Forum") .withItemsToPut( new Item() .withPrimaryKey("Name", "Amazon RDS") .withNumber("Threads", 0)); TableWriteItems threadTableWriteItems = new TableWriteItems("Thread") .withItemsToPut( new Item() .withPrimaryKey("ForumName","Amazon RDS","Subject","Amazon RDS Thread 1") .withHashAndRangeKeysToDelete("ForumName","Some partition key value", "Amazon S3", "Some sort key value"); BatchWriteItemOutcome outcome = dynamoDB.batchWriteItem(forumTableWriteItems, threadTableWriteItems); // Code for checking unprocessed items is omitted in this example
Para obter um exemplo funcional, consulte Exemplo: operação de gravação em lote usando a API de documento do AWS SDK for Java.
Obtenção em lote: obter vários itens
O método batchGetItem
permite que você recupere vários itens de uma ou mais tabelas. Para recuperar um único item, você pode usar o método getItem
.
Siga estas etapas:
-
Crie uma instância da classe
DynamoDB
. -
Crie uma instância da classe
TableKeysAndAttributes
que descreve uma lista de valores de chave primária para recuperar de uma tabela. Se você desejar ler em várias tabelas em uma única operação de aquisição em lote, será necessário criar uma instância deTableKeysAndAttributes
por tabela. -
Chame o método
batchGetItem
fornecendo os objetosTableKeysAndAttributes
que você criou na etapa anterior.
O exemplo de código Java a seguir demonstra as etapas anteriores. O exemplo recupera dois itens da tabela Forum
e três itens da tabela Thread
.
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build(); DynamoDB dynamoDB = new DynamoDB(client); TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes(forumTableName); forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name", "Amazon S3", "Amazon DynamoDB"); TableKeysAndAttributes threadTableKeysAndAttributes = new TableKeysAndAttributes(threadTableName); threadTableKeysAndAttributes.addHashAndRangePrimaryKeys("ForumName", "Subject", "Amazon DynamoDB","DynamoDB Thread 1", "Amazon DynamoDB","DynamoDB Thread 2", "Amazon S3","S3 Thread 1"); BatchGetItemOutcome outcome = dynamoDB.batchGetItem( forumTableKeysAndAttributes, threadTableKeysAndAttributes); for (String tableName : outcome.getTableItems().keySet()) { System.out.println("Items in table " + tableName); List<Item> items = outcome.getTableItems().get(tableName); for (Item item : items) { System.out.println(item); } }
Especificar parâmetros opcionais
Além dos parâmetros obrigatórios, você também pode especificar parâmetros opcionais ao usar batchGetItem
. Por exemplo, você pode fornecer uma ProjectionExpression
com cada TableKeysAndAttributes
que você definir. Isso permite que você especifique os atributos que deseja recuperar da tabela.
O exemplo de código a seguir recupera dois itens da tabela Forum
. O parâmetro withProjectionExpression
especifica que apenas o atributo Threads
deve ser recuperado.
exemplo
TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes("Forum") .withProjectionExpression("Threads"); forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name", "Amazon S3", "Amazon DynamoDB"); BatchGetItemOutcome outcome = dynamoDB.batchGetItem(forumTableKeysAndAttributes);
Atualizar um item
O método updateItem
de um objeto Table
pode atualizar valores de atributo existentes, adicionar novos atributos ou excluir atributos de um item existente.
O método updateItem
se comporta da seguinte forma:
-
Se não existir um item (não houver nenhum item na tabela com a chave primária especificada),
updateItem
adicionará um novo item à tabela -
Se existir um item,
updateItem
executará a atualização conforme especificado pelo parâmetroUpdateExpression
.
nota
Também é possível "atualizar" um item usando putItem
. Por exemplo, se você chamar putItem
para adicionar um item à tabela, mas já existir um item com a chave primária especificada, putItem
substituirá o item inteiro. Se houver atributos no item existente que não são especificados na entrada, putItem
removerá esses atributos do item.
Em geral, recomendamos que você use updateItem
sempre que desejar modificar quaisquer atributos de item. O método updateItem
só modifica os atributos de item que você especifica na entrada, e os outros atributos no item permanecem inalterados.
Siga estas etapas:
-
Crie uma instância da classe
Table
para representar a tabela com a qual você deseja trabalhar. -
Chame o método
updateTable
de instância deTable
. Você deve especificar a chave primária do item que deseja recuperar, juntamente com umaUpdateExpression
que descreve os atributos a serem modificados e como modificá-los.
O exemplo de código Java a seguir demonstra as tarefas anteriores. O código atualiza um item na tabela ProductCatalog
. Ele adiciona um novo autor ao conjunto de Authors
e exclui o atributo ISBN
existente. Ele também reduz o preço por um.
Um mapa ExpressionAttributeValues
é usado na UpdateExpression
. Os espaços reservados :val1
e :val2
serão substituídos em tempo de execução pelos valores reais de Authors
e Price
.
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build(); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("ProductCatalog"); Map<String, String> expressionAttributeNames = new HashMap<String, String>(); expressionAttributeNames.put("#A", "Authors"); expressionAttributeNames.put("#P", "Price"); expressionAttributeNames.put("#I", "ISBN"); Map<String, Object> expressionAttributeValues = new HashMap<String, Object>(); expressionAttributeValues.put(":val1", new HashSet<String>(Arrays.asList("Author YY","Author ZZ"))); expressionAttributeValues.put(":val2", 1); //Price UpdateItemOutcome outcome = table.updateItem( "Id", // key attribute name 101, // key attribute value "add #A :val1 set #P = #P - :val2 remove #I", // UpdateExpression expressionAttributeNames, expressionAttributeValues);
Especificar parâmetros opcionais
Além dos parâmetros obrigatórios, você também pode especificar parâmetros opcionais para o método updateItem
, incluindo uma condição que deve ser atendida para que a atualização ocorra. Se a condição que você especificar não for atendida, o AWS SDK for Java lançará uma ConditionalCheckFailedException
. Por exemplo, o seguinte exemplo de código Java atualiza condicionalmente o preço de item de um livro para 25. Ele especifica uma ConditionExpression
que declara que o preço deve ser atualizado somente se o preço existente for 20.
exemplo
Table table = dynamoDB.getTable("ProductCatalog"); Map<String, String> expressionAttributeNames = new HashMap<String, String>(); expressionAttributeNames.put("#P", "Price"); Map<String, Object> expressionAttributeValues = new HashMap<String, Object>(); expressionAttributeValues.put(":val1", 25); // update Price to 25... expressionAttributeValues.put(":val2", 20); //...but only if existing Price is 20 UpdateItemOutcome outcome = table.updateItem( new PrimaryKey("Id",101), "set #P = :val1", // UpdateExpression "#P = :val2", // ConditionExpression expressionAttributeNames, expressionAttributeValues);
Contador atômico
Você pode usar updateItem
para implementar um contador atômico, onde pode aumentar ou reduzir o valor de um atributo existente sem interferir em outras solicitações de gravação. Para aumentar um contador atômico, use uma UpdateExpression
com uma ação set
para adicionar um valor numérico a um atributo existente do tipo Number
.
O exemplo de código a seguir demonstra isso incrementando o atributo Quantity
em um. Ele também demonstra o uso do parâmetro ExpressionAttributeNames
em uma UpdateExpression
.
Table table = dynamoDB.getTable("ProductCatalog"); Map<String,String> expressionAttributeNames = new HashMap<String,String>(); expressionAttributeNames.put("#p", "PageCount"); Map<String,Object> expressionAttributeValues = new HashMap<String,Object>(); expressionAttributeValues.put(":val", 1); UpdateItemOutcome outcome = table.updateItem( "Id", 121, "set #p = #p + :val", expressionAttributeNames, expressionAttributeValues);
Excluir um item
O método deleteItem
exclui um item de uma tabela. É necessário fornecer a chave primária do item que você deseja excluir.
Siga estas etapas:
-
Crie uma instância do cliente
DynamoDB
. -
Chame o método
deleteItem
, fornecendo a chave do item que você deseja excluir.
O exemplo de código Java a seguir demonstra essas tarefas.
exemplo
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build(); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("ProductCatalog"); DeleteItemOutcome outcome = table.deleteItem("Id", 101);
Especificar parâmetros opcionais
Você pode especificar parâmetros opcionais para deleteItem
. Por exemplo, o seguinte exemplo de código Java especifica uma ConditionExpression
que declara que um item de livro em ProductCatalog
só pode ser excluído se o livro não estiver mais em publicação (o atributo InPublication
é falso).
exemplo
Map<String,Object> expressionAttributeValues = new HashMap<String,Object>(); expressionAttributeValues.put(":val", false); DeleteItemOutcome outcome = table.deleteItem("Id",103, "InPublication = :val", null, // ExpressionAttributeNames - not used in this example expressionAttributeValues);