Java 2.x용 SDK를 사용하는 DynamoDB 예제 - AWS SDK for Java 2.x

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

Java 2.x용 SDK를 사용하는 DynamoDB 예제

다음 코드 예제에서는 DynamoDB와 AWS SDK for Java 2.x 함께를 사용하여 작업을 수행하고 일반적인 시나리오를 구현하는 방법을 보여줍니다.

기본 사항은 서비스 내에서 필수 작업을 수행하는 방법을 보여주는 코드 예제입니다.

작업은 대규모 프로그램에서 발췌한 코드이며 컨텍스트에 맞춰 실행해야 합니다. 작업은 관련 시나리오의 컨텍스트에 따라 표시되며, 개별 서비스 함수를 직접적으로 호출하는 방법을 보여줍니다.

시나리오는 동일한 서비스 내에서 또는 다른 AWS 서비스와 결합된 상태에서 여러 함수를 호출하여 특정 태스크를 수행하는 방법을 보여주는 코드 예제입니다.

AWS 커뮤니티 기여는 여러 팀이 생성하고 유지 관리하는 예입니다 AWS. 피드백을 제공하려면 연결된 리포지토리에 제공된 메커니즘을 사용합니다.

각 예시에는 전체 소스 코드에 대한 링크가 포함되어 있으며, 여기에서 컨텍스트에 맞춰 코드를 설정하고 실행하는 방법에 대한 지침을 찾을 수 있습니다.

시작

다음 코드 예제에서는 DynamoDB를 사용하여 시작하는 방법을 보여 줍니다.

SDK for Java 2.x
참고

GitHub에 더 많은 내용이 있습니다. AWS 코드 예 리포지토리에서 전체 예를 찾고 설정 및 실행하는 방법을 배워보세요.

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.services.dynamodb.model.ListTablesRequest; import software.amazon.awssdk.services.dynamodb.model.ListTablesResponse; import java.util.List; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class ListTables { public static void main(String[] args) { System.out.println("Listing your Amazon DynamoDB tables:\n"); Region region = Region.US_EAST_1; DynamoDbClient ddb = DynamoDbClient.builder() .region(region) .build(); listAllTables(ddb); ddb.close(); } public static void listAllTables(DynamoDbClient ddb) { boolean moreTables = true; String lastName = null; while (moreTables) { try { ListTablesResponse response = null; if (lastName == null) { ListTablesRequest request = ListTablesRequest.builder().build(); response = ddb.listTables(request); } else { ListTablesRequest request = ListTablesRequest.builder() .exclusiveStartTableName(lastName).build(); response = ddb.listTables(request); } List<String> tableNames = response.tableNames(); if (tableNames.size() > 0) { for (String curName : tableNames) { System.out.format("* %s\n", curName); } } else { System.out.println("No tables found!"); System.exit(0); } lastName = response.lastEvaluatedTableName(); if (lastName == null) { moreTables = false; } } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } } System.out.println("\nDone!"); } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조ListTables를 참조하세요.

기본 사항

다음 코드 예제는 다음과 같은 작업을 수행하는 방법을 보여줍니다.

  • 영화 데이터를 저장할 수 있는 테이블을 생성합니다.

  • 테이블에 하나의 영화를 추가하고 가져오고 업데이트합니다.

  • 샘플 JSON 파일에서 테이블에 영화 데이터를 씁니다.

  • 특정 연도에 개봉된 영화를 쿼리합니다.

  • 특정 연도 범위 동안 개봉된 영화를 스캔합니다.

  • 테이블에서 영화를 삭제한 다음, 테이블을 삭제합니다.

SDK for Java 2.x
참고

GitHub에 더 많은 내용이 있습니다. AWS 코드 예 리포지토리에서 전체 예를 찾고 설정 및 실행하는 방법을 배워보세요.

DynamoDB 테이블을 생성합니다.

// Create a table with a Sort key. public static void createTable(DynamoDbClient ddb, String tableName) { DynamoDbWaiter dbWaiter = ddb.waiter(); ArrayList<AttributeDefinition> attributeDefinitions = new ArrayList<>(); // Define attributes. attributeDefinitions.add(AttributeDefinition.builder() .attributeName("year") .attributeType("N") .build()); attributeDefinitions.add(AttributeDefinition.builder() .attributeName("title") .attributeType("S") .build()); ArrayList<KeySchemaElement> tableKey = new ArrayList<>(); KeySchemaElement key = KeySchemaElement.builder() .attributeName("year") .keyType(KeyType.HASH) .build(); KeySchemaElement key2 = KeySchemaElement.builder() .attributeName("title") .keyType(KeyType.RANGE) .build(); // Add KeySchemaElement objects to the list. tableKey.add(key); tableKey.add(key2); CreateTableRequest request = CreateTableRequest.builder() .keySchema(tableKey) .billingMode(BillingMode.PAY_PER_REQUEST) // DynamoDB automatically scales based on traffic. .attributeDefinitions(attributeDefinitions) .tableName(tableName) .build(); try { CreateTableResponse response = ddb.createTable(request); DescribeTableRequest tableRequest = DescribeTableRequest.builder() .tableName(tableName) .build(); // Wait until the Amazon DynamoDB table is created. WaiterResponse<DescribeTableResponse> waiterResponse = dbWaiter.waitUntilTableExists(tableRequest); waiterResponse.matched().response().ifPresent(System.out::println); String newTable = response.tableDescription().tableName(); System.out.println("The " + newTable + " was successfully created."); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } }

헬퍼 함수를 생성하여 샘플 JSON 파일을 다운로드하고 추출합니다.

// Load data into the table. public static void loadData(DynamoDbClient ddb, String tableName, String fileName) throws IOException { DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder() .dynamoDbClient(ddb) .build(); DynamoDbTable<Movies> mappedTable = enhancedClient.table("Movies", TableSchema.fromBean(Movies.class)); JsonParser parser = new JsonFactory().createParser(new File(fileName)); com.fasterxml.jackson.databind.JsonNode rootNode = new ObjectMapper().readTree(parser); Iterator<JsonNode> iter = rootNode.iterator(); ObjectNode currentNode; int t = 0; while (iter.hasNext()) { // Only add 200 Movies to the table. if (t == 200) break; currentNode = (ObjectNode) iter.next(); int year = currentNode.path("year").asInt(); String title = currentNode.path("title").asText(); String info = currentNode.path("info").toString(); Movies movies = new Movies(); movies.setYear(year); movies.setTitle(title); movies.setInfo(info); // Put the data into the Amazon DynamoDB Movie table. mappedTable.putItem(movies); t++; } }

테이블에서 항목을 가져옵니다.

public static void getItem(DynamoDbClient ddb) { HashMap<String, AttributeValue> keyToGet = new HashMap<>(); keyToGet.put("year", AttributeValue.builder() .n("1933") .build()); keyToGet.put("title", AttributeValue.builder() .s("King Kong") .build()); GetItemRequest request = GetItemRequest.builder() .key(keyToGet) .tableName("Movies") .build(); try { Map<String, AttributeValue> returnedItem = ddb.getItem(request).item(); if (returnedItem != null) { Set<String> keys = returnedItem.keySet(); System.out.println("Amazon DynamoDB table attributes: \n"); for (String key1 : keys) { System.out.format("%s: %s\n", key1, returnedItem.get(key1).toString()); } } else { System.out.format("No item found with the key %s!\n", "year"); } } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } }

전체 예제는 다음과 같습니다.

/** * Before running this Java V2 code example, set up your development * environment, including your credentials. * <p> * For more information, see the following documentation topic: * <p> * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html * <p> * This Java example performs these tasks: * <p> * 1. Creates the Amazon DynamoDB Movie table with partition and sort key. * 2. Puts data into the Amazon DynamoDB table from a JSON document using the * Enhanced client. * 3. Gets data from the Movie table. * 4. Adds a new item. * 5. Updates an item. * 6. Uses a Scan to query items using the Enhanced client. * 7. Queries all items where the year is 2013 using the Enhanced Client. * 8. Deletes the table. */ public class Scenario { public static final String DASHES = new String(new char[80]).replace("\0", "-"); public static void main(String[] args) throws IOException { String tableName = "Movies"; String fileName = "../../../resources/sample_files/movies.json"; Region region = Region.US_EAST_1; DynamoDbClient ddb = DynamoDbClient.builder() .region(region) .build(); System.out.println(DASHES); System.out.println("Welcome to the Amazon DynamoDB example scenario."); System.out.println(DASHES); System.out.println(DASHES); System.out.println( "1. Creating an Amazon DynamoDB table named Movies with a key named year and a sort key named title."); createTable(ddb, tableName); System.out.println(DASHES); System.out.println(DASHES); System.out.println("2. Loading data into the Amazon DynamoDB table."); loadData(ddb, tableName, fileName); System.out.println(DASHES); System.out.println(DASHES); System.out.println("3. Getting data from the Movie table."); getItem(ddb); System.out.println(DASHES); System.out.println(DASHES); System.out.println("4. Putting a record into the Amazon DynamoDB table."); putRecord(ddb); System.out.println(DASHES); System.out.println(DASHES); System.out.println("5. Updating a record."); updateTableItem(ddb, tableName); System.out.println(DASHES); System.out.println(DASHES); System.out.println("6. Scanning the Amazon DynamoDB table."); scanMovies(ddb, tableName); System.out.println(DASHES); System.out.println(DASHES); System.out.println("7. Querying the Movies released in 2013."); queryTable(ddb); System.out.println(DASHES); System.out.println(DASHES); System.out.println("8. Deleting the Amazon DynamoDB table."); deleteDynamoDBTable(ddb, tableName); System.out.println(DASHES); ddb.close(); } // Create a table with a Sort key. public static void createTable(DynamoDbClient ddb, String tableName) { DynamoDbWaiter dbWaiter = ddb.waiter(); ArrayList<AttributeDefinition> attributeDefinitions = new ArrayList<>(); // Define attributes. attributeDefinitions.add(AttributeDefinition.builder() .attributeName("year") .attributeType("N") .build()); attributeDefinitions.add(AttributeDefinition.builder() .attributeName("title") .attributeType("S") .build()); ArrayList<KeySchemaElement> tableKey = new ArrayList<>(); KeySchemaElement key = KeySchemaElement.builder() .attributeName("year") .keyType(KeyType.HASH) .build(); KeySchemaElement key2 = KeySchemaElement.builder() .attributeName("title") .keyType(KeyType.RANGE) .build(); // Add KeySchemaElement objects to the list. tableKey.add(key); tableKey.add(key2); CreateTableRequest request = CreateTableRequest.builder() .keySchema(tableKey) .billingMode(BillingMode.PAY_PER_REQUEST) // DynamoDB automatically scales based on traffic. .attributeDefinitions(attributeDefinitions) .tableName(tableName) .build(); try { CreateTableResponse response = ddb.createTable(request); DescribeTableRequest tableRequest = DescribeTableRequest.builder() .tableName(tableName) .build(); // Wait until the Amazon DynamoDB table is created. WaiterResponse<DescribeTableResponse> waiterResponse = dbWaiter.waitUntilTableExists(tableRequest); waiterResponse.matched().response().ifPresent(System.out::println); String newTable = response.tableDescription().tableName(); System.out.println("The " + newTable + " was successfully created."); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } } // Query the table. public static void queryTable(DynamoDbClient ddb) { try { DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder() .dynamoDbClient(ddb) .build(); DynamoDbTable<Movies> custTable = enhancedClient.table("Movies", TableSchema.fromBean(Movies.class)); QueryConditional queryConditional = QueryConditional .keyEqualTo(Key.builder() .partitionValue(2013) .build()); // Get items in the table and write out the ID value. Iterator<Movies> results = custTable.query(queryConditional).items().iterator(); String result = ""; while (results.hasNext()) { Movies rec = results.next(); System.out.println("The title of the movie is " + rec.getTitle()); System.out.println("The movie information is " + rec.getInfo()); } } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } } // Scan the table. public static void scanMovies(DynamoDbClient ddb, String tableName) { System.out.println("******* Scanning all movies.\n"); try { DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder() .dynamoDbClient(ddb) .build(); DynamoDbTable<Movies> custTable = enhancedClient.table("Movies", TableSchema.fromBean(Movies.class)); Iterator<Movies> results = custTable.scan().items().iterator(); while (results.hasNext()) { Movies rec = results.next(); System.out.println("The movie title is " + rec.getTitle()); System.out.println("The movie year is " + rec.getYear()); } } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } } // Load data into the table. public static void loadData(DynamoDbClient ddb, String tableName, String fileName) throws IOException { DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder() .dynamoDbClient(ddb) .build(); DynamoDbTable<Movies> mappedTable = enhancedClient.table("Movies", TableSchema.fromBean(Movies.class)); JsonParser parser = new JsonFactory().createParser(new File(fileName)); com.fasterxml.jackson.databind.JsonNode rootNode = new ObjectMapper().readTree(parser); Iterator<JsonNode> iter = rootNode.iterator(); ObjectNode currentNode; int t = 0; while (iter.hasNext()) { // Only add 200 Movies to the table. if (t == 200) break; currentNode = (ObjectNode) iter.next(); int year = currentNode.path("year").asInt(); String title = currentNode.path("title").asText(); String info = currentNode.path("info").toString(); Movies movies = new Movies(); movies.setYear(year); movies.setTitle(title); movies.setInfo(info); // Put the data into the Amazon DynamoDB Movie table. mappedTable.putItem(movies); t++; } } // Update the record to include show only directors. public static void updateTableItem(DynamoDbClient ddb, String tableName) { HashMap<String, AttributeValue> itemKey = new HashMap<>(); itemKey.put("year", AttributeValue.builder().n("1933").build()); itemKey.put("title", AttributeValue.builder().s("King Kong").build()); HashMap<String, AttributeValueUpdate> updatedValues = new HashMap<>(); updatedValues.put("info", AttributeValueUpdate.builder() .value(AttributeValue.builder().s("{\"directors\":[\"Merian C. Cooper\",\"Ernest B. Schoedsack\"]") .build()) .action(AttributeAction.PUT) .build()); UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(itemKey) .attributeUpdates(updatedValues) .build(); try { ddb.updateItem(request); } catch (ResourceNotFoundException e) { System.err.println(e.getMessage()); System.exit(1); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } System.out.println("Item was updated!"); } public static void deleteDynamoDBTable(DynamoDbClient ddb, String tableName) { DeleteTableRequest request = DeleteTableRequest.builder() .tableName(tableName) .build(); try { ddb.deleteTable(request); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } System.out.println(tableName + " was successfully deleted!"); } public static void putRecord(DynamoDbClient ddb) { try { DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder() .dynamoDbClient(ddb) .build(); DynamoDbTable<Movies> table = enhancedClient.table("Movies", TableSchema.fromBean(Movies.class)); // Populate the Table. Movies record = new Movies(); record.setYear(2020); record.setTitle("My Movie2"); record.setInfo("no info"); table.putItem(record); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } System.out.println("Added a new movie to the table."); } public static void getItem(DynamoDbClient ddb) { HashMap<String, AttributeValue> keyToGet = new HashMap<>(); keyToGet.put("year", AttributeValue.builder() .n("1933") .build()); keyToGet.put("title", AttributeValue.builder() .s("King Kong") .build()); GetItemRequest request = GetItemRequest.builder() .key(keyToGet) .tableName("Movies") .build(); try { Map<String, AttributeValue> returnedItem = ddb.getItem(request).item(); if (returnedItem != null) { Set<String> keys = returnedItem.keySet(); System.out.println("Amazon DynamoDB table attributes: \n"); for (String key1 : keys) { System.out.format("%s: %s\n", key1, returnedItem.get(key1).toString()); } } else { System.out.format("No item found with the key %s!\n", "year"); } } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } } }

작업

다음 코드 예시는 BatchGetItem의 사용 방법을 보여 줍니다.

SDK for Java 2.x
참고

GitHub에 더 많은 내용이 있습니다. AWS 코드 예 리포지토리에서 전체 예를 찾고 설정 및 실행하는 방법을 배워보세요.

서비스 클라이언트를 사용하여 배치 항목을 가져오는 방법을 보여줍니다.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.BatchGetItemRequest; import software.amazon.awssdk.services.dynamodb.model.BatchGetItemResponse; import software.amazon.awssdk.services.dynamodb.model.KeysAndAttributes; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Before running this Java V2 code example, set up your development environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class BatchReadItems { public static void main(String[] args){ final String usage = """ Usage: <tableName> Where: tableName - The Amazon DynamoDB table (for example, Music).\s """; String tableName = "Music"; Region region = Region.US_EAST_1; DynamoDbClient dynamoDbClient = DynamoDbClient.builder() .region(region) .build(); getBatchItems(dynamoDbClient, tableName); } public static void getBatchItems(DynamoDbClient dynamoDbClient, String tableName) { // Define the primary key values for the items you want to retrieve. Map<String, AttributeValue> key1 = new HashMap<>(); key1.put("Artist", AttributeValue.builder().s("Artist1").build()); Map<String, AttributeValue> key2 = new HashMap<>(); key2.put("Artist", AttributeValue.builder().s("Artist2").build()); // Construct the batchGetItem request. Map<String, KeysAndAttributes> requestItems = new HashMap<>(); requestItems.put(tableName, KeysAndAttributes.builder() .keys(List.of(key1, key2)) .projectionExpression("Artist, SongTitle") .build()); BatchGetItemRequest batchGetItemRequest = BatchGetItemRequest.builder() .requestItems(requestItems) .build(); // Make the batchGetItem request. BatchGetItemResponse batchGetItemResponse = dynamoDbClient.batchGetItem(batchGetItemRequest); // Extract and print the retrieved items. Map<String, List<Map<String, AttributeValue>>> responses = batchGetItemResponse.responses(); if (responses.containsKey(tableName)) { List<Map<String, AttributeValue>> musicItems = responses.get(tableName); for (Map<String, AttributeValue> item : musicItems) { System.out.println("Artist: " + item.get("Artist").s() + ", SongTitle: " + item.get("SongTitle").s()); } } else { System.out.println("No items retrieved."); } } }

서비스 클라이언트와 페이지네이터를 사용하여 배치 항목을 가져오는 방법을 보여줍니다.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.BatchGetItemRequest; import software.amazon.awssdk.services.dynamodb.model.KeysAndAttributes; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; public class BatchGetItemsPaginator { public static void main(String[] args){ final String usage = """ Usage: <tableName> Where: tableName - The Amazon DynamoDB table (for example, Music).\s """; String tableName = "Music"; Region region = Region.US_EAST_1; DynamoDbClient dynamoDbClient = DynamoDbClient.builder() .region(region) .build(); getBatchItemsPaginator(dynamoDbClient, tableName) ; } public static void getBatchItemsPaginator(DynamoDbClient dynamoDbClient, String tableName) { // Define the primary key values for the items you want to retrieve. Map<String, AttributeValue> key1 = new HashMap<>(); key1.put("Artist", AttributeValue.builder().s("Artist1").build()); Map<String, AttributeValue> key2 = new HashMap<>(); key2.put("Artist", AttributeValue.builder().s("Artist2").build()); // Construct the batchGetItem request. Map<String, KeysAndAttributes> requestItems = new HashMap<>(); requestItems.put(tableName, KeysAndAttributes.builder() .keys(List.of(key1, key2)) .projectionExpression("Artist, SongTitle") .build()); BatchGetItemRequest batchGetItemRequest = BatchGetItemRequest.builder() .requestItems(requestItems) .build(); // Use batchGetItemPaginator for paginated requests. dynamoDbClient.batchGetItemPaginator(batchGetItemRequest).stream() .flatMap(response -> response.responses().getOrDefault(tableName, Collections.emptyList()).stream()) .forEach(item -> { System.out.println("Artist: " + item.get("Artist").s() + ", SongTitle: " + item.get("SongTitle").s()); }); } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조BatchGetItem을 참조하세요.

다음 코드 예시는 BatchWriteItem의 사용 방법을 보여 줍니다.

SDK for Java 2.x
참고

GitHub에 더 많은 내용이 있습니다. AWS 코드 예 리포지토리에서 전체 예를 찾고 설정 및 실행하는 방법을 배워보세요.

서비스 클라이언트를 사용하여 테이블에 많은 항목을 삽입합니다.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.BatchWriteItemRequest; import software.amazon.awssdk.services.dynamodb.model.BatchWriteItemResponse; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.PutRequest; import software.amazon.awssdk.services.dynamodb.model.WriteRequest; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Before running this Java V2 code example, set up your development environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class BatchWriteItems { public static void main(String[] args){ final String usage = """ Usage: <tableName> Where: tableName - The Amazon DynamoDB table (for example, Music).\s """; String tableName = "Music"; Region region = Region.US_EAST_1; DynamoDbClient dynamoDbClient = DynamoDbClient.builder() .region(region) .build(); addBatchItems(dynamoDbClient, tableName); } public static void addBatchItems(DynamoDbClient dynamoDbClient, String tableName) { // Specify the updates you want to perform. List<WriteRequest> writeRequests = new ArrayList<>(); // Set item 1. Map<String, AttributeValue> item1Attributes = new HashMap<>(); item1Attributes.put("Artist", AttributeValue.builder().s("Artist1").build()); item1Attributes.put("Rating", AttributeValue.builder().s("5").build()); item1Attributes.put("Comments", AttributeValue.builder().s("Great song!").build()); item1Attributes.put("SongTitle", AttributeValue.builder().s("SongTitle1").build()); writeRequests.add(WriteRequest.builder().putRequest(PutRequest.builder().item(item1Attributes).build()).build()); // Set item 2. Map<String, AttributeValue> item2Attributes = new HashMap<>(); item2Attributes.put("Artist", AttributeValue.builder().s("Artist2").build()); item2Attributes.put("Rating", AttributeValue.builder().s("4").build()); item2Attributes.put("Comments", AttributeValue.builder().s("Nice melody.").build()); item2Attributes.put("SongTitle", AttributeValue.builder().s("SongTitle2").build()); writeRequests.add(WriteRequest.builder().putRequest(PutRequest.builder().item(item2Attributes).build()).build()); try { // Create the BatchWriteItemRequest. BatchWriteItemRequest batchWriteItemRequest = BatchWriteItemRequest.builder() .requestItems(Map.of(tableName, writeRequests)) .build(); // Execute the BatchWriteItem operation. BatchWriteItemResponse batchWriteItemResponse = dynamoDbClient.batchWriteItem(batchWriteItemRequest); // Process the response. System.out.println("Batch write successful: " + batchWriteItemResponse); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } } }

향상된 클라이언트를 사용하여 테이블에 많은 항목을 삽입합니다.

import com.example.dynamodb.Customer; import com.example.dynamodb.Music; 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.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; /* * Before running this code example, create an Amazon DynamoDB table named Customer with these columns: * - id - the id of the record that is the key * - custName - the customer name * - email - the email value * - registrationDate - an instant value when the item was added to the table * * Also, ensure that you have set up your development environment, including your credentials. * * For information, see this documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class EnhancedBatchWriteItems { public static void main(String[] args) { Region region = Region.US_EAST_1; DynamoDbClient ddb = DynamoDbClient.builder() .region(region) .build(); DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder() .dynamoDbClient(ddb) .build(); putBatchRecords(enhancedClient); ddb.close(); } public static void putBatchRecords(DynamoDbEnhancedClient enhancedClient) { try { DynamoDbTable<Customer> customerMappedTable = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class)); DynamoDbTable<Music> musicMappedTable = enhancedClient.table("Music", TableSchema.fromBean(Music.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("[email protected]"); record2.setRegistrationDate(instant); Customer record3 = new Customer(); record3.setCustName("Susan Pink"); record3.setId("id120"); record3.setEmail("[email protected]"); record3.setRegistrationDate(instant); Customer record4 = new Customer(); record4.setCustName("Jerry orange"); record4.setId("id101"); record4.setEmail("[email protected]"); record4.setRegistrationDate(instant); BatchWriteItemEnhancedRequest batchWriteItemEnhancedRequest = BatchWriteItemEnhancedRequest .builder() .writeBatches( WriteBatch.builder(Customer.class) // add items to the Customer // table .mappedTableResource(customerMappedTable) .addPutItem(builder -> builder.item(record2)) .addPutItem(builder -> builder.item(record3)) .addPutItem(builder -> builder.item(record4)) .build(), WriteBatch.builder(Music.class) // delete an item from the Music // table .mappedTableResource(musicMappedTable) .addDeleteItem(builder -> builder.key( Key.builder().partitionValue( "Famous Band") .build())) .build()) .build(); // Add three items to the Customer table and delete one item from the Music // table. enhancedClient.batchWriteItem(batchWriteItemEnhancedRequest); System.out.println("done"); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조BatchWriteItem을 참조하세요.

다음 코드 예시는 CreateTable의 사용 방법을 보여 줍니다.

SDK for Java 2.x
참고

GitHub에 더 많은 내용이 있습니다. AWS 코드 예제 리포지토리에서 전체 예제를 찾고 설정 및 실행하는 방법을 배워보세요.

import software.amazon.awssdk.core.waiters.WaiterResponse; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeDefinition; import software.amazon.awssdk.services.dynamodb.model.BillingMode; import software.amazon.awssdk.services.dynamodb.model.CreateTableRequest; import software.amazon.awssdk.services.dynamodb.model.CreateTableResponse; import software.amazon.awssdk.services.dynamodb.model.DescribeTableRequest; import software.amazon.awssdk.services.dynamodb.model.DescribeTableResponse; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.KeySchemaElement; import software.amazon.awssdk.services.dynamodb.model.KeyType; import software.amazon.awssdk.services.dynamodb.model.OnDemandThroughput; import software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughput; import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType; import software.amazon.awssdk.services.dynamodb.waiters.DynamoDbWaiter; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * <p> * For more information, see the following documentation topic: * <p> * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class CreateTable { public static void main(String[] args) { final String usage = """ Usage: <tableName> <key> Where: tableName - The Amazon DynamoDB table to create (for example, Music3). key - The key for the Amazon DynamoDB table (for example, Artist). """; if (args.length != 2) { System.out.println(usage); System.exit(1); } String tableName = args[0]; String key = args[1]; System.out.println("Creating an Amazon DynamoDB table " + tableName + " with a simple primary key: " + key); Region region = Region.US_EAST_1; DynamoDbClient ddb = DynamoDbClient.builder() .region(region) .build(); String result = createTable(ddb, tableName, key); System.out.println("New table is " + result); ddb.close(); } public static String createTable(DynamoDbClient ddb, String tableName, String key) { DynamoDbWaiter dbWaiter = ddb.waiter(); CreateTableRequest request = CreateTableRequest.builder() .attributeDefinitions(AttributeDefinition.builder() .attributeName(key) .attributeType(ScalarAttributeType.S) .build()) .keySchema(KeySchemaElement.builder() .attributeName(key) .keyType(KeyType.HASH) .build()) .billingMode(BillingMode.PAY_PER_REQUEST) // DynamoDB automatically scales based on traffic. .tableName(tableName) .build(); String newTable; try { CreateTableResponse response = ddb.createTable(request); DescribeTableRequest tableRequest = DescribeTableRequest.builder() .tableName(tableName) .build(); // Wait until the Amazon DynamoDB table is created. WaiterResponse<DescribeTableResponse> waiterResponse = dbWaiter.waitUntilTableExists(tableRequest); waiterResponse.matched().response().ifPresent(System.out::println); newTable = response.tableDescription().tableName(); return newTable; } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } return ""; } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조CreateTable을 참조하세요.

다음 코드 예시는 DeleteItem의 사용 방법을 보여 줍니다.

SDK for Java 2.x
참고

GitHub에 더 많은 내용이 있습니다. AWS 코드 예제 리포지토리에서 전체 예제를 찾고 설정 및 실행하는 방법을 배워보세요.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DeleteItemRequest; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import java.util.HashMap; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class DeleteItem { public static void main(String[] args) { final String usage = """ Usage: <tableName> <key> <keyval> Where: tableName - The Amazon DynamoDB table to delete the item from (for example, Music3). key - The key used in the Amazon DynamoDB table (for example, Artist).\s keyval - The key value that represents the item to delete (for example, Famous Band). """; if (args.length != 3) { System.out.println(usage); System.exit(1); } String tableName = args[0]; String key = args[1]; String keyVal = args[2]; System.out.format("Deleting item \"%s\" from %s\n", keyVal, tableName); Region region = Region.US_EAST_1; DynamoDbClient ddb = DynamoDbClient.builder() .region(region) .build(); deleteDynamoDBItem(ddb, tableName, key, keyVal); ddb.close(); } public static void deleteDynamoDBItem(DynamoDbClient ddb, String tableName, String key, String keyVal) { HashMap<String, AttributeValue> keyToGet = new HashMap<>(); keyToGet.put(key, AttributeValue.builder() .s(keyVal) .build()); DeleteItemRequest deleteReq = DeleteItemRequest.builder() .tableName(tableName) .key(keyToGet) .build(); try { ddb.deleteItem(deleteReq); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조DeleteItem을 참조하세요.

다음 코드 예시는 DeleteTable의 사용 방법을 보여 줍니다.

SDK for Java 2.x
참고

GitHub에 더 많은 내용이 있습니다. AWS 코드 예제 리포지토리에서 전체 예제를 찾고 설정 및 실행하는 방법을 배워보세요.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.DeleteTableRequest; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class DeleteTable { public static void main(String[] args) { final String usage = """ Usage: <tableName> Where: tableName - The Amazon DynamoDB table to delete (for example, Music3). **Warning** This program will delete the table that you specify! """; if (args.length != 1) { System.out.println(usage); System.exit(1); } String tableName = args[0]; System.out.format("Deleting the Amazon DynamoDB table %s...\n", tableName); Region region = Region.US_EAST_1; DynamoDbClient ddb = DynamoDbClient.builder() .region(region) .build(); deleteDynamoDBTable(ddb, tableName); ddb.close(); } public static void deleteDynamoDBTable(DynamoDbClient ddb, String tableName) { DeleteTableRequest request = DeleteTableRequest.builder() .tableName(tableName) .build(); try { ddb.deleteTable(request); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } System.out.println(tableName + " was successfully deleted!"); } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조DeleteTable을 참조하세요.

다음 코드 예시는 DescribeTable의 사용 방법을 보여 줍니다.

SDK for Java 2.x
참고

GitHub에 더 많은 내용이 있습니다. AWS 코드 예제 리포지토리에서 전체 예제를 찾고 설정 및 실행하는 방법을 배워보세요.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeDefinition; import software.amazon.awssdk.services.dynamodb.model.DescribeTableRequest; import software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughputDescription; import software.amazon.awssdk.services.dynamodb.model.TableDescription; import java.util.List; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class DescribeTable { public static void main(String[] args) { final String usage = """ Usage: <tableName> Where: tableName - The Amazon DynamoDB table to get information about (for example, Music3). """; if (args.length != 1) { System.out.println(usage); System.exit(1); } String tableName = args[0]; System.out.format("Getting description for %s\n\n", tableName); Region region = Region.US_EAST_1; DynamoDbClient ddb = DynamoDbClient.builder() .region(region) .build(); describeDymamoDBTable(ddb, tableName); ddb.close(); } public static void describeDymamoDBTable(DynamoDbClient ddb, String tableName) { DescribeTableRequest request = DescribeTableRequest.builder() .tableName(tableName) .build(); try { TableDescription tableInfo = ddb.describeTable(request).table(); if (tableInfo != null) { System.out.format("Table name : %s\n", tableInfo.tableName()); System.out.format("Table ARN : %s\n", tableInfo.tableArn()); System.out.format("Status : %s\n", tableInfo.tableStatus()); System.out.format("Item count : %d\n", tableInfo.itemCount()); System.out.format("Size (bytes): %d\n", tableInfo.tableSizeBytes()); ProvisionedThroughputDescription throughputInfo = tableInfo.provisionedThroughput(); System.out.println("Throughput"); System.out.format(" Read Capacity : %d\n", throughputInfo.readCapacityUnits()); System.out.format(" Write Capacity: %d\n", throughputInfo.writeCapacityUnits()); List<AttributeDefinition> attributes = tableInfo.attributeDefinitions(); System.out.println("Attributes"); for (AttributeDefinition a : attributes) { System.out.format(" %s (%s)\n", a.attributeName(), a.attributeType()); } } } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } System.out.println("\nDone!"); } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조DescribeTable을 참조하세요.

다음 코드 예시는 DescribeTimeToLive의 사용 방법을 보여 줍니다.

SDK for Java 2.x

AWS SDK for Java 2.x를 사용하여 기존 DynamoDB 테이블의 TTL 구성을 설명합니다.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.DescribeTimeToLiveRequest; import software.amazon.awssdk.services.dynamodb.model.DescribeTimeToLiveResponse; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.util.logging.Level; import java.util.logging.Logger; public DescribeTimeToLiveResponse describeTTL(final String tableName, final Region region) { final DescribeTimeToLiveRequest request = DescribeTimeToLiveRequest.builder().tableName(tableName).build(); try (DynamoDbClient ddb = dynamoDbClient != null ? dynamoDbClient : DynamoDbClient.builder().region(region).build()) { return ddb.describeTimeToLive(request); } catch (ResourceNotFoundException e) { System.err.format(TABLE_NOT_FOUND_ERROR, tableName); throw e; } catch (DynamoDbException e) { System.err.println(e.getMessage()); throw e; } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조의 DescribeTimeToLive를 참조하세요.

다음 코드 예시는 GetItem의 사용 방법을 보여 줍니다.

SDK for Java 2.x
참고

GitHub에 더 많은 내용이 있습니다. AWS 코드 예 리포지토리에서 전체 예를 찾고 설정 및 실행하는 방법을 배워보세요.

DynamoDbClient를 사용하여 테이블에서 항목을 가져옵니다.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.GetItemRequest; import java.util.HashMap; import java.util.Map; import java.util.Set; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html * * To get an item from an Amazon DynamoDB table using the AWS SDK for Java V2, * its better practice to use the * Enhanced Client, see the EnhancedGetItem example. */ public class GetItem { public static void main(String[] args) { final String usage = """ Usage: <tableName> <key> <keyVal> Where: tableName - The Amazon DynamoDB table from which an item is retrieved (for example, Music3).\s key - The key used in the Amazon DynamoDB table (for example, Artist).\s keyval - The key value that represents the item to get (for example, Famous Band). """; if (args.length != 3) { System.out.println(usage); System.exit(1); } String tableName = args[0]; String key = args[1]; String keyVal = args[2]; System.out.format("Retrieving item \"%s\" from \"%s\"\n", keyVal, tableName); Region region = Region.US_EAST_1; DynamoDbClient ddb = DynamoDbClient.builder() .region(region) .build(); getDynamoDBItem(ddb, tableName, key, keyVal); ddb.close(); } public static void getDynamoDBItem(DynamoDbClient ddb, String tableName, String key, String keyVal) { HashMap<String, AttributeValue> keyToGet = new HashMap<>(); keyToGet.put(key, AttributeValue.builder() .s(keyVal) .build()); GetItemRequest request = GetItemRequest.builder() .key(keyToGet) .tableName(tableName) .build(); try { // If there is no matching item, GetItem does not return any data. Map<String, AttributeValue> returnedItem = ddb.getItem(request).item(); if (returnedItem.isEmpty()) System.out.format("No item found with the key %s!\n", key); else { Set<String> keys = returnedItem.keySet(); System.out.println("Amazon DynamoDB table attributes: \n"); for (String key1 : keys) { System.out.format("%s: %s\n", key1, returnedItem.get(key1).toString()); } } } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조GetItem을 참조하세요.

다음 코드 예시는 ListTables의 사용 방법을 보여 줍니다.

SDK for Java 2.x
참고

GitHub에 더 많은 내용이 있습니다. AWS 코드 예 리포지토리에서 전체 예를 찾고 설정 및 실행하는 방법을 배워보세요.

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.services.dynamodb.model.ListTablesRequest; import software.amazon.awssdk.services.dynamodb.model.ListTablesResponse; import java.util.List; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class ListTables { public static void main(String[] args) { System.out.println("Listing your Amazon DynamoDB tables:\n"); Region region = Region.US_EAST_1; DynamoDbClient ddb = DynamoDbClient.builder() .region(region) .build(); listAllTables(ddb); ddb.close(); } public static void listAllTables(DynamoDbClient ddb) { boolean moreTables = true; String lastName = null; while (moreTables) { try { ListTablesResponse response = null; if (lastName == null) { ListTablesRequest request = ListTablesRequest.builder().build(); response = ddb.listTables(request); } else { ListTablesRequest request = ListTablesRequest.builder() .exclusiveStartTableName(lastName).build(); response = ddb.listTables(request); } List<String> tableNames = response.tableNames(); if (tableNames.size() > 0) { for (String curName : tableNames) { System.out.format("* %s\n", curName); } } else { System.out.println("No tables found!"); System.exit(0); } lastName = response.lastEvaluatedTableName(); if (lastName == null) { moreTables = false; } } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } } System.out.println("\nDone!"); } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조ListTables를 참조하세요.

다음 코드 예시는 PutItem의 사용 방법을 보여 줍니다.

SDK for Java 2.x
참고

GitHub에 더 많은 내용이 있습니다. AWS 코드 예 리포지토리에서 전체 예를 찾고 설정 및 실행하는 방법을 배워보세요.

DynamoDbClient를 사용하여 테이블에 항목 추가

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.PutItemRequest; import software.amazon.awssdk.services.dynamodb.model.PutItemResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.util.HashMap; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html * * To place items into an Amazon DynamoDB table using the AWS SDK for Java V2, * its better practice to use the * Enhanced Client. See the EnhancedPutItem example. */ public class PutItem { public static void main(String[] args) { final String usage = """ Usage: <tableName> <key> <keyVal> <albumtitle> <albumtitleval> <awards> <awardsval> <Songtitle> <songtitleval> Where: tableName - The Amazon DynamoDB table in which an item is placed (for example, Music3). key - The key used in the Amazon DynamoDB table (for example, Artist). keyval - The key value that represents the item to get (for example, Famous Band). albumTitle - The Album title (for example, AlbumTitle). AlbumTitleValue - The name of the album (for example, Songs About Life ). Awards - The awards column (for example, Awards). AwardVal - The value of the awards (for example, 10). SongTitle - The song title (for example, SongTitle). SongTitleVal - The value of the song title (for example, Happy Day). **Warning** This program will place an item that you specify into a table! """; if (args.length != 9) { System.out.println(usage); System.exit(1); } String tableName = args[0]; String key = args[1]; String keyVal = args[2]; String albumTitle = args[3]; String albumTitleValue = args[4]; String awards = args[5]; String awardVal = args[6]; String songTitle = args[7]; String songTitleVal = args[8]; Region region = Region.US_EAST_1; DynamoDbClient ddb = DynamoDbClient.builder() .region(region) .build(); putItemInTable(ddb, tableName, key, keyVal, albumTitle, albumTitleValue, awards, awardVal, songTitle, songTitleVal); System.out.println("Done!"); ddb.close(); } public static void putItemInTable(DynamoDbClient ddb, String tableName, String key, String keyVal, String albumTitle, String albumTitleValue, String awards, String awardVal, String songTitle, String songTitleVal) { HashMap<String, AttributeValue> itemValues = new HashMap<>(); itemValues.put(key, AttributeValue.builder().s(keyVal).build()); itemValues.put(songTitle, AttributeValue.builder().s(songTitleVal).build()); itemValues.put(albumTitle, AttributeValue.builder().s(albumTitleValue).build()); itemValues.put(awards, AttributeValue.builder().s(awardVal).build()); PutItemRequest request = PutItemRequest.builder() .tableName(tableName) .item(itemValues) .build(); try { PutItemResponse response = ddb.putItem(request); System.out.println(tableName + " was successfully updated. The request id is " + response.responseMetadata().requestId()); } catch (ResourceNotFoundException e) { System.err.format("Error: The Amazon DynamoDB table \"%s\" can't be found.\n", tableName); System.err.println("Be sure that it exists and that you've typed its name correctly!"); System.exit(1); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조PutItem을 참조하세요.

다음 코드 예시는 Query의 사용 방법을 보여 줍니다.

SDK for Java 2.x
참고

GitHub에 더 많은 내용이 있습니다. AWS 코드 예 리포지토리에서 전체 예를 찾고 설정 및 실행하는 방법을 배워보세요.

DynamoDbClient를 사용하여 테이블을 쿼리합니다.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import java.util.HashMap; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html * * To query items from an Amazon DynamoDB table using the AWS SDK for Java V2, * its better practice to use the * Enhanced Client. See the EnhancedQueryRecords example. */ public class Query { public static void main(String[] args) { final String usage = """ Usage: <tableName> <partitionKeyName> <partitionKeyVal> Where: tableName - The Amazon DynamoDB table to put the item in (for example, Music3). partitionKeyName - The partition key name of the Amazon DynamoDB table (for example, Artist). partitionKeyVal - The value of the partition key that should match (for example, Famous Band). """; if (args.length != 3) { System.out.println(usage); System.exit(1); } String tableName = args[0]; String partitionKeyName = args[1]; String partitionKeyVal = args[2]; // For more information about an alias, see: // https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ExpressionAttributeNames.html String partitionAlias = "#a"; System.out.format("Querying %s", tableName); System.out.println(""); Region region = Region.US_EAST_1; DynamoDbClient ddb = DynamoDbClient.builder() .region(region) .build(); int count = queryTable(ddb, tableName, partitionKeyName, partitionKeyVal, partitionAlias); System.out.println("There were " + count + " record(s) returned"); ddb.close(); } public static int queryTable(DynamoDbClient ddb, String tableName, String partitionKeyName, String partitionKeyVal, String partitionAlias) { // Set up an alias for the partition key name in case it's a reserved word. HashMap<String, String> attrNameAlias = new HashMap<String, String>(); attrNameAlias.put(partitionAlias, partitionKeyName); // Set up mapping of the partition name with the value. HashMap<String, AttributeValue> attrValues = new HashMap<>(); attrValues.put(":" + partitionKeyName, AttributeValue.builder() .s(partitionKeyVal) .build()); QueryRequest queryReq = QueryRequest.builder() .tableName(tableName) .keyConditionExpression(partitionAlias + " = :" + partitionKeyName) .expressionAttributeNames(attrNameAlias) .expressionAttributeValues(attrValues) .build(); try { QueryResponse response = ddb.query(queryReq); return response.count(); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } return -1; } }

DynamoDbClient 및 보조 인덱스를 사용하여 테이블을 쿼리합니다.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import java.util.HashMap; import java.util.Map; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html * * Create the Movies table by running the Scenario example and loading the Movie * data from the JSON file. Next create a secondary * index for the Movies table that uses only the year column. Name the index * **year-index**. For more information, see: * * https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html */ public class QueryItemsUsingIndex { public static void main(String[] args) { String tableName = "Movies"; Region region = Region.US_EAST_1; DynamoDbClient ddb = DynamoDbClient.builder() .region(region) .build(); queryIndex(ddb, tableName); ddb.close(); } public static void queryIndex(DynamoDbClient ddb, String tableName) { try { Map<String, String> expressionAttributesNames = new HashMap<>(); expressionAttributesNames.put("#year", "year"); Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put(":yearValue", AttributeValue.builder().n("2013").build()); QueryRequest request = QueryRequest.builder() .tableName(tableName) .indexName("year-index") .keyConditionExpression("#year = :yearValue") .expressionAttributeNames(expressionAttributesNames) .expressionAttributeValues(expressionAttributeValues) .build(); System.out.println("=== Movie Titles ==="); QueryResponse response = ddb.query(request); response.items() .forEach(movie -> System.out.println(movie.get("title").s())); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조Query를 참조하세요.

다음 코드 예시는 Scan의 사용 방법을 보여 줍니다.

SDK for Java 2.x
참고

GitHub에 더 많은 내용이 있습니다. AWS 코드 예 리포지토리에서 전체 예를 찾고 설정 및 실행하는 방법을 배워보세요.

DynamoDbClient를 사용하여 Amazon DynamoDB 테이블을 스캔합니다.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.ScanRequest; import software.amazon.awssdk.services.dynamodb.model.ScanResponse; import java.util.Map; import java.util.Set; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html * * To scan items from an Amazon DynamoDB table using the AWS SDK for Java V2, * its better practice to use the * Enhanced Client, See the EnhancedScanRecords example. */ public class DynamoDBScanItems { public static void main(String[] args) { final String usage = """ Usage: <tableName> Where: tableName - The Amazon DynamoDB table to get information from (for example, Music3). """; if (args.length != 1) { System.out.println(usage); System.exit(1); } String tableName = args[0]; Region region = Region.US_EAST_1; DynamoDbClient ddb = DynamoDbClient.builder() .region(region) .build(); scanItems(ddb, tableName); ddb.close(); } public static void scanItems(DynamoDbClient ddb, String tableName) { try { ScanRequest scanRequest = ScanRequest.builder() .tableName(tableName) .build(); ScanResponse response = ddb.scan(scanRequest); for (Map<String, AttributeValue> item : response.items()) { Set<String> keys = item.keySet(); for (String key : keys) { System.out.println("The key name is " + key + "\n"); System.out.println("The value is " + item.get(key).s()); } } } catch (DynamoDbException e) { e.printStackTrace(); System.exit(1); } } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조Scan을 참조하세요.

다음 코드 예시는 UpdateItem의 사용 방법을 보여 줍니다.

SDK for Java 2.x
참고

GitHub에 더 많은 내용이 있습니다. AWS 코드 예 리포지토리에서 전체 예를 찾고 설정 및 실행하는 방법을 배워보세요.

DynamoDbClient를 사용하여 테이블의 항목 업데이트

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.AttributeAction; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.AttributeValueUpdate; import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import java.util.HashMap; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html * * To update an Amazon DynamoDB table using the AWS SDK for Java V2, its better * practice to use the * Enhanced Client, See the EnhancedModifyItem example. */ public class UpdateItem { public static void main(String[] args) { final String usage = """ Usage: <tableName> <key> <keyVal> <name> <updateVal> Where: tableName - The Amazon DynamoDB table (for example, Music3). key - The name of the key in the table (for example, Artist). keyVal - The value of the key (for example, Famous Band). name - The name of the column where the value is updated (for example, Awards). updateVal - The value used to update an item (for example, 14). Example: UpdateItem Music3 Artist Famous Band Awards 14 """; if (args.length != 5) { System.out.println(usage); System.exit(1); } String tableName = args[0]; String key = args[1]; String keyVal = args[2]; String name = args[3]; String updateVal = args[4]; Region region = Region.US_EAST_1; DynamoDbClient ddb = DynamoDbClient.builder() .region(region) .build(); updateTableItem(ddb, tableName, key, keyVal, name, updateVal); ddb.close(); } public static void updateTableItem(DynamoDbClient ddb, String tableName, String key, String keyVal, String name, String updateVal) { HashMap<String, AttributeValue> itemKey = new HashMap<>(); itemKey.put(key, AttributeValue.builder() .s(keyVal) .build()); HashMap<String, AttributeValueUpdate> updatedValues = new HashMap<>(); updatedValues.put(name, AttributeValueUpdate.builder() .value(AttributeValue.builder().s(updateVal).build()) .action(AttributeAction.PUT) .build()); UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(itemKey) .attributeUpdates(updatedValues) .build(); try { ddb.updateItem(request); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } System.out.println("The Amazon DynamoDB table was updated!"); } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조UpdateItem을 참조하세요.

다음 코드 예시는 UpdateTimeToLive의 사용 방법을 보여 줍니다.

SDK for Java 2.x

AWS SDK for Java 2.x를 사용하여 기존 DynamoDB 테이블에서 TTL을 활성화합니다.

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.services.dynamodb.model.ResourceNotFoundException; import software.amazon.awssdk.services.dynamodb.model.TimeToLiveSpecification; import software.amazon.awssdk.services.dynamodb.model.UpdateTimeToLiveRequest; import software.amazon.awssdk.services.dynamodb.model.UpdateTimeToLiveResponse; import java.util.logging.Level; import java.util.logging.Logger; public UpdateTimeToLiveResponse enableTTL(final String tableName, final String attributeName, final Region region) { final TimeToLiveSpecification ttlSpec = TimeToLiveSpecification.builder() .attributeName(attributeName) .enabled(true) .build(); final UpdateTimeToLiveRequest request = UpdateTimeToLiveRequest.builder() .tableName(tableName) .timeToLiveSpecification(ttlSpec) .build(); try (DynamoDbClient ddb = dynamoDbClient != null ? dynamoDbClient : DynamoDbClient.builder().region(region).build()) { return ddb.updateTimeToLive(request); } catch (ResourceNotFoundException e) { System.err.format(TABLE_NOT_FOUND_ERROR, tableName); throw e; } catch (DynamoDbException e) { System.err.println(e.getMessage()); throw e; } }

AWS SDK for Java 2.x를 사용하여 기존 DynamoDB 테이블에서 TTL을 비활성화합니다.

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.services.dynamodb.model.ResourceNotFoundException; import software.amazon.awssdk.services.dynamodb.model.TimeToLiveSpecification; import software.amazon.awssdk.services.dynamodb.model.UpdateTimeToLiveRequest; import software.amazon.awssdk.services.dynamodb.model.UpdateTimeToLiveResponse; import java.util.logging.Level; import java.util.logging.Logger; public UpdateTimeToLiveResponse disableTTL( final String tableName, final String attributeName, final Region region) { final TimeToLiveSpecification ttlSpec = TimeToLiveSpecification.builder() .attributeName(attributeName) .enabled(false) .build(); final UpdateTimeToLiveRequest request = UpdateTimeToLiveRequest.builder() .tableName(tableName) .timeToLiveSpecification(ttlSpec) .build(); try (DynamoDbClient ddb = dynamoDbClient != null ? dynamoDbClient : DynamoDbClient.builder().region(region).build()) { return ddb.updateTimeToLive(request); } catch (ResourceNotFoundException e) { System.err.format(TABLE_NOT_FOUND_ERROR, tableName); throw e; } catch (DynamoDbException e) { System.err.println(e.getMessage()); throw e; } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조의 UpdateTimeToLive를 참조하세요.

시나리오

다음 코드 예제에서는 Amazon DynamoDB 테이블에 데이터를 제출하고 사용자가 테이블을 업데이트할 때 알리는 애플리케이션을 빌드하는 방법을 보여줍니다.

SDK for Java 2.x

Amazon DynamoDB Java API를 사용하여 데이터를 제출하고 Amazon Simple Notification Service Java API를 사용하여 문자 메시지를 전송하는 동적 웹 애플리케이션을 생성하는 방법을 보여줍니다.

전체 소스 코드와 설정 및 실행 방법에 대한 지침은 GitHub에서 전체 예제를 참조하세요.

이 예제에서 사용되는 서비스
  • DynamoDB

  • Amazon SNS

다음 코드 예제에서는 여러 값을 DynamoDB의 단일 속성과 비교하는 방법을 보여줍니다.

  • IN 연산자를 사용하여 여러 값을 단일 속성과 비교합니다.

  • IN 연산자를 여러 OR 조건과 비교합니다.

  • IN 사용의 성능 및 표현식 복잡성 이점을 이해합니다.

SDK for Java 2.x

를 사용하여 DynamoDB의 단일 속성과 여러 값을 비교합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ScanRequest; import software.amazon.awssdk.services.dynamodb.model.ScanResponse; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; /** * Queries a table using the IN operator to compare multiple values with a single attribute. * * <p>This method demonstrates how to use the IN operator in a filter expression * to match an attribute against multiple values. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param partitionKeyName The name of the partition key attribute * @param partitionKeyValue The value of the partition key to query * @param attributeName The name of the attribute to compare * @param valuesList List of values to compare against * @return The query response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static QueryResponse compareMultipleValues( DynamoDbClient dynamoDbClient, String tableName, String partitionKeyName, AttributeValue partitionKeyValue, String attributeName, List<AttributeValue> valuesList) { // Create expression attribute names Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put("#pkName", partitionKeyName); expressionAttributeNames.put("#attrName", attributeName); // Create expression attribute values Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put(":pkValue", partitionKeyValue); // Add values for IN operator for (int i = 0; i < valuesList.size(); i++) { expressionAttributeValues.put(":val" + i, valuesList.get(i)); } // Build the IN clause StringBuilder inClause = new StringBuilder(); for (int i = 0; i < valuesList.size(); i++) { if (i > 0) { inClause.append(", "); } inClause.append(":val").append(i); } // Define the query parameters QueryRequest request = QueryRequest.builder() .tableName(tableName) .keyConditionExpression("#pkName = :pkValue") .filterExpression("#attrName IN (" + inClause.toString() + ")") .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .build(); // Perform the query operation return dynamoDbClient.query(request); } /** * Queries a table using multiple OR conditions to compare multiple values with a single attribute. * * <p>This method demonstrates the alternative approach to using the IN operator, * by using multiple OR conditions. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param partitionKeyName The name of the partition key attribute * @param partitionKeyValue The value of the partition key to query * @param attributeName The name of the attribute to compare * @param valuesList List of values to compare against * @return The query response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static QueryResponse compareWithOrConditions( DynamoDbClient dynamoDbClient, String tableName, String partitionKeyName, AttributeValue partitionKeyValue, String attributeName, List<AttributeValue> valuesList) { // Create expression attribute names Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put("#pkName", partitionKeyName); expressionAttributeNames.put("#attrName", attributeName); // Create expression attribute values Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put(":pkValue", partitionKeyValue); // Add values for OR conditions for (int i = 0; i < valuesList.size(); i++) { expressionAttributeValues.put(":val" + i, valuesList.get(i)); } // Build the OR conditions StringBuilder orConditions = new StringBuilder(); for (int i = 0; i < valuesList.size(); i++) { if (i > 0) { orConditions.append(" OR "); } orConditions.append("#attrName = :val").append(i); } // Define the query parameters QueryRequest request = QueryRequest.builder() .tableName(tableName) .keyConditionExpression("#pkName = :pkValue") .filterExpression(orConditions.toString()) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .build(); // Perform the query operation return dynamoDbClient.query(request); } /** * Compares the performance of using the IN operator versus multiple OR conditions. * * <p>This method demonstrates the performance difference between using the IN operator * and using multiple OR conditions. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param partitionKeyName The name of the partition key attribute * @param partitionKeyValue The value of the partition key to query * @param attributeName The name of the attribute to compare * @param valuesList List of values to compare against * @return Map containing the performance comparison results */ public static Map<String, Object> comparePerformance( DynamoDbClient dynamoDbClient, String tableName, String partitionKeyName, AttributeValue partitionKeyValue, String attributeName, List<AttributeValue> valuesList) { Map<String, Object> results = new HashMap<>(); try { // Measure performance of IN operator long inStartTime = System.nanoTime(); QueryResponse inResponse = compareMultipleValues( dynamoDbClient, tableName, partitionKeyName, partitionKeyValue, attributeName, valuesList); long inEndTime = System.nanoTime(); long inDuration = inEndTime - inStartTime; // Measure performance of OR conditions long orStartTime = System.nanoTime(); QueryResponse orResponse = compareWithOrConditions( dynamoDbClient, tableName, partitionKeyName, partitionKeyValue, attributeName, valuesList); long orEndTime = System.nanoTime(); long orDuration = orEndTime - orStartTime; // Record results results.put("inOperatorDuration", inDuration); results.put("orConditionsDuration", orDuration); results.put("inOperatorItems", inResponse.count()); results.put("orConditionsItems", orResponse.count()); results.put("inOperatorExpression", "IN operator with " + valuesList.size() + " values"); results.put("orConditionsExpression", valuesList.size() + " OR conditions"); results.put("success", true); } catch (DynamoDbException e) { results.put("success", false); results.put("error", e.getMessage()); } return results; } /** * Scans a table using the IN operator with a large number of values. * * <p>This method demonstrates how to use the IN operator with a large number of values, * which can help stay within the 300 operator limit. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param attributeName The name of the attribute to compare * @param valuesList List of values to compare against * @return The scan response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static ScanResponse scanWithLargeInClause( DynamoDbClient dynamoDbClient, String tableName, String attributeName, List<AttributeValue> valuesList) { // Create expression attribute names Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put("#attrName", attributeName); // Create expression attribute values Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); // Add values for IN operator for (int i = 0; i < valuesList.size(); i++) { expressionAttributeValues.put(":val" + i, valuesList.get(i)); } // Build the IN clause StringBuilder inClause = new StringBuilder(); for (int i = 0; i < valuesList.size(); i++) { if (i > 0) { inClause.append(", "); } inClause.append(":val").append(i); } // Define the scan parameters ScanRequest request = ScanRequest.builder() .tableName(tableName) .filterExpression("#attrName IN (" + inClause.toString() + ")") .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .build(); // Perform the scan operation return dynamoDbClient.scan(request); } /** * Generates a list of sample values for testing. * * <p>Helper method to generate a list of sample values for testing. * * @param valueType The type of values to generate (string, number, or boolean) * @param count The number of values to generate * @return List of generated attribute values */ public static List<AttributeValue> generateSampleValues(String valueType, int count) { List<AttributeValue> values = new ArrayList<>(); for (int i = 0; i < count; i++) { AttributeValue value; switch (valueType.toLowerCase(Locale.ROOT)) { case "string": value = AttributeValue.builder().s("Value" + i).build(); break; case "number": value = AttributeValue.builder().n(String.valueOf(i)).build(); break; case "boolean": value = AttributeValue.builder().bool(i % 2 == 0).build(); break; default: throw new IllegalArgumentException("Unsupported value type: " + valueType); } values.add(value); } return values; }

여러 값을와 비교하는 예제 사용 AWS SDK for Java 2.x.

public static void exampleUsage(DynamoDbClient dynamoDbClient, String tableName) { System.out.println("Demonstrating how to compare multiple values with a single attribute in DynamoDB"); try { // Example 1: Using the IN operator System.out.println("\nExample 1: Using the IN operator"); List<AttributeValue> categories = List.of( AttributeValue.builder().s("Electronics").build(), AttributeValue.builder().s("Computers").build(), AttributeValue.builder().s("Accessories").build()); QueryResponse inResponse = compareMultipleValues( dynamoDbClient, tableName, "Department", AttributeValue.builder().s("Retail").build(), "Category", categories); System.out.println("Found " + inResponse.count() + " items using IN operator"); System.out.println("Items: " + inResponse.items()); // Example 2: Using multiple OR conditions System.out.println("\nExample 2: Using multiple OR conditions"); QueryResponse orResponse = compareWithOrConditions( dynamoDbClient, tableName, "Department", AttributeValue.builder().s("Retail").build(), "Category", categories); System.out.println("Found " + orResponse.count() + " items using OR conditions"); System.out.println("Items: " + orResponse.items()); // Example 3: Performance comparison System.out.println("\nExample 3: Performance comparison"); Map<String, Object> perfComparison = comparePerformance( dynamoDbClient, tableName, "Department", AttributeValue.builder().s("Retail").build(), "Category", categories); if ((boolean) perfComparison.get("success")) { System.out.println("IN operator duration: " + perfComparison.get("inOperatorDuration") + " ns"); System.out.println("OR conditions duration: " + perfComparison.get("orConditionsDuration") + " ns"); System.out.println("IN operator found " + perfComparison.get("inOperatorItems") + " items"); System.out.println("OR conditions found " + perfComparison.get("orConditionsItems") + " items"); System.out.println("Expression complexity comparison:"); System.out.println(" IN operator: " + perfComparison.get("inOperatorExpression")); System.out.println(" OR conditions: " + perfComparison.get("orConditionsExpression")); } else { System.out.println("Performance comparison failed: " + perfComparison.get("error")); } // Example 4: Using IN with a large number of values System.out.println("\nExample 4: Using IN with a large number of values"); List<AttributeValue> productIds = generateSampleValues("string", 20); ScanResponse largeInResponse = scanWithLargeInClause(dynamoDbClient, tableName, "ProductId", productIds); System.out.println( "Found " + largeInResponse.count() + " items using IN with " + productIds.size() + " values"); // Explain the benefits of using IN System.out.println("\nKey points about using the IN operator in DynamoDB:"); System.out.println("1. The IN operator allows comparing a single attribute against multiple values"); System.out.println("2. IN is more concise than using multiple OR conditions"); System.out.println("3. IN counts as only 1 operator regardless of the number of values"); System.out.println("4. Multiple OR conditions count as 1 operator per condition plus 1 per OR"); System.out.println("5. Using IN helps stay within the 300 operator limit for complex expressions"); System.out.println("6. IN can be used in filter expressions and condition expressions"); System.out.println("7. The IN operator supports up to 100 comparison values"); } catch (DynamoDbException e) { System.err.println("Error: " + e.getMessage()); e.printStackTrace(); } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조의 다음 주제를 참조하세요.

다음 코드 예제에서는 항목의 TTL을 조건부로 업데이트하는 방법을 보여줍니다.

SDK for Java 2.x

조건을 사용하여 테이블의 기존 DynamoDB 항목에서 TTL을 업데이트합니다.

package com.amazon.samplelib.ttl; import com.amazon.samplelib.CodeSampleUtils; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.ConditionalCheckFailedException; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest; import software.amazon.awssdk.services.dynamodb.model.UpdateItemResponse; import java.util.Map; import java.util.Optional; /** * Updates an item in a DynamoDB table with TTL attributes using a conditional expression. * This class demonstrates how to conditionally update TTL expiration timestamps. */ public class UpdateTTLConditional { private static final String USAGE = """ Usage: <tableName> <primaryKey> <sortKey> <region> Where: tableName - The Amazon DynamoDB table being queried. primaryKey - The name of the primary key. Also known as the hash or partition key. sortKey - The name of the sort key. Also known as the range attribute. region (optional) - The AWS region that the Amazon DynamoDB table is located in. (Default: us-east-1) """; private static final int DAYS_TO_EXPIRE = 90; private static final int SECONDS_PER_DAY = 24 * 60 * 60; private static final String PRIMARY_KEY_ATTR = "primaryKey"; private static final String SORT_KEY_ATTR = "sortKey"; private static final String UPDATED_AT_ATTR = "updatedAt"; private static final String EXPIRE_AT_ATTR = "expireAt"; private static final String UPDATE_EXPRESSION = "SET " + UPDATED_AT_ATTR + "=:c, " + EXPIRE_AT_ATTR + "=:e"; private static final String CONDITION_EXPRESSION = "attribute_exists(" + PRIMARY_KEY_ATTR + ")"; private static final String SUCCESS_MESSAGE = "%s UpdateItem operation with TTL successful."; private static final String CONDITION_FAILED_MESSAGE = "Condition check failed. Item does not exist."; private static final String TABLE_NOT_FOUND_ERROR = "Error: The Amazon DynamoDB table \"%s\" can't be found."; private final DynamoDbClient dynamoDbClient; /** * Constructs an UpdateTTLConditional with a default DynamoDB client. */ public UpdateTTLConditional() { this.dynamoDbClient = null; } /** * Constructs an UpdateTTLConditional with the specified DynamoDB client. * * @param dynamoDbClient The DynamoDB client to use */ public UpdateTTLConditional(final DynamoDbClient dynamoDbClient) { this.dynamoDbClient = dynamoDbClient; } /** * Main method to demonstrate conditionally updating an item with TTL. * * @param args Command line arguments */ public static void main(final String[] args) { try { int result = new UpdateTTLConditional().processArgs(args); System.exit(result); } catch (Exception e) { System.err.println(e.getMessage()); System.exit(1); } } /** * Process command line arguments and conditionally update an item with TTL. * * @param args Command line arguments * @return 0 if successful, non-zero otherwise * @throws ResourceNotFoundException If the table doesn't exist * @throws DynamoDbException If an error occurs during the operation * @throws IllegalArgumentException If arguments are invalid */ public int processArgs(final String[] args) { // Argument validation (remove or replace this line when reusing this code) CodeSampleUtils.validateArgs(args, new int[] {3, 4}, USAGE); final String tableName = args[0]; final String primaryKey = args[1]; final String sortKey = args[2]; final Region region = Optional.ofNullable(args.length > 3 ? args[3] : null) .map(Region::of) .orElse(Region.US_EAST_1); // Get current time in epoch second format final long currentTime = System.currentTimeMillis() / 1000; // Calculate expiration time 90 days from now in epoch second format final long expireDate = currentTime + (DAYS_TO_EXPIRE * SECONDS_PER_DAY); // Create the key map for the item to update final Map<String, AttributeValue> keyMap = Map.of( PRIMARY_KEY_ATTR, AttributeValue.builder().s(primaryKey).build(), SORT_KEY_ATTR, AttributeValue.builder().s(sortKey).build()); // Create the expression attribute values final Map<String, AttributeValue> expressionAttributeValues = Map.of( ":c", AttributeValue.builder().n(String.valueOf(currentTime)).build(), ":e", AttributeValue.builder().n(String.valueOf(expireDate)).build()); final UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(keyMap) .updateExpression(UPDATE_EXPRESSION) .conditionExpression(CONDITION_EXPRESSION) .expressionAttributeValues(expressionAttributeValues) .build(); try (DynamoDbClient ddb = dynamoDbClient != null ? dynamoDbClient : DynamoDbClient.builder().region(region).build()) { final UpdateItemResponse response = ddb.updateItem(request); System.out.println(String.format(SUCCESS_MESSAGE, tableName)); return 0; } catch (ConditionalCheckFailedException e) { System.err.println(CONDITION_FAILED_MESSAGE); throw e; } catch (ResourceNotFoundException e) { System.err.format(TABLE_NOT_FOUND_ERROR, tableName); throw e; } catch (DynamoDbException e) { System.err.println(e.getMessage()); throw e; } } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조UpdateItem을 참조하세요.

다음 코드 예제에서는 DynamoDB에서 표현식 연산자를 계산하는 방법을 보여줍니다.

  • DynamoDB의 300 연산자 제한을 이해합니다.

  • 복잡한 표현식에서 연산자를 계산합니다.

  • 제한 내에서 유지되도록 표현식을 최적화합니다.

SDK for Java 2.x

를 사용하여 표현식 연산자 계산을 시연합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest; import software.amazon.awssdk.services.dynamodb.model.UpdateItemResponse; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Creates a complex filter expression with a specified number of conditions. * * <p>This method demonstrates how to generate a complex expression with * a specific number of operators to test the 300 operator limit. * * @param conditionsCount Number of conditions to include * @param useAnd Whether to use AND (true) or OR (false) between conditions * @return Map containing the filter expression, attribute values, and operator count */ public static Map<String, Object> createComplexFilterExpression(int conditionsCount, boolean useAnd) { // Initialize the expression parts and attribute values StringBuilder filterExpression = new StringBuilder(); Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); // Generate the specified number of conditions for (int i = 0; i < conditionsCount; i++) { // Add the operator between conditions (except for the first one) if (i > 0) { filterExpression.append(useAnd ? " AND " : " OR "); } // Alternate between different comparison operators for variety String valueKey = ":val" + i; switch (i % 5) { case 0: filterExpression.append("attribute").append(i).append(" = ").append(valueKey); expressionAttributeValues.put( valueKey, AttributeValue.builder().s("value" + i).build()); break; case 1: filterExpression.append("attribute").append(i).append(" > ").append(valueKey); expressionAttributeValues.put( valueKey, AttributeValue.builder().n(String.valueOf(i)).build()); break; case 2: filterExpression.append("attribute").append(i).append(" < ").append(valueKey); expressionAttributeValues.put( valueKey, AttributeValue.builder().n(String.valueOf(i * 10)).build()); break; case 3: filterExpression .append("contains(attribute") .append(i) .append(", ") .append(valueKey) .append(")"); expressionAttributeValues.put( valueKey, AttributeValue.builder().s("substring" + i).build()); break; case 4: filterExpression .append("attribute_exists(attribute") .append(i) .append(")"); break; default: // This case will never be reached, but added to satisfy checkstyle break; } } // Calculate the operator count // Each condition has 1 operator (=, >, <, contains, attribute_exists) // Each AND or OR between conditions is 1 operator int operatorCount = conditionsCount + (conditionsCount > 0 ? conditionsCount - 1 : 0); // Create the result map Map<String, Object> result = new HashMap<>(); result.put("filterExpression", filterExpression.toString()); result.put("expressionAttributeValues", expressionAttributeValues); result.put("operatorCount", operatorCount); return result; } /** * Creates a complex update expression with a specified number of operations. * * <p>This method demonstrates how to generate a complex update expression with * a specific number of operators to test the 300 operator limit. * * @param operationsCount Number of operations to include * @return Map containing the update expression, attribute values, and operator count */ public static Map<String, Object> createComplexUpdateExpression(int operationsCount) { // Initialize the expression parts and attribute values StringBuilder updateExpression = new StringBuilder("SET "); Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); // Generate the specified number of SET operations for (int i = 0; i < operationsCount; i++) { // Add comma between operations (except for the first one) if (i > 0) { updateExpression.append(", "); } // Alternate between different types of SET operations String valueKey = ":val" + i; switch (i % 3) { case 0: // Simple assignment (1 operator: =) updateExpression.append("attribute").append(i).append(" = ").append(valueKey); expressionAttributeValues.put( valueKey, AttributeValue.builder().s("value" + i).build()); break; case 1: // Addition (2 operators: = and +) updateExpression .append("attribute") .append(i) .append(" = attribute") .append(i) .append(" + ") .append(valueKey); expressionAttributeValues.put( valueKey, AttributeValue.builder().n(String.valueOf(i)).build()); break; case 2: // Conditional assignment with if_not_exists (2 operators: = and if_not_exists) updateExpression .append("attribute") .append(i) .append(" = if_not_exists(attribute") .append(i) .append(", ") .append(valueKey) .append(")"); expressionAttributeValues.put( valueKey, AttributeValue.builder().n(String.valueOf(i * 10)).build()); break; default: // This case will never be reached, but added to satisfy checkstyle break; } } // Calculate the operator count // Each operation has 1-2 operators as noted above int operatorCount = 0; for (int i = 0; i < operationsCount; i++) { operatorCount += (i % 3 == 0) ? 1 : 2; } // Create the result map Map<String, Object> result = new HashMap<>(); result.put("updateExpression", updateExpression.toString()); result.put("expressionAttributeValues", expressionAttributeValues); result.put("operatorCount", operatorCount); return result; } /** * Test the operator limit by attempting an operation with a complex expression. * * <p>This method demonstrates what happens when an expression approaches or * exceeds the 300 operator limit. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param operatorCount Target number of operators to include * @return Map containing the result of the operation attempt */ public static Map<String, Object> testOperatorLimit( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, int operatorCount) { // Create a complex update expression with the specified operator count Map<String, Object> expressionData = createComplexUpdateExpression((int) Math.ceil(operatorCount / 1.5)); // Adjust to get close to target count String updateExpression = (String) expressionData.get("updateExpression"); @SuppressWarnings("unchecked") Map<String, AttributeValue> expressionAttributeValues = (Map<String, AttributeValue>) expressionData.get("expressionAttributeValues"); int actualCount = (int) expressionData.get("operatorCount"); System.out.println("Generated update expression with approximately " + actualCount + " operators"); // Define the update parameters UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression(updateExpression) .expressionAttributeValues(expressionAttributeValues) .returnValues("UPDATED_NEW") .build(); try { // Attempt the update operation UpdateItemResponse response = dynamoDbClient.updateItem(request); Map<String, Object> result = new HashMap<>(); result.put("success", true); result.put("message", "Operation succeeded with " + actualCount + " operators"); result.put("data", response); return result; } catch (DynamoDbException e) { // Check if the error is due to exceeding the operator limit if (e.getMessage().contains("too many operators")) { Map<String, Object> result = new HashMap<>(); result.put("success", false); result.put("message", "Operation failed: " + e.getMessage()); result.put("operatorCount", actualCount); return result; } // Return other errors Map<String, Object> result = new HashMap<>(); result.put("success", false); result.put("message", "Operation failed: " + e.getMessage()); result.put("error", e); return result; } } /** * Break down a complex expression into multiple simpler operations. * * <p>This method demonstrates how to handle expressions that would exceed * the 300 operator limit by breaking them into multiple operations. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param totalOperations Total number of operations to perform * @return Map containing the results of the operations */ public static Map<String, Object> breakDownComplexExpression( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, int totalOperations) { // Calculate how many operations we can safely include in each batch // Using 150 as a conservative limit (well below 300) final int operationsPerBatch = 100; final int batchCount = (int) Math.ceil((double) totalOperations / operationsPerBatch); System.out.println("Breaking down " + totalOperations + " operations into " + batchCount + " batches"); Map<String, Object> results = new HashMap<>(); results.put("totalBatches", batchCount); Map<Integer, Map<String, Object>> batchResults = new HashMap<>(); // Process each batch for (int batch = 0; batch < batchCount; batch++) { // Calculate the operations for this batch int batchStart = batch * operationsPerBatch; int batchEnd = Math.min(batchStart + operationsPerBatch, totalOperations); int batchSize = batchEnd - batchStart; System.out.println( "Processing batch " + (batch + 1) + "/" + batchCount + " with " + batchSize + " operations"); // Create an update expression for this batch Map<String, Object> expressionData = createComplexUpdateExpression(batchSize); String updateExpression = (String) expressionData.get("updateExpression"); @SuppressWarnings("unchecked") Map<String, AttributeValue> expressionAttributeValues = (Map<String, AttributeValue>) expressionData.get("expressionAttributeValues"); int operatorCount = (int) expressionData.get("operatorCount"); // Define the update parameters UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression(updateExpression) .expressionAttributeValues(expressionAttributeValues) .returnValues("UPDATED_NEW") .build(); try { // Perform the update operation for this batch UpdateItemResponse response = dynamoDbClient.updateItem(request); Map<String, Object> batchResult = new HashMap<>(); batchResult.put("batch", batch + 1); batchResult.put("success", true); batchResult.put("operatorCount", operatorCount); batchResult.put("attributes", response.attributes()); batchResults.put(batch, batchResult); } catch (DynamoDbException e) { Map<String, Object> batchResult = new HashMap<>(); batchResult.put("batch", batch + 1); batchResult.put("success", false); batchResult.put("operatorCount", operatorCount); batchResult.put("error", e.getMessage()); batchResults.put(batch, batchResult); // Continue with next batch instead of breaking continue; } } results.put("results", batchResults); return results; } /** * Count operators in a DynamoDB expression based on the rules in the documentation. * * <p>This method demonstrates how operators are counted according to the * DynamoDB documentation. * * @param expression The DynamoDB expression to analyze * @return Map containing the breakdown of operator counts */ public static Map<String, Integer> countOperatorsInExpression(String expression) { // Initialize counters for different operator types Map<String, Integer> counts = new HashMap<>(); counts.put("comparisonOperators", 0); counts.put("logicalOperators", 0); counts.put("functions", 0); counts.put("arithmeticOperators", 0); counts.put("specialOperators", 0); counts.put("total", 0); // Count comparison operators (=, <>, <, <=, >, >=) // This is a simplified approach and may not catch all cases int comparisonCount = 0; Pattern comparisonPattern = Pattern.compile("(=|<>|<=|>=|<|>)"); Matcher comparisonMatcher = comparisonPattern.matcher(expression); while (comparisonMatcher.find()) { comparisonCount++; } counts.put("comparisonOperators", comparisonCount); // Count logical operators (AND, OR, NOT) int andCount = countOccurrences(expression, "\\bAND\\b"); int orCount = countOccurrences(expression, "\\bOR\\b"); int notCount = countOccurrences(expression, "\\bNOT\\b"); counts.put("logicalOperators", andCount + orCount + notCount); // Count functions (attribute_exists, attribute_not_exists, attribute_type, begins_with, contains, size) int functionCount = countOccurrences( expression, "\\b(attribute_exists|attribute_not_exists|attribute_type|begins_with|contains|size|if_not_exists)\\("); counts.put("functions", functionCount); // Count arithmetic operators (+ and -) // This is a simplified approach and may not catch all cases int arithmeticCount = 0; Pattern arithmeticPattern = Pattern.compile("[a-zA-Z0-9_)\\]]\\s*[\\+\\-]\\s*[a-zA-Z0-9_:(]"); Matcher arithmeticMatcher = arithmeticPattern.matcher(expression); while (arithmeticMatcher.find()) { arithmeticCount++; } counts.put("arithmeticOperators", arithmeticCount); // Count special operators (BETWEEN, IN) int betweenCount = countOccurrences(expression, "\\bBETWEEN\\b"); int inCount = countOccurrences(expression, "\\bIN\\b"); counts.put("specialOperators", betweenCount + inCount); // Add extra operators for BETWEEN (each BETWEEN includes an AND) int currentLogicalOps = counts.getOrDefault("logicalOperators", 0); counts.put("logicalOperators", currentLogicalOps + betweenCount); // Calculate total int total = counts.getOrDefault("comparisonOperators", 0) + counts.getOrDefault("logicalOperators", 0) + counts.getOrDefault("functions", 0) + counts.getOrDefault("arithmeticOperators", 0) + counts.getOrDefault("specialOperators", 0); counts.put("total", total); return counts; } /** * Helper method to count occurrences of a pattern in a string. * * @param text The text to search in * @param regex The regular expression pattern to search for * @return The number of occurrences */ private static int countOccurrences(String text, String regex) { final Pattern pattern = Pattern.compile(regex); final Matcher matcher = pattern.matcher(text); int count = 0; while (matcher.find()) { count++; } return count; }

에서 계산하는 표현식 연산자의 사용 예입니다 AWS SDK for Java 2.x.

public static void exampleUsage(DynamoDbClient dynamoDbClient, String tableName) { // Example key Map<String, AttributeValue> key = new HashMap<>(); key.put("ProductId", AttributeValue.builder().s("P12345").build()); System.out.println("Demonstrating DynamoDB expression operator counting and the 300 operator limit"); try { // Example 1: Analyze a simple expression System.out.println("\nExample 1: Analyzing a simple expression"); String simpleExpression = "Price = :price AND Rating > :rating AND Category IN (:cat1, :cat2, :cat3)"; Map<String, Integer> simpleCount = countOperatorsInExpression(simpleExpression); System.out.println("Expression: " + simpleExpression); System.out.println("Operator count breakdown:"); System.out.println("- Comparison operators: " + simpleCount.get("comparisonOperators")); System.out.println("- Logical operators: " + simpleCount.get("logicalOperators")); System.out.println("- Functions: " + simpleCount.get("functions")); System.out.println("- Arithmetic operators: " + simpleCount.get("arithmeticOperators")); System.out.println("- Special operators: " + simpleCount.get("specialOperators")); System.out.println("- Total operators: " + simpleCount.get("total")); // Example 2: Analyze a complex expression System.out.println("\nExample 2: Analyzing a complex expression"); String complexExpression = "(attribute_exists(Category) AND Size BETWEEN :min AND :max) OR " + "(Price > :price AND contains(Description, :keyword) AND " + "(Rating >= :minRating OR Reviews > :minReviews))"; Map<String, Integer> complexCount = countOperatorsInExpression(complexExpression); System.out.println("Expression: " + complexExpression); System.out.println("Operator count breakdown:"); System.out.println("- Comparison operators: " + complexCount.get("comparisonOperators")); System.out.println("- Logical operators: " + complexCount.get("logicalOperators")); System.out.println("- Functions: " + complexCount.get("functions")); System.out.println("- Arithmetic operators: " + complexCount.get("arithmeticOperators")); System.out.println("- Special operators: " + complexCount.get("specialOperators")); System.out.println("- Total operators: " + complexCount.get("total")); // Example 3: Test approaching the operator limit System.out.println("\nExample 3: Testing an expression approaching the operator limit"); Map<String, Object> approachingLimit = testOperatorLimit(dynamoDbClient, tableName, key, 290); System.out.println(approachingLimit.get("message")); // Example 4: Test exceeding the operator limit System.out.println("\nExample 4: Testing an expression exceeding the operator limit"); Map<String, Object> exceedingLimit = testOperatorLimit(dynamoDbClient, tableName, key, 310); System.out.println(exceedingLimit.get("message")); // Example 5: Breaking down a complex expression System.out.println("\nExample 5: Breaking down a complex expression into multiple operations"); Map<String, Object> breakdownResult = breakDownComplexExpression(dynamoDbClient, tableName, key, 500); @SuppressWarnings("unchecked") Map<Integer, Map<String, Object>> results = (Map<Integer, Map<String, Object>>) breakdownResult.get("results"); System.out.println( "Processed " + results.size() + " of " + breakdownResult.get("totalBatches") + " batches"); // Explain the operator counting rules System.out.println("\nKey points about DynamoDB expression operator counting:"); System.out.println("1. The maximum number of operators in any expression is 300"); System.out.println("2. Each comparison operator (=, <>, <, <=, >, >=) counts as 1 operator"); System.out.println("3. Each logical operator (AND, OR, NOT) counts as 1 operator"); System.out.println("4. Each function call (attribute_exists, contains, etc.) counts as 1 operator"); System.out.println("5. Each arithmetic operator (+ or -) counts as 1 operator"); System.out.println("6. BETWEEN counts as 2 operators (BETWEEN itself and the AND within it)"); System.out.println("7. IN counts as 1 operator regardless of the number of values"); System.out.println("8. Parentheses for grouping and attribute paths don't count as operators"); System.out.println("9. When you exceed the limit, the error always reports '301 operators'"); System.out.println("10. For complex operations, break them into multiple smaller operations"); } catch (Exception e) { System.err.println("Error: " + e.getMessage()); e.printStackTrace(); } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조UpdateItem을 참조하세요.

다음 코드 예시에서는 사용자가 레이블을 사용하여 사진을 관리할 수 있는 서버리스 애플리케이션을 생성하는 방법을 보여줍니다.

SDK for Java 2.x

Amazon Rekognition을 사용하여 이미지에서 레이블을 감지하고 나중에 검색할 수 있도록 저장하는 사진 자산 관리 애플리케이션을 개발하는 방법을 보여줍니다.

전체 소스 코드와 설정 및 실행 방법에 대한 지침은 GitHub에서 전체 예제를 참조하세요.

이 예제의 출처에 대한 자세한 내용은 AWS  커뮤니티의 게시물을 참조하세요.

이 예시에서 사용되는 서비스
  • API Gateway

  • DynamoDB

  • Lambda

  • Amazon Rekognition

  • Amazon S3

  • Amazon SNS

다음 코드 예제는 글로벌 보조 인덱스로 테이블을 만드는 방법을 보여줍니다.

SDK for Java 2.x

를 사용하여 글로벌 보조 인덱스가 있는 DynamoDB 테이블을 생성합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider; import software.amazon.awssdk.core.waiters.WaiterResponse; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeDefinition; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.CreateTableRequest; import software.amazon.awssdk.services.dynamodb.model.DeleteTableRequest; import software.amazon.awssdk.services.dynamodb.model.DescribeTableRequest; import software.amazon.awssdk.services.dynamodb.model.DescribeTableResponse; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.GlobalSecondaryIndex; import software.amazon.awssdk.services.dynamodb.model.KeySchemaElement; import software.amazon.awssdk.services.dynamodb.model.KeyType; import software.amazon.awssdk.services.dynamodb.model.Projection; import software.amazon.awssdk.services.dynamodb.model.ProjectionType; import software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughput; import software.amazon.awssdk.services.dynamodb.model.PutItemRequest; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType; import software.amazon.awssdk.services.dynamodb.waiters.DynamoDbWaiter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public void createTable() { try { // Attribute definitions final List<AttributeDefinition> attributeDefinitions = new ArrayList<>(); attributeDefinitions.add(AttributeDefinition.builder() .attributeName(ISSUE_ID_ATTR) .attributeType(ScalarAttributeType.S) .build()); attributeDefinitions.add(AttributeDefinition.builder() .attributeName(TITLE_ATTR) .attributeType(ScalarAttributeType.S) .build()); attributeDefinitions.add(AttributeDefinition.builder() .attributeName(CREATE_DATE_ATTR) .attributeType(ScalarAttributeType.S) .build()); attributeDefinitions.add(AttributeDefinition.builder() .attributeName(DUE_DATE_ATTR) .attributeType(ScalarAttributeType.S) .build()); // Key schema for table final List<KeySchemaElement> tableKeySchema = new ArrayList<>(); tableKeySchema.add(KeySchemaElement.builder() .attributeName(ISSUE_ID_ATTR) .keyType(KeyType.HASH) .build()); // Partition key tableKeySchema.add(KeySchemaElement.builder() .attributeName(TITLE_ATTR) .keyType(KeyType.RANGE) .build()); // Sort key // Initial provisioned throughput settings for the indexes final ProvisionedThroughput ptIndex = ProvisionedThroughput.builder() .readCapacityUnits(1L) .writeCapacityUnits(1L) .build(); // CreateDateIndex final List<KeySchemaElement> createDateKeySchema = new ArrayList<>(); createDateKeySchema.add(KeySchemaElement.builder() .attributeName(CREATE_DATE_ATTR) .keyType(KeyType.HASH) .build()); createDateKeySchema.add(KeySchemaElement.builder() .attributeName(ISSUE_ID_ATTR) .keyType(KeyType.RANGE) .build()); final Projection createDateProjection = Projection.builder() .projectionType(ProjectionType.INCLUDE) .nonKeyAttributes(DESCRIPTION_ATTR, STATUS_ATTR) .build(); final GlobalSecondaryIndex createDateIndex = GlobalSecondaryIndex.builder() .indexName(CREATE_DATE_INDEX) .keySchema(createDateKeySchema) .projection(createDateProjection) .provisionedThroughput(ptIndex) .build(); // TitleIndex final List<KeySchemaElement> titleKeySchema = new ArrayList<>(); titleKeySchema.add(KeySchemaElement.builder() .attributeName(TITLE_ATTR) .keyType(KeyType.HASH) .build()); titleKeySchema.add(KeySchemaElement.builder() .attributeName(ISSUE_ID_ATTR) .keyType(KeyType.RANGE) .build()); final Projection titleProjection = Projection.builder().projectionType(ProjectionType.KEYS_ONLY).build(); final GlobalSecondaryIndex titleIndex = GlobalSecondaryIndex.builder() .indexName(TITLE_INDEX) .keySchema(titleKeySchema) .projection(titleProjection) .provisionedThroughput(ptIndex) .build(); // DueDateIndex final List<KeySchemaElement> dueDateKeySchema = new ArrayList<>(); dueDateKeySchema.add(KeySchemaElement.builder() .attributeName(DUE_DATE_ATTR) .keyType(KeyType.HASH) .build()); final Projection dueDateProjection = Projection.builder().projectionType(ProjectionType.ALL).build(); final GlobalSecondaryIndex dueDateIndex = GlobalSecondaryIndex.builder() .indexName(DUE_DATE_INDEX) .keySchema(dueDateKeySchema) .projection(dueDateProjection) .provisionedThroughput(ptIndex) .build(); final CreateTableRequest createTableRequest = CreateTableRequest.builder() .tableName(TABLE_NAME) .keySchema(tableKeySchema) .attributeDefinitions(attributeDefinitions) .globalSecondaryIndexes(createDateIndex, titleIndex, dueDateIndex) .provisionedThroughput(ProvisionedThroughput.builder() .readCapacityUnits(1L) .writeCapacityUnits(1L) .build()) .build(); System.out.println("Creating table " + TABLE_NAME + "..."); dynamoDbClient.createTable(createTableRequest); // Wait for table to become active System.out.println("Waiting for " + TABLE_NAME + " to become ACTIVE..."); final DynamoDbWaiter waiter = dynamoDbClient.waiter(); final DescribeTableRequest describeTableRequest = DescribeTableRequest.builder().tableName(TABLE_NAME).build(); final WaiterResponse<DescribeTableResponse> waiterResponse = waiter.waitUntilTableExists(describeTableRequest); waiterResponse.matched().response().ifPresent(response -> System.out.println("Table is now ready for use")); } catch (DynamoDbException e) { System.err.println("Error creating table: " + e.getMessage()); e.printStackTrace(); } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조CreateTable을 참조하세요.

다음 코드 예제에서는 웜 처리량이 활성화된 테이블을 생성하는 방법을 보여줍니다.

SDK for Java 2.x

AWS SDK for Java 2.x를 사용하여 웜 처리량 설정이 있는 DynamoDB 테이블을 만듭니다.

import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeDefinition; import software.amazon.awssdk.services.dynamodb.model.CreateTableRequest; import software.amazon.awssdk.services.dynamodb.model.CreateTableResponse; import software.amazon.awssdk.services.dynamodb.model.GlobalSecondaryIndex; import software.amazon.awssdk.services.dynamodb.model.KeySchemaElement; import software.amazon.awssdk.services.dynamodb.model.KeyType; import software.amazon.awssdk.services.dynamodb.model.Projection; import software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughput; import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType; import software.amazon.awssdk.services.dynamodb.model.WarmThroughput; public static WarmThroughput buildWarmThroughput(final Long readUnitsPerSecond, final Long writeUnitsPerSecond) { return WarmThroughput.builder() .readUnitsPerSecond(readUnitsPerSecond) .writeUnitsPerSecond(writeUnitsPerSecond) .build(); } /** * Builds a ProvisionedThroughput object with the specified read and write capacity units. * * @param readCapacityUnits The read capacity units * @param writeCapacityUnits The write capacity units * @return A configured ProvisionedThroughput object */ public static ProvisionedThroughput buildProvisionedThroughput( final Long readCapacityUnits, final Long writeCapacityUnits) { return ProvisionedThroughput.builder() .readCapacityUnits(readCapacityUnits) .writeCapacityUnits(writeCapacityUnits) .build(); } /** * Builds an AttributeDefinition with the specified name and type. * * @param attributeName The attribute name * @param scalarAttributeType The attribute type * @return A configured AttributeDefinition */ private static AttributeDefinition buildAttributeDefinition( final String attributeName, final ScalarAttributeType scalarAttributeType) { return AttributeDefinition.builder() .attributeName(attributeName) .attributeType(scalarAttributeType) .build(); } /** * Builds a KeySchemaElement with the specified name and key type. * * @param attributeName The attribute name * @param keyType The key type (HASH or RANGE) * @return A configured KeySchemaElement */ private static KeySchemaElement buildKeySchemaElement(final String attributeName, final KeyType keyType) { return KeySchemaElement.builder() .attributeName(attributeName) .keyType(keyType) .build(); } /** * Creates a DynamoDB table with the specified configuration including warm throughput settings. * * @param ddb The DynamoDB client * @param tableName The name of the table to create * @param partitionKey The partition key attribute name * @param sortKey The sort key attribute name * @param miscellaneousKeyAttribute Additional key attribute name for GSI * @param nonKeyAttribute Non-key attribute to include in GSI projection * @param tableReadCapacityUnits Read capacity units for the table * @param tableWriteCapacityUnits Write capacity units for the table * @param tableWarmReadUnitsPerSecond Warm read units per second for the table * @param tableWarmWriteUnitsPerSecond Warm write units per second for the table * @param globalSecondaryIndexName The name of the GSI to create * @param globalSecondaryIndexReadCapacityUnits Read capacity units for the GSI * @param globalSecondaryIndexWriteCapacityUnits Write capacity units for the GSI * @param globalSecondaryIndexWarmReadUnitsPerSecond Warm read units per second for the GSI * @param globalSecondaryIndexWarmWriteUnitsPerSecond Warm write units per second for the GSI */ public static void createDynamoDBTable( final DynamoDbClient ddb, final String tableName, final String partitionKey, final String sortKey, final String miscellaneousKeyAttribute, final String nonKeyAttribute, final Long tableReadCapacityUnits, final Long tableWriteCapacityUnits, final Long tableWarmReadUnitsPerSecond, final Long tableWarmWriteUnitsPerSecond, final String globalSecondaryIndexName, final Long globalSecondaryIndexReadCapacityUnits, final Long globalSecondaryIndexWriteCapacityUnits, final Long globalSecondaryIndexWarmReadUnitsPerSecond, final Long globalSecondaryIndexWarmWriteUnitsPerSecond) { // Define the table attributes final AttributeDefinition partitionKeyAttribute = buildAttributeDefinition(partitionKey, ScalarAttributeType.S); final AttributeDefinition sortKeyAttribute = buildAttributeDefinition(sortKey, ScalarAttributeType.S); final AttributeDefinition miscellaneousKeyAttributeDefinition = buildAttributeDefinition(miscellaneousKeyAttribute, ScalarAttributeType.N); final AttributeDefinition[] attributeDefinitions = { partitionKeyAttribute, sortKeyAttribute, miscellaneousKeyAttributeDefinition }; // Define the table key schema final KeySchemaElement partitionKeyElement = buildKeySchemaElement(partitionKey, KeyType.HASH); final KeySchemaElement sortKeyElement = buildKeySchemaElement(sortKey, KeyType.RANGE); final KeySchemaElement[] keySchema = {partitionKeyElement, sortKeyElement}; // Define the provisioned throughput for the table final ProvisionedThroughput provisionedThroughput = buildProvisionedThroughput(tableReadCapacityUnits, tableWriteCapacityUnits); // Define the Global Secondary Index (GSI) final KeySchemaElement globalSecondaryIndexPartitionKeyElement = buildKeySchemaElement(sortKey, KeyType.HASH); final KeySchemaElement globalSecondaryIndexSortKeyElement = buildKeySchemaElement(miscellaneousKeyAttribute, KeyType.RANGE); final KeySchemaElement[] gsiKeySchema = { globalSecondaryIndexPartitionKeyElement, globalSecondaryIndexSortKeyElement }; final Projection gsiProjection = Projection.builder() .projectionType(PROJECTION_TYPE_INCLUDE) .nonKeyAttributes(nonKeyAttribute) .build(); final ProvisionedThroughput gsiProvisionedThroughput = buildProvisionedThroughput(globalSecondaryIndexReadCapacityUnits, globalSecondaryIndexWriteCapacityUnits); // Define the warm throughput for the Global Secondary Index (GSI) final WarmThroughput gsiWarmThroughput = buildWarmThroughput( globalSecondaryIndexWarmReadUnitsPerSecond, globalSecondaryIndexWarmWriteUnitsPerSecond); final GlobalSecondaryIndex globalSecondaryIndex = GlobalSecondaryIndex.builder() .indexName(globalSecondaryIndexName) .keySchema(gsiKeySchema) .projection(gsiProjection) .provisionedThroughput(gsiProvisionedThroughput) .warmThroughput(gsiWarmThroughput) .build(); // Define the warm throughput for the table final WarmThroughput tableWarmThroughput = buildWarmThroughput(tableWarmReadUnitsPerSecond, tableWarmWriteUnitsPerSecond); final CreateTableRequest request = CreateTableRequest.builder() .tableName(tableName) .attributeDefinitions(attributeDefinitions) .keySchema(keySchema) .provisionedThroughput(provisionedThroughput) .globalSecondaryIndexes(globalSecondaryIndex) .warmThroughput(tableWarmThroughput) .build(); final CreateTableResponse response = ddb.createTable(request); System.out.println(response); }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조CreateTable을 참조하세요.

다음 코드 예제에서는 Amazon DynamoDB 테이블의 작업 항목을 추적하고 Amazon Simple Email Service(Amazon SES)를 사용하여 보고서를 전송하는 웹 애플리케이션을 생성하는 방법을 보여줍니다.

SDK for Java 2.x

Amazon DynamoDB API를 사용하여 DynamoDB 작업 데이터를 추적하는 동적 웹 애플리케이션을 만드는 방법을 보여줍니다.

전체 소스 코드와 설정 및 실행 방법에 대한 지침은 GitHub에서 전체 예제를 참조하세요.

이 예제에서 사용되는 서비스
  • DynamoDB

  • Amazon SES

다음 코드 예제에서는 TTL을 사용하여 항목을 생성하는 방법을 보여줍니다.

SDK for Java 2.x
package com.amazon.samplelib.ttl; import com.amazon.samplelib.CodeSampleUtils; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.PutItemRequest; import software.amazon.awssdk.services.dynamodb.model.PutItemResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.util.HashMap; import java.util.Map; import java.util.Optional; /** * Creates an item in a DynamoDB table with TTL attributes. * This class demonstrates how to add TTL expiration timestamps to DynamoDB items. */ public class CreateTTL { private static final String USAGE = """ Usage: <tableName> <primaryKey> <sortKey> <region> Where: tableName - The Amazon DynamoDB table being queried. primaryKey - The name of the primary key. Also known as the hash or partition key. sortKey - The name of the sort key. Also known as the range attribute. region (optional) - The AWS region that the Amazon DynamoDB table is located in. (Default: us-east-1) """; private static final int DAYS_TO_EXPIRE = 90; private static final int SECONDS_PER_DAY = 24 * 60 * 60; private static final String PRIMARY_KEY_ATTR = "primaryKey"; private static final String SORT_KEY_ATTR = "sortKey"; private static final String CREATION_DATE_ATTR = "creationDate"; private static final String EXPIRE_AT_ATTR = "expireAt"; private static final String SUCCESS_MESSAGE = "%s PutItem operation with TTL successful."; private static final String TABLE_NOT_FOUND_ERROR = "Error: The Amazon DynamoDB table \"%s\" can't be found."; private final DynamoDbClient dynamoDbClient; /** * Constructs a CreateTTL instance with the specified DynamoDB client. * * @param dynamoDbClient The DynamoDB client to use */ public CreateTTL(final DynamoDbClient dynamoDbClient) { this.dynamoDbClient = dynamoDbClient; } /** * Constructs a CreateTTL with a default DynamoDB client. */ public CreateTTL() { this.dynamoDbClient = null; } /** * Main method to demonstrate creating an item with TTL. * * @param args Command line arguments */ public static void main(final String[] args) { try { int result = new CreateTTL().processArgs(args); System.exit(result); } catch (Exception e) { System.err.println(e.getMessage()); System.exit(1); } } /** * Process command line arguments and create an item with TTL. * * @param args Command line arguments * @return 0 if successful, non-zero otherwise * @throws ResourceNotFoundException If the table doesn't exist * @throws DynamoDbException If an error occurs during the operation * @throws IllegalArgumentException If arguments are invalid */ public int processArgs(final String[] args) { // Argument validation (remove or replace this line when reusing this code) CodeSampleUtils.validateArgs(args, new int[] {3, 4}, USAGE); final String tableName = args[0]; final String primaryKey = args[1]; final String sortKey = args[2]; final Region region = Optional.ofNullable(args.length > 3 ? args[3] : null) .map(Region::of) .orElse(Region.US_EAST_1); try (DynamoDbClient ddb = dynamoDbClient != null ? dynamoDbClient : DynamoDbClient.builder().region(region).build()) { final CreateTTL createTTL = new CreateTTL(ddb); createTTL.createItemWithTTL(tableName, primaryKey, sortKey); return 0; } catch (Exception e) { throw e; } } /** * Creates an item in the specified table with TTL attributes. * * @param tableName The name of the table * @param primaryKeyValue The value for the primary key * @param sortKeyValue The value for the sort key * @return The response from the PutItem operation * @throws ResourceNotFoundException If the table doesn't exist * @throws DynamoDbException If an error occurs during the operation */ public PutItemResponse createItemWithTTL( final String tableName, final String primaryKeyValue, final String sortKeyValue) { // Get current time in epoch second format final long createDate = System.currentTimeMillis() / 1000; // Calculate expiration time 90 days from now in epoch second format final long expireDate = createDate + (DAYS_TO_EXPIRE * SECONDS_PER_DAY); final Map<String, AttributeValue> itemMap = new HashMap<>(); itemMap.put( PRIMARY_KEY_ATTR, AttributeValue.builder().s(primaryKeyValue).build()); itemMap.put(SORT_KEY_ATTR, AttributeValue.builder().s(sortKeyValue).build()); itemMap.put( CREATION_DATE_ATTR, AttributeValue.builder().n(String.valueOf(createDate)).build()); itemMap.put( EXPIRE_AT_ATTR, AttributeValue.builder().n(String.valueOf(expireDate)).build()); final PutItemRequest request = PutItemRequest.builder().tableName(tableName).item(itemMap).build(); try { final PutItemResponse response = dynamoDbClient.putItem(request); System.out.println(String.format(SUCCESS_MESSAGE, tableName)); return response; } catch (ResourceNotFoundException e) { System.err.format(TABLE_NOT_FOUND_ERROR, tableName); throw e; } catch (DynamoDbException e) { System.err.println(e.getMessage()); throw e; } } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조PutItem을 참조하세요.

다음 코드 예제에서는 Amazon Rekognition을 사용하여 이미지에서 개인 보호 장비(PPE)를 감지하는 앱을 구축하는 방법을 보여줍니다.

SDK for Java 2.x

개인 보호 장비로 이미지를 감지하는 AWS Lambda 함수를 생성하는 방법을 보여줍니다.

전체 소스 코드와 설정 및 실행 방법에 대한 지침은 GitHub에서 전체 예제를 참조하세요.

이 예제에서 사용되는 서비스
  • DynamoDB

  • Amazon Rekognition

  • Amazon S3

  • Amazon SES

다음 코드 예제는 성능 모니터링을 위해 애플리케이션의 DynamoDB 사용을 구성하는 방법을 보여줍니다.

SDK for Java 2.x

이 예제는 DynamoDB의 성능을 모니터링하도록 Java 애플리케이션을 구성하는 방법을 보여줍니다. 애플리케이션은 성능을 모니터링할 수 있는 CloudWatch로 지표 데이터를 전송합니다.

전체 소스 코드와 설정 및 실행 방법에 대한 지침은 GitHub에서 전체 예제를 참조하세요.

이 예시에서 사용되는 서비스
  • CloudWatch

  • DynamoDB

다음 코드 예제에서는 DynamoDB에서 고급 쿼리 작업을 수행하는 방법을 보여줍니다.

  • 다양한 필터링 및 조건 기법을 사용하여 테이블을 쿼리합니다.

  • 대규모 결과 세트에 페이지 매김을 구현합니다.

  • 대체 액세스 패턴에 글로벌 보조 인덱스를 사용합니다.

  • 애플리케이션 요구 사항에 따라 일관성 제어를 적용합니다.

SDK for Java 2.x

를 사용하여 강력히 일관된 읽기로 쿼리합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; public QueryResponse queryWithConsistentReads( final String tableName, final String partitionKeyName, final String partitionKeyValue, final boolean useConsistentRead) { CodeSampleUtils.validateTableParameters(tableName, partitionKeyName, partitionKeyValue); // Create expression attribute names for the column names final Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_PK, partitionKeyName); // Create expression attribute values for the column values final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_PK, AttributeValue.builder().s(partitionKeyValue).build()); // Create the query request final QueryRequest queryRequest = QueryRequest.builder() .tableName(tableName) .keyConditionExpression(KEY_CONDITION_EXPRESSION) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .consistentRead(useConsistentRead) .build(); try { final QueryResponse response = dynamoDbClient.query(queryRequest); LOGGER.log(Level.INFO, "Query successful. Found {0} items", response.count()); return response; } catch (ResourceNotFoundException e) { LOGGER.log(Level.SEVERE, "Table not found: {0}", tableName); throw e; } catch (DynamoDbException e) { LOGGER.log(Level.SEVERE, "Error querying with consistent reads", e); throw e; } }

와 함께 글로벌 보조 인덱스를 사용하여 쿼리합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.util.HashMap; import java.util.Map; public QueryResponse queryTable( final String tableName, final String partitionKeyName, final String partitionKeyValue) { CodeSampleUtils.validateTableParameters(tableName, partitionKeyName, partitionKeyValue); // Create expression attribute names for the column names final Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_PK, partitionKeyName); // Create expression attribute values for the column values final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_PK, AttributeValue.builder().s(partitionKeyValue).build()); // Create the query request final QueryRequest queryRequest = QueryRequest.builder() .tableName(tableName) .keyConditionExpression(KEY_CONDITION_EXPRESSION) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .build(); try { final QueryResponse response = dynamoDbClient.query(queryRequest); System.out.println("Query on base table successful. Found " + response.count() + " items"); return response; } catch (ResourceNotFoundException e) { System.err.format("Error: The Amazon DynamoDB table \"%s\" can't be found.\n", tableName); throw new DynamoDbQueryException("Table not found: " + tableName, e); } catch (DynamoDbException e) { System.err.println("Error querying base table: " + e.getMessage()); throw new DynamoDbQueryException("Failed to execute query on base table", e); } } /** * Queries a DynamoDB Global Secondary Index (GSI) by partition key. * * @param tableName The name of the DynamoDB table * @param indexName The name of the GSI * @param partitionKeyName The name of the GSI partition key attribute * @param partitionKeyValue The value of the GSI partition key to query * @return The query response from DynamoDB * @throws ResourceNotFoundException if the table or index doesn't exist * @throws DynamoDbException if the query fails */ public QueryResponse queryGlobalSecondaryIndex( final String tableName, final String indexName, final String partitionKeyName, final String partitionKeyValue) { CodeSampleUtils.validateTableParameters(tableName, partitionKeyName, partitionKeyValue); CodeSampleUtils.validateStringParameter("Index name", indexName); // Create expression attribute names for the column names final Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_IK, partitionKeyName); // Create expression attribute values for the column values final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_IK, AttributeValue.builder().s(partitionKeyValue).build()); // Create the query request final QueryRequest queryRequest = QueryRequest.builder() .tableName(tableName) .indexName(indexName) .keyConditionExpression(GSI_KEY_CONDITION_EXPRESSION) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .build(); try { final QueryResponse response = dynamoDbClient.query(queryRequest); System.out.println("Query on GSI successful. Found " + response.count() + " items"); return response; } catch (ResourceNotFoundException e) { System.err.format( "Error: The Amazon DynamoDB table \"%s\" or index \"%s\" can't be found.\n", tableName, indexName); throw new DynamoDbQueryException("Table or index not found: " + tableName + "/" + indexName, e); } catch (DynamoDbException e) { System.err.println("Error querying GSI: " + e.getMessage()); throw new DynamoDbQueryException("Failed to execute query on GSI", e); } }

를 사용하여 페이지 매김으로 쿼리합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public List<Map<String, AttributeValue>> queryWithPagination( final String tableName, final String partitionKeyName, final String partitionKeyValue, final int pageSize) { CodeSampleUtils.validateTableParameters(tableName, partitionKeyName, partitionKeyValue); CodeSampleUtils.validatePositiveInteger("Page size", pageSize); // Create expression attribute names for the column names final Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_PK, partitionKeyName); // Create expression attribute values for the column values final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_PK, AttributeValue.builder().s(partitionKeyValue).build()); // Create the query request QueryRequest.Builder queryRequestBuilder = QueryRequest.builder() .tableName(tableName) .keyConditionExpression(KEY_CONDITION_EXPRESSION) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .limit(pageSize); // List to store all items from all pages final List<Map<String, AttributeValue>> allItems = new ArrayList<>(); // Map to store the last evaluated key for pagination Map<String, AttributeValue> lastEvaluatedKey = null; int pageNumber = 1; try { do { // If we have a last evaluated key, use it for the next page if (lastEvaluatedKey != null) { queryRequestBuilder.exclusiveStartKey(lastEvaluatedKey); } // Execute the query final QueryResponse response = dynamoDbClient.query(queryRequestBuilder.build()); // Process the current page of results final List<Map<String, AttributeValue>> pageItems = response.items(); allItems.addAll(pageItems); // Get the last evaluated key for the next page lastEvaluatedKey = response.lastEvaluatedKey(); if (lastEvaluatedKey != null && lastEvaluatedKey.isEmpty()) { lastEvaluatedKey = null; } System.out.println("Page " + pageNumber + ": Retrieved " + pageItems.size() + " items (Running total: " + allItems.size() + ")"); pageNumber++; } while (lastEvaluatedKey != null); System.out.println("Query with pagination complete. Retrieved a total of " + allItems.size() + " items across " + (pageNumber - 1) + " pages"); return allItems; } catch (ResourceNotFoundException e) { System.err.format("Error: The Amazon DynamoDB table \"%s\" can't be found.\n", tableName); throw e; } catch (DynamoDbException e) { System.err.println("Error querying with pagination: " + e.getMessage()); throw e; } }

를 사용하여 복잡한 필터로 쿼리합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; public QueryResponse queryWithComplexFilter( final String tableName, final String partitionKeyName, final String partitionKeyValue, final String statusAttrName, final String activeStatus, final String pendingStatus, final String priceAttrName, final double minPrice, final double maxPrice, final String categoryAttrName) { // Validate parameters CodeSampleUtils.validateTableParameters(tableName, partitionKeyName, partitionKeyValue); CodeSampleUtils.validateStringParameter("Status attribute name", statusAttrName); CodeSampleUtils.validateStringParameter("Active status", activeStatus); CodeSampleUtils.validateStringParameter("Pending status", pendingStatus); CodeSampleUtils.validateStringParameter("Price attribute name", priceAttrName); CodeSampleUtils.validateStringParameter("Category attribute name", categoryAttrName); CodeSampleUtils.validateNumericRange("Minimum price", minPrice, 0.0, Double.MAX_VALUE); CodeSampleUtils.validateNumericRange("Maximum price", maxPrice, minPrice, Double.MAX_VALUE); // Create expression attribute names for the column names final Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put("#pk", partitionKeyName); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_STATUS, statusAttrName); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_PRICE, priceAttrName); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_CATEGORY, categoryAttrName); // Create expression attribute values for the column values final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put( ":pkValue", AttributeValue.builder().s(partitionKeyValue).build()); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_ACTIVE, AttributeValue.builder().s(activeStatus).build()); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_PENDING, AttributeValue.builder().s(pendingStatus).build()); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_MIN_PRICE, AttributeValue.builder().n(String.valueOf(minPrice)).build()); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_MAX_PRICE, AttributeValue.builder().n(String.valueOf(maxPrice)).build()); // Create the query request final QueryRequest queryRequest = QueryRequest.builder() .tableName(tableName) .keyConditionExpression(KEY_CONDITION_EXPRESSION) .filterExpression(FILTER_EXPRESSION) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .build(); return dynamoDbClient.query(queryRequest); }

를 사용하여 동적으로 구성된 필터 표현식을 사용하여 쿼리합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.util.HashMap; import java.util.Map; public static QueryResponse queryWithDynamicFilter( final String tableName, final String partitionKeyName, final String partitionKeyValue, final Map<String, Object> filterCriteria, final Region region, final DynamoDbClient dynamoDbClient) { validateParameters(tableName, partitionKeyName, partitionKeyValue, filterCriteria); DynamoDbClient ddbClient = dynamoDbClient; boolean shouldClose = false; try { if (ddbClient == null) { ddbClient = createClient(region); shouldClose = true; } final QueryWithDynamicFilter queryHelper = new QueryWithDynamicFilter(ddbClient); return queryHelper.queryWithDynamicFilter(tableName, partitionKeyName, partitionKeyValue, filterCriteria); } catch (ResourceNotFoundException e) { System.err.println("Table not found: " + tableName); throw e; } catch (DynamoDbException e) { System.err.println("Failed to execute dynamic filter query: " + e.getMessage()); throw e; } catch (Exception e) { System.err.println("Unexpected error during query: " + e.getMessage()); throw e; } finally { if (shouldClose && ddbClient != null) { ddbClient.close(); } } } public static void main(String[] args) { final String usage = """ Usage: <tableName> <partitionKeyName> <partitionKeyValue> <filterAttrName> <filterAttrValue> [region] Where: tableName - The Amazon DynamoDB table to query. partitionKeyName - The name of the partition key attribute. partitionKeyValue - The value of the partition key to query. filterAttrName - The name of the attribute to filter on. filterAttrValue - The value to filter by. region (optional) - The AWS region where the table exists. (Default: us-east-1) """; if (args.length < 5) { System.out.println(usage); System.exit(1); } final String tableName = args[0]; final String partitionKeyName = args[1]; final String partitionKeyValue = args[2]; final String filterAttrName = args[3]; final String filterAttrValue = args[4]; final Region region = args.length > 5 ? Region.of(args[5]) : Region.US_EAST_1; System.out.println("Querying items with dynamic filter: " + filterAttrName + " = " + filterAttrValue); try { // Using the builder pattern to create and execute the query final QueryResponse response = new DynamicFilterQueryBuilder() .withTableName(tableName) .withPartitionKeyName(partitionKeyName) .withPartitionKeyValue(partitionKeyValue) .withFilterCriterion(filterAttrName, filterAttrValue) .withRegion(region) .execute(); // Process the results System.out.println("Found " + response.count() + " items:"); response.items().forEach(item -> System.out.println(item)); // Demonstrate multiple filter criteria System.out.println("\nNow querying with multiple filter criteria:"); Map<String, Object> multipleFilters = new HashMap<>(); multipleFilters.put(filterAttrName, filterAttrValue); multipleFilters.put("status", "active"); final QueryResponse multiFilterResponse = new DynamicFilterQueryBuilder() .withTableName(tableName) .withPartitionKeyName(partitionKeyName) .withPartitionKeyValue(partitionKeyValue) .withFilterCriteria(multipleFilters) .withRegion(region) .execute(); System.out.println("Found " + multiFilterResponse.count() + " items with multiple filters:"); multiFilterResponse.items().forEach(item -> System.out.println(item)); } catch (IllegalArgumentException e) { System.err.println("Invalid input: " + e.getMessage()); System.exit(1); } catch (ResourceNotFoundException e) { System.err.println("Table not found: " + tableName); System.exit(1); } catch (DynamoDbException e) { System.err.println("DynamoDB error: " + e.getMessage()); System.exit(1); } catch (Exception e) { System.err.println("Unexpected error: " + e.getMessage()); System.exit(1); } }

를 사용하여 필터 표현식 및 제한으로 쿼리합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; public QueryResponse queryWithFilterAndLimit( final String tableName, final String partitionKeyName, final String partitionKeyValue, final String filterAttrName, final String filterAttrValue, final int limit) { CodeSampleUtils.validateTableParameters(tableName, partitionKeyName, partitionKeyValue); CodeSampleUtils.validateStringParameter("Filter attribute name", filterAttrName); CodeSampleUtils.validateStringParameter("Filter attribute value", filterAttrValue); CodeSampleUtils.validatePositiveInteger("Limit", limit); // Create expression attribute names for the column names final Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_PK, partitionKeyName); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_FILTER, filterAttrName); // Create expression attribute values for the column values final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_PK, AttributeValue.builder().s(partitionKeyValue).build()); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_FILTER, AttributeValue.builder().s(filterAttrValue).build()); // Create the filter expression final String filterExpression = "#filterAttr = :filterValue"; // Create the query request final QueryRequest queryRequest = QueryRequest.builder() .tableName(tableName) .keyConditionExpression(KEY_CONDITION_EXPRESSION) .filterExpression(filterExpression) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .limit(limit) .build(); try { final QueryResponse response = dynamoDbClient.query(queryRequest); LOGGER.log(Level.INFO, "Query with filter and limit successful. Found {0} items", response.count()); LOGGER.log( Level.INFO, "ScannedCount: {0} (total items evaluated before filtering)", response.scannedCount()); return response; } catch (ResourceNotFoundException e) { LOGGER.log(Level.SEVERE, "Table not found: {0}", tableName); throw e; } catch (DynamoDbException e) { LOGGER.log(Level.SEVERE, "Error querying with filter and limit: {0}", e.getMessage()); throw e; } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조Query를 참조하세요.

다음 코드 예제에서는 DynamoDB에서 목록 작업을 수행하는 방법을 보여줍니다.

  • 목록 속성에 요소를 추가합니다.

  • 목록 속성에서 요소를 제거합니다.

  • 인덱스별 목록의 특정 요소를 업데이트합니다.

  • 목록 추가 및 목록 인덱스 함수를 사용합니다.

SDK for Java 2.x

를 사용하여 목록 작업을 시연합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.GetItemRequest; import software.amazon.awssdk.services.dynamodb.model.GetItemResponse; import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest; import software.amazon.awssdk.services.dynamodb.model.UpdateItemResponse; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Appends items to a list attribute. * * <p>This method demonstrates how to use the list_append function to add * items to the end of a list attribute. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param listAttributeName The name of the list attribute * @param itemsToAppend The items to append to the list * @return The response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static UpdateItemResponse appendToList( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String listAttributeName, List<AttributeValue> itemsToAppend) { // Create a list value from the items to append AttributeValue listValue = AttributeValue.builder().l(itemsToAppend).build(); // Define the update parameters UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("SET #attrName = list_append(if_not_exists(#attrName, :emptyList), :newItems)") .expressionAttributeNames(Map.of("#attrName", listAttributeName)) .expressionAttributeValues(Map.of( ":newItems", listValue, ":emptyList", AttributeValue.builder().l(new ArrayList<AttributeValue>()).build())) .returnValues("UPDATED_NEW") .build(); // Perform the update operation return dynamoDbClient.updateItem(request); } /** * Prepends items to a list attribute. * * <p>This method demonstrates how to use the list_append function to add * items to the beginning of a list attribute. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param listAttributeName The name of the list attribute * @param itemsToPrepend The items to prepend to the list * @return The response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static UpdateItemResponse prependToList( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String listAttributeName, List<AttributeValue> itemsToPrepend) { // Create a list value from the items to prepend AttributeValue listValue = AttributeValue.builder().l(itemsToPrepend).build(); // Define the update parameters // Note: To prepend, we put the new items first in the list_append function UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("SET #attrName = list_append(:newItems, if_not_exists(#attrName, :emptyList))") .expressionAttributeNames(Map.of("#attrName", listAttributeName)) .expressionAttributeValues(Map.of( ":newItems", listValue, ":emptyList", AttributeValue.builder().l(new ArrayList<AttributeValue>()).build())) .returnValues("UPDATED_NEW") .build(); // Perform the update operation return dynamoDbClient.updateItem(request); } /** * Updates a specific element in a list attribute. * * <p>This method demonstrates how to update a specific element in a list * by its index. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param listAttributeName The name of the list attribute * @param index The index of the element to update * @param newValue The new value for the element * @return The response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static UpdateItemResponse updateListElement( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String listAttributeName, int index, AttributeValue newValue) { // Define the update parameters UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("SET #attrName[" + index + "] = :newValue") .expressionAttributeNames(Map.of("#attrName", listAttributeName)) .expressionAttributeValues(Map.of(":newValue", newValue)) .returnValues("UPDATED_NEW") .build(); // Perform the update operation return dynamoDbClient.updateItem(request); } /** * Removes a specific element from a list attribute. * * <p>This method demonstrates how to remove a specific element from a list * by its index. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param listAttributeName The name of the list attribute * @param index The index of the element to remove * @return The response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static UpdateItemResponse removeListElement( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String listAttributeName, int index) { // Define the update parameters UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("REMOVE #attrName[" + index + "]") .expressionAttributeNames(Map.of("#attrName", listAttributeName)) .returnValues("UPDATED_NEW") .build(); // Perform the update operation return dynamoDbClient.updateItem(request); } /** * Gets the current value of a list attribute. * * <p>Helper method to retrieve the current value of a list attribute. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to get * @param listAttributeName The name of the list attribute * @return The list attribute value or null if not found * @throws DynamoDbException if an error occurs during the operation */ public static List<AttributeValue> getListAttribute( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String listAttributeName) { // Define the get parameters GetItemRequest request = GetItemRequest.builder() .tableName(tableName) .key(key) .projectionExpression(listAttributeName) .build(); try { // Perform the get operation GetItemResponse response = dynamoDbClient.getItem(request); // Return the list attribute if it exists, otherwise null if (response.item() != null && response.item().containsKey(listAttributeName)) { return response.item().get(listAttributeName).l(); } return null; } catch (DynamoDbException e) { throw DynamoDbException.builder() .message("Failed to get list attribute: " + e.getMessage()) .cause(e) .build(); } }

를 사용한 목록 작업 사용의 예입니다 AWS SDK for Java 2.x.

public static void exampleUsage(DynamoDbClient dynamoDbClient, String tableName) { // Example key Map<String, AttributeValue> key = new HashMap<>(); key.put("ProductId", AttributeValue.builder().s("P12345").build()); System.out.println("Demonstrating list operations in DynamoDB"); try { // Example 1: Append items to a list System.out.println("\nExample 1: Appending items to a list"); List<AttributeValue> tagsToAppend = List.of( AttributeValue.builder().s("Electronics").build(), AttributeValue.builder().s("Gadget").build()); UpdateItemResponse appendResponse = appendToList(dynamoDbClient, tableName, key, "Tags", tagsToAppend); System.out.println("Updated list attribute: " + appendResponse.attributes()); // Example 2: Prepend items to a list System.out.println("\nExample 2: Prepending items to a list"); List<AttributeValue> tagsToPrepend = List.of( AttributeValue.builder().s("Featured").build(), AttributeValue.builder().s("New").build()); UpdateItemResponse prependResponse = prependToList(dynamoDbClient, tableName, key, "Tags", tagsToPrepend); System.out.println("Updated list attribute: " + prependResponse.attributes()); // Example 3: Update a specific element in a list System.out.println("\nExample 3: Updating a specific element in a list"); UpdateItemResponse updateResponse = updateListElement( dynamoDbClient, tableName, key, "Tags", 0, AttributeValue.builder().s("BestSeller").build()); System.out.println("Updated list attribute: " + updateResponse.attributes()); // Example 4: Remove a specific element from a list System.out.println("\nExample 4: Removing a specific element from a list"); UpdateItemResponse removeResponse = removeListElement(dynamoDbClient, tableName, key, "Tags", 1); System.out.println("Updated list attribute: " + removeResponse.attributes()); // Example 5: Get the current value of a list attribute System.out.println("\nExample 5: Getting the current value of a list attribute"); List<AttributeValue> currentList = getListAttribute(dynamoDbClient, tableName, key, "Tags"); if (currentList != null) { System.out.println("Current list attribute:"); for (int i = 0; i < currentList.size(); i++) { System.out.println(" [" + i + "]: " + currentList.get(i).s()); } } else { System.out.println("List attribute not found"); } // Explain list operations System.out.println("\nKey points about DynamoDB list operations:"); System.out.println("1. Lists are ordered collections of attributes"); System.out.println("2. Use list_append to add items to a list"); System.out.println("3. To append items, use list_append(existingList, newItems)"); System.out.println("4. To prepend items, use list_append(newItems, existingList)"); System.out.println("5. Use index notation (list[0]) to access or update specific elements"); System.out.println("6. Use REMOVE to delete elements from a list"); System.out.println("7. List indices are zero-based"); System.out.println("8. Use if_not_exists to handle the case where the list doesn't exist yet"); } catch (DynamoDbException e) { System.err.println("Error: " + e.getMessage()); e.printStackTrace(); } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조UpdateItem을 참조하세요.

다음 코드 예제에서는 DynamoDB에서 맵 작업을 수행하는 방법을 보여줍니다.

  • 맵 구조에 중첩 속성을 추가하고 업데이트합니다.

  • 맵에서 특정 필드를 제거합니다.

  • 깊이 중첩된 맵 속성으로 작업합니다.

SDK for Java 2.x

를 사용하여 맵 작업을 시연합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.GetItemRequest; import software.amazon.awssdk.services.dynamodb.model.GetItemResponse; import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest; import software.amazon.awssdk.services.dynamodb.model.UpdateItemResponse; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Updates a map attribute that may not exist. * * <p>This method demonstrates how to safely update a map attribute * by using if_not_exists to handle the case where the map doesn't exist yet. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param mapName The name of the map attribute * @param mapKey The key within the map to update * @param value The value to set * @return The response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static UpdateItemResponse updateMapAttributeSafe( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String mapName, String mapKey, AttributeValue value) { // Create an empty map to use if the map doesn't exist Map<String, AttributeValue> emptyMap = new HashMap<>(); AttributeValue emptyMapValue = AttributeValue.builder().m(emptyMap).build(); // Define the update parameters UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("SET #mapName = if_not_exists(#mapName, :emptyMap), #mapName.#mapKey = :value") .expressionAttributeNames(Map.of( "#mapName", mapName, "#mapKey", mapKey)) .expressionAttributeValues(Map.of( ":value", value, ":emptyMap", AttributeValue.builder().m(new HashMap<>()).build())) .returnValues("UPDATED_NEW") .build(); // Perform the update operation return dynamoDbClient.updateItem(request); } /** * Adds an attribute to a nested map. * * <p>This method demonstrates how to update a nested attribute without * overwriting the entire map. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param path The path to the nested attribute as a list * @param value The value to set * @return The response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static UpdateItemResponse addToNestedMap( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, List<String> path, AttributeValue value) { // Create expression attribute names for each part of the path Map<String, String> expressionAttributeNames = new HashMap<>(); for (int i = 0; i < path.size(); i++) { expressionAttributeNames.put("#attr" + i, path.get(i)); } // Build the attribute path using the expression attribute names StringBuilder attributePathExpression = new StringBuilder(); for (int i = 0; i < path.size(); i++) { if (i > 0) { attributePathExpression.append("."); } attributePathExpression.append("#attr").append(i); } // Define the update parameters UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("SET " + attributePathExpression.toString() + " = :value") .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(Map.of(":value", value)) .returnValues("UPDATED_NEW") .build(); // Perform the update operation return dynamoDbClient.updateItem(request); } /** * Removes an attribute from a map. * * <p>This method demonstrates how to remove a specific attribute from a map. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param mapName The name of the map attribute * @param mapKey The key within the map to remove * @return The response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static UpdateItemResponse removeMapAttribute( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String mapName, String mapKey) { // Define the update parameters UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("REMOVE #mapName.#mapKey") .expressionAttributeNames(Map.of( "#mapName", mapName, "#mapKey", mapKey)) .returnValues("UPDATED_NEW") .build(); // Perform the update operation return dynamoDbClient.updateItem(request); } /** * Creates a map with multiple attributes in a single operation. * * <p>This method demonstrates how to create a map with multiple attributes * in a single update operation. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param mapName The name of the map attribute * @param attributes The attributes to set in the map * @return The response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static UpdateItemResponse createMapWithAttributes( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String mapName, Map<String, AttributeValue> attributes) { // Create a map value from the attributes AttributeValue mapValue = AttributeValue.builder().m(attributes).build(); // Define the update parameters UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("SET #mapName = :mapValue") .expressionAttributeNames(Map.of("#mapName", mapName)) .expressionAttributeValues(Map.of(":mapValue", mapValue)) .returnValues("UPDATED_NEW") .build(); // Perform the update operation return dynamoDbClient.updateItem(request); } /** * Gets the current value of a map attribute. * * <p>Helper method to retrieve the current value of a map attribute. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to get * @param mapName The name of the map attribute * @return The map attribute value or null if not found * @throws DynamoDbException if an error occurs during the operation */ public static Map<String, AttributeValue> getMapAttribute( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String mapName) { // Define the get parameters GetItemRequest request = GetItemRequest.builder() .tableName(tableName) .key(key) .projectionExpression(mapName) .build(); try { // Perform the get operation GetItemResponse response = dynamoDbClient.getItem(request); // Return the map attribute if it exists, otherwise null if (response.item() != null && response.item().containsKey(mapName)) { return response.item().get(mapName).m(); } return null; } catch (DynamoDbException e) { throw DynamoDbException.builder() .message("Failed to get map attribute: " + e.getMessage()) .cause(e) .build(); } }

를 사용한 맵 작업 사용의 예입니다 AWS SDK for Java 2.x.

public static void exampleUsage(DynamoDbClient dynamoDbClient, String tableName) { // Example key Map<String, AttributeValue> key = new HashMap<>(); key.put("ProductId", AttributeValue.builder().s("P12345").build()); System.out.println("Demonstrating map operations in DynamoDB"); try { // Example 1: Create a map with multiple attributes System.out.println("\nExample 1: Creating a map with multiple attributes"); Map<String, AttributeValue> productDetails = new HashMap<>(); productDetails.put("Color", AttributeValue.builder().s("Red").build()); productDetails.put("Weight", AttributeValue.builder().n("2.5").build()); productDetails.put( "Dimensions", AttributeValue.builder().s("10x20x5").build()); UpdateItemResponse createResponse = createMapWithAttributes(dynamoDbClient, tableName, key, "Details", productDetails); System.out.println("Created map attribute: " + createResponse.attributes()); // Example 2: Update a specific attribute in a map System.out.println("\nExample 2: Updating a specific attribute in a map"); UpdateItemResponse updateResponse = updateMapAttributeSafe( dynamoDbClient, tableName, key, "Details", "Color", AttributeValue.builder().s("Blue").build()); System.out.println("Updated map attribute: " + updateResponse.attributes()); // Example 3: Add an attribute to a nested map System.out.println("\nExample 3: Adding an attribute to a nested map"); UpdateItemResponse nestedResponse = addToNestedMap( dynamoDbClient, tableName, key, List.of("Specifications", "Technical", "Resolution"), AttributeValue.builder().s("1920x1080").build()); System.out.println("Added to nested map: " + nestedResponse.attributes()); // Example 4: Remove an attribute from a map System.out.println("\nExample 4: Removing an attribute from a map"); UpdateItemResponse removeResponse = removeMapAttribute(dynamoDbClient, tableName, key, "Details", "Dimensions"); System.out.println("Updated map after removal: " + removeResponse.attributes()); // Example 5: Get the current value of a map attribute System.out.println("\nExample 5: Getting the current value of a map attribute"); Map<String, AttributeValue> currentMap = getMapAttribute(dynamoDbClient, tableName, key, "Details"); if (currentMap != null) { System.out.println("Current map attribute:"); for (Map.Entry<String, AttributeValue> entry : currentMap.entrySet()) { System.out.println(" " + entry.getKey() + ": " + entry.getValue()); } } else { System.out.println("Map attribute not found"); } // Explain map operations System.out.println("\nKey points about DynamoDB map operations:"); System.out.println("1. Maps are unordered collections of name-value pairs"); System.out.println("2. Use dot notation (map.key) to access or update specific attributes"); System.out.println("3. You can update individual attributes without overwriting the entire map"); System.out.println("4. Maps can be nested to create complex data structures"); System.out.println("5. Use REMOVE to delete attributes from a map"); System.out.println("6. You can create a map with multiple attributes in a single operation"); System.out.println("7. Map keys are case-sensitive"); } catch (DynamoDbException e) { System.err.println("Error: " + e.getMessage()); e.printStackTrace(); } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조UpdateItem을 참조하세요.

다음 코드 예제에서는 DynamoDB에서 설정 작업을 수행하는 방법을 보여줍니다.

  • 설정된 속성에 요소를 추가합니다.

  • 설정된 속성에서 요소를 제거합니다.

  • 집합과 함께 ADD 및 DELETE 작업을 사용합니다.

SDK for Java 2.x

를 사용하여 세트 작업을 시연합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.GetItemRequest; import software.amazon.awssdk.services.dynamodb.model.GetItemResponse; import software.amazon.awssdk.services.dynamodb.model.ReturnValue; import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest; import software.amazon.awssdk.services.dynamodb.model.UpdateItemResponse; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; /** * Adds values to a string set attribute. * * <p>This method demonstrates how to use the ADD operation to add values * to a string set attribute. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param setAttributeName The name of the set attribute * @param valuesToAdd The values to add to the set * @return The response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static UpdateItemResponse addToStringSet( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String setAttributeName, Set<String> valuesToAdd) { // Create a string set value from the values to add AttributeValue setValue = AttributeValue.builder().ss(valuesToAdd).build(); // Define the update parameters UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("ADD #setAttr :valuesToAdd") .expressionAttributeNames(Map.of("#setAttr", setAttributeName)) .expressionAttributeValues(Map.of(":valuesToAdd", setValue)) .returnValues(ReturnValue.UPDATED_NEW) .build(); // Perform the update operation return dynamoDbClient.updateItem(request); } /** * Adds values to a number set attribute. * * <p>This method demonstrates how to use the ADD operation to add values * to a number set attribute. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param setAttributeName The name of the set attribute * @param valuesToAdd The values to add to the set * @return The response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static UpdateItemResponse addToNumberSet( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String setAttributeName, Set<Number> valuesToAdd) { // Convert numbers to strings for DynamoDB Set<String> stringValues = new HashSet<>(); for (Number value : valuesToAdd) { stringValues.add(value.toString()); } // Create a number set value from the values to add AttributeValue setValue = AttributeValue.builder().ns(stringValues).build(); // Define the update parameters UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("ADD #setAttr :valuesToAdd") .expressionAttributeNames(Map.of("#setAttr", setAttributeName)) .expressionAttributeValues(Map.of(":valuesToAdd", setValue)) .returnValues(ReturnValue.UPDATED_NEW) .build(); // Perform the update operation return dynamoDbClient.updateItem(request); } /** * Removes values from a set attribute. * * <p>This method demonstrates how to use the DELETE operation to remove values * from a set attribute. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param setAttributeName The name of the set attribute * @param valuesToRemove The values to remove from the set * @param isNumberSet Whether the set is a number set (true) or string set (false) * @return The response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static UpdateItemResponse removeFromSet( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String setAttributeName, Set<?> valuesToRemove, boolean isNumberSet) { AttributeValue setValue; if (isNumberSet) { // Convert numbers to strings for DynamoDB Set<String> stringValues = new HashSet<>(); for (Object value : valuesToRemove) { if (value instanceof Number) { stringValues.add(value.toString()); } else { throw new IllegalArgumentException("Values must be numbers for a number set"); } } setValue = AttributeValue.builder().ns(stringValues).build(); } else { // Convert objects to strings for DynamoDB Set<String> stringValues = new HashSet<>(); for (Object value : valuesToRemove) { stringValues.add(value.toString()); } setValue = AttributeValue.builder().ss(stringValues).build(); } // Define the update parameters UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("DELETE #setAttr :valuesToRemove") .expressionAttributeNames(Map.of("#setAttr", setAttributeName)) .expressionAttributeValues(Map.of(":valuesToRemove", setValue)) .returnValues(ReturnValue.UPDATED_NEW) .build(); // Perform the update operation return dynamoDbClient.updateItem(request); } /** * Checks if a value exists in a set attribute. * * <p>This method demonstrates how to use the contains function to check * if a value exists in a set attribute. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to check * @param setAttributeName The name of the set attribute * @param valueToCheck The value to check for * @return Map containing the result of the check * @throws DynamoDbException if an error occurs during the operation */ public static Map<String, Object> checkIfValueInSet( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String setAttributeName, String valueToCheck) { Map<String, Object> result = new HashMap<>(); try { // Define the update parameters with a condition expression UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("SET #tempAttr = :tempVal") .conditionExpression("contains(#setAttr, :valueToCheck)") .expressionAttributeNames(Map.of("#setAttr", setAttributeName, "#tempAttr", "TempAttribute")) .expressionAttributeValues(Map.of( ":valueToCheck", AttributeValue.builder().s(valueToCheck).build(), ":tempVal", AttributeValue.builder().s("TempValue").build())) .returnValues(ReturnValue.UPDATED_NEW) .build(); // Attempt the update operation dynamoDbClient.updateItem(request); // If we get here, the condition was met result.put("exists", true); result.put("message", "Value '" + valueToCheck + "' exists in the set"); // Clean up the temporary attribute UpdateItemRequest cleanupRequest = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("REMOVE #tempAttr") .expressionAttributeNames(Map.of("#tempAttr", "TempAttribute")) .build(); dynamoDbClient.updateItem(cleanupRequest); } catch (DynamoDbException e) { if (e.getMessage().contains("ConditionalCheckFailed")) { // The condition was not met result.put("exists", false); result.put("message", "Value '" + valueToCheck + "' does not exist in the set"); } else { // Some other error occurred result.put("exists", false); result.put("message", "Error checking set: " + e.getMessage()); result.put("error", e.getClass().getSimpleName()); } } return result; } /** * Creates a set with multiple values in a single operation. * * <p>This method demonstrates how to create a set with multiple values * in a single update operation. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param setAttributeName The name of the set attribute * @param setValues The values to include in the set * @param isNumberSet Whether to create a number set (true) or string set (false) * @return The response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static UpdateItemResponse createSetWithValues( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String setAttributeName, Set<?> setValues, boolean isNumberSet) { AttributeValue setValue; if (isNumberSet) { // Convert numbers to strings for DynamoDB Set<String> stringValues = new HashSet<>(); for (Object value : setValues) { if (value instanceof Number) { stringValues.add(value.toString()); } else { throw new IllegalArgumentException("Values must be numbers for a number set"); } } setValue = AttributeValue.builder().ns(stringValues).build(); } else { // Convert objects to strings for DynamoDB Set<String> stringValues = new HashSet<>(); for (Object value : setValues) { stringValues.add(value.toString()); } setValue = AttributeValue.builder().ss(stringValues).build(); } // Define the update parameters UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("SET #setAttr = :setValue") .expressionAttributeNames(Map.of("#setAttr", setAttributeName)) .expressionAttributeValues(Map.of(":setValue", setValue)) .returnValues(ReturnValue.UPDATED_NEW) .build(); // Perform the update operation return dynamoDbClient.updateItem(request); } /** * Gets the current value of a set attribute. * * <p>Helper method to retrieve the current value of a set attribute. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to get * @param setAttributeName The name of the set attribute * @return The set attribute value or null if not found * @throws DynamoDbException if an error occurs during the operation */ public static AttributeValue getSetAttribute( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String setAttributeName) { // Define the get parameters GetItemRequest request = GetItemRequest.builder() .tableName(tableName) .key(key) .projectionExpression(setAttributeName) .build(); try { // Perform the get operation GetItemResponse response = dynamoDbClient.getItem(request); // Return the set attribute if it exists, otherwise null if (response.item() != null && response.item().containsKey(setAttributeName)) { return response.item().get(setAttributeName); } return null; } catch (DynamoDbException e) { throw DynamoDbException.builder() .message("Failed to get set attribute: " + e.getMessage()) .cause(e) .build(); } }

를 사용한 설정 작업 사용의 예입니다 AWS SDK for Java 2.x.

public static void exampleUsage(DynamoDbClient dynamoDbClient, String tableName) { // Example key Map<String, AttributeValue> key = new HashMap<>(); key.put("ProductId", AttributeValue.builder().s("P12345").build()); System.out.println("Demonstrating set operations in DynamoDB"); try { // Example 1: Create a string set with multiple values System.out.println("\nExample 1: Creating a string set with multiple values"); Set<String> tags = new HashSet<>(); tags.add("Electronics"); tags.add("Gadget"); tags.add("Smartphone"); UpdateItemResponse createResponse = createSetWithValues( dynamoDbClient, tableName, key, "Tags", tags, false // Not a number set ); System.out.println("Created set attribute: " + createResponse.attributes()); // Example 2: Add values to a string set System.out.println("\nExample 2: Adding values to a string set"); Set<String> additionalTags = new HashSet<>(); additionalTags.add("Mobile"); additionalTags.add("Wireless"); UpdateItemResponse addResponse = addToStringSet(dynamoDbClient, tableName, key, "Tags", additionalTags); System.out.println("Updated set attribute: " + addResponse.attributes()); // Example 3: Create a number set with multiple values System.out.println("\nExample 3: Creating a number set with multiple values"); Set<Number> ratings = new HashSet<>(); ratings.add(4); ratings.add(5); ratings.add(4.5); UpdateItemResponse createNumberSetResponse = createSetWithValues( dynamoDbClient, tableName, key, "Ratings", ratings, true // Is a number set ); System.out.println("Created number set attribute: " + createNumberSetResponse.attributes()); // Example 4: Add values to a number set System.out.println("\nExample 4: Adding values to a number set"); Set<Number> additionalRatings = new HashSet<>(); additionalRatings.add(3.5); additionalRatings.add(4.2); UpdateItemResponse addNumberResponse = addToNumberSet(dynamoDbClient, tableName, key, "Ratings", additionalRatings); System.out.println("Updated number set attribute: " + addNumberResponse.attributes()); // Example 5: Remove values from a set System.out.println("\nExample 5: Removing values from a set"); Set<String> tagsToRemove = new HashSet<>(); tagsToRemove.add("Gadget"); UpdateItemResponse removeResponse = removeFromSet( dynamoDbClient, tableName, key, "Tags", tagsToRemove, false // Not a number set ); System.out.println("Updated set after removal: " + removeResponse.attributes()); // Example 6: Check if a value exists in a set System.out.println("\nExample 6: Checking if a value exists in a set"); Map<String, Object> checkResult = checkIfValueInSet(dynamoDbClient, tableName, key, "Tags", "Electronics"); System.out.println("Check result: " + checkResult.get("message")); // Example 7: Get the current value of a set attribute System.out.println("\nExample 7: Getting the current value of a set attribute"); AttributeValue currentStringSet = getSetAttribute(dynamoDbClient, tableName, key, "Tags"); if (currentStringSet != null && currentStringSet.ss() != null) { System.out.println("Current string set values: " + currentStringSet.ss()); } else { System.out.println("String set attribute not found"); } AttributeValue currentNumberSet = getSetAttribute(dynamoDbClient, tableName, key, "Ratings"); if (currentNumberSet != null && currentNumberSet.ns() != null) { System.out.println("Current number set values: " + currentNumberSet.ns()); } else { System.out.println("Number set attribute not found"); } // Explain set operations System.out.println("\nKey points about DynamoDB set operations:"); System.out.println( "1. DynamoDB supports three set types: string sets (SS), number sets (NS), and binary sets (BS)"); System.out.println("2. Sets can only contain elements of the same type"); System.out.println("3. Use ADD to add elements to a set"); System.out.println("4. Use DELETE to remove elements from a set"); System.out.println("5. Sets automatically remove duplicate values"); System.out.println("6. Sets are unordered collections"); System.out.println("7. Use the contains function to check if a value exists in a set"); System.out.println("8. You can create a set with multiple values in a single operation"); } catch (DynamoDbException e) { System.err.println("Error: " + e.getMessage()); e.printStackTrace(); } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조UpdateItem을 참조하세요.

다음 코드 예제에서는 다음과 같은 작업을 수행하는 방법을 보여줍니다.

  • 여러 SELECT 문을 실행하여 항목 배치를 가져옵니다.

  • 여러 INSERT 문을 실행하여 항목 배치를 추가합니다.

  • 여러 UPDATE 문을 실행하여 항목 배치를 업데이트합니다.

  • 여러 DELETE 문을 실행하여 항목 배치를 삭제합니다.

SDK for Java 2.x
참고

GitHub에 더 많은 내용이 있습니다. AWS 코드 예 리포지토리에서 전체 예를 찾고 설정 및 실행하는 방법을 배워보세요.

public class ScenarioPartiQLBatch { public static void main(String[] args) throws IOException { String tableName = "MoviesPartiQBatch"; Region region = Region.US_EAST_1; DynamoDbClient ddb = DynamoDbClient.builder() .region(region) .build(); System.out.println("Creating an Amazon DynamoDB table named " + tableName + " with a key named year and a sort key named title."); createTable(ddb, tableName); System.out.println("Adding multiple records into the " + tableName + " table using a batch command."); putRecordBatch(ddb); // Update multiple movies by using the BatchExecute statement. String title1 = "Star Wars"; int year1 = 1977; String title2 = "Wizard of Oz"; int year2 = 1939; System.out.println("Query two movies."); getBatch(ddb, tableName, title1, title2, year1, year2); System.out.println("Updating multiple records using a batch command."); updateTableItemBatch(ddb); System.out.println("Deleting multiple records using a batch command."); deleteItemBatch(ddb); System.out.println("Deleting the Amazon DynamoDB table."); deleteDynamoDBTable(ddb, tableName); ddb.close(); } public static boolean getBatch(DynamoDbClient ddb, String tableName, String title1, String title2, int year1, int year2) { String getBatch = "SELECT * FROM " + tableName + " WHERE title = ? AND year = ?"; List<BatchStatementRequest> statements = new ArrayList<>(); statements.add(BatchStatementRequest.builder() .statement(getBatch) .parameters(AttributeValue.builder().s(title1).build(), AttributeValue.builder().n(String.valueOf(year1)).build()) .build()); statements.add(BatchStatementRequest.builder() .statement(getBatch) .parameters(AttributeValue.builder().s(title2).build(), AttributeValue.builder().n(String.valueOf(year2)).build()) .build()); BatchExecuteStatementRequest batchExecuteStatementRequest = BatchExecuteStatementRequest.builder() .statements(statements) .build(); try { BatchExecuteStatementResponse response = ddb.batchExecuteStatement(batchExecuteStatementRequest); if (!response.responses().isEmpty()) { response.responses().forEach(r -> { System.out.println(r.item().get("title") + "\\t" + r.item().get("year")); }); return true; } else { System.out.println("Couldn't find either " + title1 + " or " + title2 + "."); return false; } } catch (DynamoDbException e) { System.err.println(e.getMessage()); return false; } } public static void createTable(DynamoDbClient ddb, String tableName) { DynamoDbWaiter dbWaiter = ddb.waiter(); ArrayList<AttributeDefinition> attributeDefinitions = new ArrayList<>(); // Define attributes. attributeDefinitions.add(AttributeDefinition.builder() .attributeName("year") .attributeType("N") .build()); attributeDefinitions.add(AttributeDefinition.builder() .attributeName("title") .attributeType("S") .build()); ArrayList<KeySchemaElement> tableKey = new ArrayList<>(); KeySchemaElement key = KeySchemaElement.builder() .attributeName("year") .keyType(KeyType.HASH) .build(); KeySchemaElement key2 = KeySchemaElement.builder() .attributeName("title") .keyType(KeyType.RANGE) // Sort .build(); // Add KeySchemaElement objects to the list. tableKey.add(key); tableKey.add(key2); CreateTableRequest request = CreateTableRequest.builder() .keySchema(tableKey) .billingMode(BillingMode.PAY_PER_REQUEST) // DynamoDB automatically scales based on traffic. .attributeDefinitions(attributeDefinitions) .tableName(tableName) .build(); try { CreateTableResponse response = ddb.createTable(request); DescribeTableRequest tableRequest = DescribeTableRequest.builder() .tableName(tableName) .build(); // Wait until the Amazon DynamoDB table is created. WaiterResponse<DescribeTableResponse> waiterResponse = dbWaiter .waitUntilTableExists(tableRequest); waiterResponse.matched().response().ifPresent(System.out::println); String newTable = response.tableDescription().tableName(); System.out.println("The " + newTable + " was successfully created."); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } } public static void putRecordBatch(DynamoDbClient ddb) { String sqlStatement = "INSERT INTO MoviesPartiQBatch VALUE {'year':?, 'title' : ?, 'info' : ?}"; try { // Create three movies to add to the Amazon DynamoDB table. // Set data for Movie 1. List<AttributeValue> parameters = new ArrayList<>(); AttributeValue att1 = AttributeValue.builder() .n("1977") .build(); AttributeValue att2 = AttributeValue.builder() .s("Star Wars") .build(); AttributeValue att3 = AttributeValue.builder() .s("No Information") .build(); parameters.add(att1); parameters.add(att2); parameters.add(att3); BatchStatementRequest statementRequestMovie1 = BatchStatementRequest.builder() .statement(sqlStatement) .parameters(parameters) .build(); // Set data for Movie 2. List<AttributeValue> parametersMovie2 = new ArrayList<>(); AttributeValue attMovie2 = AttributeValue.builder() .n("1939") .build(); AttributeValue attMovie2A = AttributeValue.builder() .s("Wizard of Oz") .build(); AttributeValue attMovie2B = AttributeValue.builder() .s("No Information") .build(); parametersMovie2.add(attMovie2); parametersMovie2.add(attMovie2A); parametersMovie2.add(attMovie2B); BatchStatementRequest statementRequestMovie2 = BatchStatementRequest.builder() .statement(sqlStatement) .parameters(parametersMovie2) .build(); // Set data for Movie 3. List<AttributeValue> parametersMovie3 = new ArrayList<>(); AttributeValue attMovie3 = AttributeValue.builder() .n(String.valueOf("2022")) .build(); AttributeValue attMovie3A = AttributeValue.builder() .s("My Movie 3") .build(); AttributeValue attMovie3B = AttributeValue.builder() .s("No Information") .build(); parametersMovie3.add(attMovie3); parametersMovie3.add(attMovie3A); parametersMovie3.add(attMovie3B); BatchStatementRequest statementRequestMovie3 = BatchStatementRequest.builder() .statement(sqlStatement) .parameters(parametersMovie3) .build(); // Add all three movies to the list. List<BatchStatementRequest> myBatchStatementList = new ArrayList<>(); myBatchStatementList.add(statementRequestMovie1); myBatchStatementList.add(statementRequestMovie2); myBatchStatementList.add(statementRequestMovie3); BatchExecuteStatementRequest batchRequest = BatchExecuteStatementRequest.builder() .statements(myBatchStatementList) .build(); BatchExecuteStatementResponse response = ddb.batchExecuteStatement(batchRequest); System.out.println("ExecuteStatement successful: " + response.toString()); System.out.println("Added new movies using a batch command."); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } } public static void updateTableItemBatch(DynamoDbClient ddb) { String sqlStatement = "UPDATE MoviesPartiQBatch SET info = 'directors\":[\"Merian C. Cooper\",\"Ernest B. Schoedsack' where year=? and title=?"; List<AttributeValue> parametersRec1 = new ArrayList<>(); // Update three records. AttributeValue att1 = AttributeValue.builder() .n(String.valueOf("2022")) .build(); AttributeValue att2 = AttributeValue.builder() .s("My Movie 1") .build(); parametersRec1.add(att1); parametersRec1.add(att2); BatchStatementRequest statementRequestRec1 = BatchStatementRequest.builder() .statement(sqlStatement) .parameters(parametersRec1) .build(); // Update record 2. List<AttributeValue> parametersRec2 = new ArrayList<>(); AttributeValue attRec2 = AttributeValue.builder() .n(String.valueOf("2022")) .build(); AttributeValue attRec2a = AttributeValue.builder() .s("My Movie 2") .build(); parametersRec2.add(attRec2); parametersRec2.add(attRec2a); BatchStatementRequest statementRequestRec2 = BatchStatementRequest.builder() .statement(sqlStatement) .parameters(parametersRec2) .build(); // Update record 3. List<AttributeValue> parametersRec3 = new ArrayList<>(); AttributeValue attRec3 = AttributeValue.builder() .n(String.valueOf("2022")) .build(); AttributeValue attRec3a = AttributeValue.builder() .s("My Movie 3") .build(); parametersRec3.add(attRec3); parametersRec3.add(attRec3a); BatchStatementRequest statementRequestRec3 = BatchStatementRequest.builder() .statement(sqlStatement) .parameters(parametersRec3) .build(); // Add all three movies to the list. List<BatchStatementRequest> myBatchStatementList = new ArrayList<>(); myBatchStatementList.add(statementRequestRec1); myBatchStatementList.add(statementRequestRec2); myBatchStatementList.add(statementRequestRec3); BatchExecuteStatementRequest batchRequest = BatchExecuteStatementRequest.builder() .statements(myBatchStatementList) .build(); try { BatchExecuteStatementResponse response = ddb.batchExecuteStatement(batchRequest); System.out.println("ExecuteStatement successful: " + response.toString()); System.out.println("Updated three movies using a batch command."); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } System.out.println("Item was updated!"); } public static void deleteItemBatch(DynamoDbClient ddb) { String sqlStatement = "DELETE FROM MoviesPartiQBatch WHERE year = ? and title=?"; List<AttributeValue> parametersRec1 = new ArrayList<>(); // Specify three records to delete. AttributeValue att1 = AttributeValue.builder() .n(String.valueOf("2022")) .build(); AttributeValue att2 = AttributeValue.builder() .s("My Movie 1") .build(); parametersRec1.add(att1); parametersRec1.add(att2); BatchStatementRequest statementRequestRec1 = BatchStatementRequest.builder() .statement(sqlStatement) .parameters(parametersRec1) .build(); // Specify record 2. List<AttributeValue> parametersRec2 = new ArrayList<>(); AttributeValue attRec2 = AttributeValue.builder() .n(String.valueOf("2022")) .build(); AttributeValue attRec2a = AttributeValue.builder() .s("My Movie 2") .build(); parametersRec2.add(attRec2); parametersRec2.add(attRec2a); BatchStatementRequest statementRequestRec2 = BatchStatementRequest.builder() .statement(sqlStatement) .parameters(parametersRec2) .build(); // Specify record 3. List<AttributeValue> parametersRec3 = new ArrayList<>(); AttributeValue attRec3 = AttributeValue.builder() .n(String.valueOf("2022")) .build(); AttributeValue attRec3a = AttributeValue.builder() .s("My Movie 3") .build(); parametersRec3.add(attRec3); parametersRec3.add(attRec3a); BatchStatementRequest statementRequestRec3 = BatchStatementRequest.builder() .statement(sqlStatement) .parameters(parametersRec3) .build(); // Add all three movies to the list. List<BatchStatementRequest> myBatchStatementList = new ArrayList<>(); myBatchStatementList.add(statementRequestRec1); myBatchStatementList.add(statementRequestRec2); myBatchStatementList.add(statementRequestRec3); BatchExecuteStatementRequest batchRequest = BatchExecuteStatementRequest.builder() .statements(myBatchStatementList) .build(); try { ddb.batchExecuteStatement(batchRequest); System.out.println("Deleted three movies using a batch command."); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } } public static void deleteDynamoDBTable(DynamoDbClient ddb, String tableName) { DeleteTableRequest request = DeleteTableRequest.builder() .tableName(tableName) .build(); try { ddb.deleteTable(request); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } System.out.println(tableName + " was successfully deleted!"); } private static ExecuteStatementResponse executeStatementRequest(DynamoDbClient ddb, String statement, List<AttributeValue> parameters) { ExecuteStatementRequest request = ExecuteStatementRequest.builder() .statement(statement) .parameters(parameters) .build(); return ddb.executeStatement(request); } }

다음 코드 예제에서는 다음과 같은 작업을 수행하는 방법을 보여줍니다.

  • SELECT 문을 실행하여 항목을 가져옵니다.

  • INSERT 문을 실행하여 항목을 추가합니다.

  • UPDATE 문을 실행하여 항목을 업데이트합니다.

  • DELETE 문을 실행하여 항목을 삭제합니다.

SDK for Java 2.x
참고

GitHub에 더 많은 내용이 있습니다. AWS 코드 예 리포지토리에서 전체 예를 찾고 설정 및 실행하는 방법을 배워보세요.

public class ScenarioPartiQ { public static void main(String[] args) throws IOException { String fileName = "../../../resources/sample_files/movies.json"; String tableName = "MoviesPartiQ"; Region region = Region.US_EAST_1; DynamoDbClient ddb = DynamoDbClient.builder() .region(region) .build(); System.out.println( "******* Creating an Amazon DynamoDB table named MoviesPartiQ with a key named year and a sort key named title."); createTable(ddb, tableName); System.out.println("Loading data into the MoviesPartiQ table."); loadData(ddb, fileName); System.out.println("Getting data from the MoviesPartiQ table."); getItem(ddb); System.out.println("Putting a record into the MoviesPartiQ table."); putRecord(ddb); System.out.println("Updating a record."); updateTableItem(ddb); System.out.println("Querying the movies released in 2013."); queryTable(ddb); System.out.println("Deleting the Amazon DynamoDB table."); deleteDynamoDBTable(ddb, tableName); ddb.close(); } public static void createTable(DynamoDbClient ddb, String tableName) { DynamoDbWaiter dbWaiter = ddb.waiter(); ArrayList<AttributeDefinition> attributeDefinitions = new ArrayList<>(); // Define attributes. attributeDefinitions.add(AttributeDefinition.builder() .attributeName("year") .attributeType("N") .build()); attributeDefinitions.add(AttributeDefinition.builder() .attributeName("title") .attributeType("S") .build()); ArrayList<KeySchemaElement> tableKey = new ArrayList<>(); KeySchemaElement key = KeySchemaElement.builder() .attributeName("year") .keyType(KeyType.HASH) .build(); KeySchemaElement key2 = KeySchemaElement.builder() .attributeName("title") .keyType(KeyType.RANGE) // Sort .build(); // Add KeySchemaElement objects to the list. tableKey.add(key); tableKey.add(key2); CreateTableRequest request = CreateTableRequest.builder() .keySchema(tableKey) .billingMode(BillingMode.PAY_PER_REQUEST) //Scales based on traffic. .attributeDefinitions(attributeDefinitions) .tableName(tableName) .build(); try { CreateTableResponse response = ddb.createTable(request); DescribeTableRequest tableRequest = DescribeTableRequest.builder() .tableName(tableName) .build(); // Wait until the Amazon DynamoDB table is created. WaiterResponse<DescribeTableResponse> waiterResponse = dbWaiter.waitUntilTableExists(tableRequest); waiterResponse.matched().response().ifPresent(System.out::println); String newTable = response.tableDescription().tableName(); System.out.println("The " + newTable + " was successfully created."); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } } // Load data into the table. public static void loadData(DynamoDbClient ddb, String fileName) throws IOException { String sqlStatement = "INSERT INTO MoviesPartiQ VALUE {'year':?, 'title' : ?, 'info' : ?}"; JsonParser parser = new JsonFactory().createParser(new File(fileName)); com.fasterxml.jackson.databind.JsonNode rootNode = new ObjectMapper().readTree(parser); Iterator<JsonNode> iter = rootNode.iterator(); ObjectNode currentNode; int t = 0; List<AttributeValue> parameters = new ArrayList<>(); while (iter.hasNext()) { // Add 200 movies to the table. if (t == 200) break; currentNode = (ObjectNode) iter.next(); int year = currentNode.path("year").asInt(); String title = currentNode.path("title").asText(); String info = currentNode.path("info").toString(); AttributeValue att1 = AttributeValue.builder() .n(String.valueOf(year)) .build(); AttributeValue att2 = AttributeValue.builder() .s(title) .build(); AttributeValue att3 = AttributeValue.builder() .s(info) .build(); parameters.add(att1); parameters.add(att2); parameters.add(att3); // Insert the movie into the Amazon DynamoDB table. executeStatementRequest(ddb, sqlStatement, parameters); System.out.println("Added Movie " + title); parameters.remove(att1); parameters.remove(att2); parameters.remove(att3); t++; } } public static void getItem(DynamoDbClient ddb) { String sqlStatement = "SELECT * FROM MoviesPartiQ where year=? and title=?"; List<AttributeValue> parameters = new ArrayList<>(); AttributeValue att1 = AttributeValue.builder() .n("2012") .build(); AttributeValue att2 = AttributeValue.builder() .s("The Perks of Being a Wallflower") .build(); parameters.add(att1); parameters.add(att2); try { ExecuteStatementResponse response = executeStatementRequest(ddb, sqlStatement, parameters); System.out.println("ExecuteStatement successful: " + response.toString()); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } } public static void putRecord(DynamoDbClient ddb) { String sqlStatement = "INSERT INTO MoviesPartiQ VALUE {'year':?, 'title' : ?, 'info' : ?}"; try { List<AttributeValue> parameters = new ArrayList<>(); AttributeValue att1 = AttributeValue.builder() .n(String.valueOf("2020")) .build(); AttributeValue att2 = AttributeValue.builder() .s("My Movie") .build(); AttributeValue att3 = AttributeValue.builder() .s("No Information") .build(); parameters.add(att1); parameters.add(att2); parameters.add(att3); executeStatementRequest(ddb, sqlStatement, parameters); System.out.println("Added new movie."); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } } public static void updateTableItem(DynamoDbClient ddb) { String sqlStatement = "UPDATE MoviesPartiQ SET info = 'directors\":[\"Merian C. Cooper\",\"Ernest B. Schoedsack' where year=? and title=?"; List<AttributeValue> parameters = new ArrayList<>(); AttributeValue att1 = AttributeValue.builder() .n(String.valueOf("2013")) .build(); AttributeValue att2 = AttributeValue.builder() .s("The East") .build(); parameters.add(att1); parameters.add(att2); try { executeStatementRequest(ddb, sqlStatement, parameters); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } System.out.println("Item was updated!"); } // Query the table where the year is 2013. public static void queryTable(DynamoDbClient ddb) { String sqlStatement = "SELECT * FROM MoviesPartiQ where year = ? ORDER BY year"; try { List<AttributeValue> parameters = new ArrayList<>(); AttributeValue att1 = AttributeValue.builder() .n(String.valueOf("2013")) .build(); parameters.add(att1); // Get items in the table and write out the ID value. ExecuteStatementResponse response = executeStatementRequest(ddb, sqlStatement, parameters); System.out.println("ExecuteStatement successful: " + response.toString()); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } } public static void deleteDynamoDBTable(DynamoDbClient ddb, String tableName) { DeleteTableRequest request = DeleteTableRequest.builder() .tableName(tableName) .build(); try { ddb.deleteTable(request); } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); } System.out.println(tableName + " was successfully deleted!"); } private static ExecuteStatementResponse executeStatementRequest(DynamoDbClient ddb, String statement, List<AttributeValue> parameters) { ExecuteStatementRequest request = ExecuteStatementRequest.builder() .statement(statement) .parameters(parameters) .build(); return ddb.executeStatement(request); } private static void processResults(ExecuteStatementResponse executeStatementResult) { System.out.println("ExecuteStatement successful: " + executeStatementResult.toString()); } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조ExecuteStatement를 참조하세요.

다음 코드 예제에서는 글로벌 보조 인덱스를 사용하여 테이블을 쿼리하는 방법을 보여줍니다.

  • 프라이머리 키를 사용하여 DynamoDB 테이블을 쿼리합니다.

  • 글로벌 보조 인덱스(GSI)에서 대체 액세스 패턴을 쿼리합니다.

  • 테이블 쿼리와 GSI 쿼리를 비교합니다.

SDK for Java 2.x

기본 키와를 사용하는 글로벌 보조 인덱스(GSI)를 사용하여 DynamoDB 테이블을 쿼리합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.util.HashMap; import java.util.Map; public QueryResponse queryTable( final String tableName, final String partitionKeyName, final String partitionKeyValue) { CodeSampleUtils.validateTableParameters(tableName, partitionKeyName, partitionKeyValue); // Create expression attribute names for the column names final Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_PK, partitionKeyName); // Create expression attribute values for the column values final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_PK, AttributeValue.builder().s(partitionKeyValue).build()); // Create the query request final QueryRequest queryRequest = QueryRequest.builder() .tableName(tableName) .keyConditionExpression(KEY_CONDITION_EXPRESSION) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .build(); try { final QueryResponse response = dynamoDbClient.query(queryRequest); System.out.println("Query on base table successful. Found " + response.count() + " items"); return response; } catch (ResourceNotFoundException e) { System.err.format("Error: The Amazon DynamoDB table \"%s\" can't be found.\n", tableName); throw new DynamoDbQueryException("Table not found: " + tableName, e); } catch (DynamoDbException e) { System.err.println("Error querying base table: " + e.getMessage()); throw new DynamoDbQueryException("Failed to execute query on base table", e); } } /** * Queries a DynamoDB Global Secondary Index (GSI) by partition key. * * @param tableName The name of the DynamoDB table * @param indexName The name of the GSI * @param partitionKeyName The name of the GSI partition key attribute * @param partitionKeyValue The value of the GSI partition key to query * @return The query response from DynamoDB * @throws ResourceNotFoundException if the table or index doesn't exist * @throws DynamoDbException if the query fails */ public QueryResponse queryGlobalSecondaryIndex( final String tableName, final String indexName, final String partitionKeyName, final String partitionKeyValue) { CodeSampleUtils.validateTableParameters(tableName, partitionKeyName, partitionKeyValue); CodeSampleUtils.validateStringParameter("Index name", indexName); // Create expression attribute names for the column names final Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_IK, partitionKeyName); // Create expression attribute values for the column values final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_IK, AttributeValue.builder().s(partitionKeyValue).build()); // Create the query request final QueryRequest queryRequest = QueryRequest.builder() .tableName(tableName) .indexName(indexName) .keyConditionExpression(GSI_KEY_CONDITION_EXPRESSION) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .build(); try { final QueryResponse response = dynamoDbClient.query(queryRequest); System.out.println("Query on GSI successful. Found " + response.count() + " items"); return response; } catch (ResourceNotFoundException e) { System.err.format( "Error: The Amazon DynamoDB table \"%s\" or index \"%s\" can't be found.\n", tableName, indexName); throw new DynamoDbQueryException("Table or index not found: " + tableName + "/" + indexName, e); } catch (DynamoDbException e) { System.err.println("Error querying GSI: " + e.getMessage()); throw new DynamoDbQueryException("Failed to execute query on GSI", e); } }

테이블 직접 쿼리와 GSI 쿼리를 비교합니다 AWS SDK for Java 2.x.

public static void main(String[] args) { final String usage = """ Usage: <tableName> <basePartitionKeyName> <basePartitionKeyValue> <gsiName> <gsiPartitionKeyName> <gsiPartitionKeyValue> [region] Where: tableName - The Amazon DynamoDB table to query. basePartitionKeyName - The name of the base table partition key attribute. basePartitionKeyValue - The value of the base table partition key to query. gsiName - The name of the Global Secondary Index. gsiPartitionKeyName - The name of the GSI partition key attribute. gsiPartitionKeyValue - The value of the GSI partition key to query. region (optional) - The AWS region where the table exists. (Default: us-east-1) """; if (args.length < 6) { System.out.println(usage); System.exit(1); } final String tableName = args[0]; final String basePartitionKeyName = args[1]; final String basePartitionKeyValue = args[2]; final String gsiName = args[3]; final String gsiPartitionKeyName = args[4]; final String gsiPartitionKeyValue = args[5]; final Region region = args.length > 6 ? Region.of(args[6]) : Region.US_EAST_1; try (DynamoDbClient ddb = DynamoDbClient.builder().region(region).build()) { final QueryTableAndGSI queryHelper = new QueryTableAndGSI(ddb); // Query the base table System.out.println("Querying base table where " + basePartitionKeyName + " = " + basePartitionKeyValue); final QueryResponse tableResponse = queryHelper.queryTable(tableName, basePartitionKeyName, basePartitionKeyValue); System.out.println("Found " + tableResponse.count() + " items in base table:"); tableResponse.items().forEach(item -> System.out.println(item)); // Query the GSI System.out.println( "\nQuerying GSI '" + gsiName + "' where " + gsiPartitionKeyName + " = " + gsiPartitionKeyValue); final QueryResponse gsiResponse = queryHelper.queryGlobalSecondaryIndex(tableName, gsiName, gsiPartitionKeyName, gsiPartitionKeyValue); System.out.println("Found " + gsiResponse.count() + " items in GSI:"); gsiResponse.items().forEach(item -> System.out.println(item)); // Explain the differences between querying a table and a GSI System.out.println("\nKey differences between querying a table and a GSI:"); System.out.println("1. When querying a GSI, you must specify the indexName parameter"); System.out.println("2. GSIs may not contain all attributes from the base table (projection)"); System.out.println("3. GSIs consume read capacity units from the GSI's capacity, not the base table's"); System.out.println("4. GSIs may have eventually consistent data (cannot use ConsistentRead=true)"); } catch (IllegalArgumentException e) { System.err.println("Invalid input: " + e.getMessage()); System.exit(1); } catch (ResourceNotFoundException e) { System.err.println("Table or index not found: " + e.getMessage()); System.exit(1); } catch (DynamoDbException e) { System.err.println("DynamoDB error: " + e.getMessage()); System.exit(1); } catch (Exception e) { System.err.println("Unexpected error: " + e.getMessage()); System.exit(1); } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조Query를 참조하세요.

다음 코드 예제에서는 begins_with 조건을 사용하여 테이블을 쿼리하는 방법을 보여줍니다.

  • 키 조건 표현식에서 begins_with 함수를 사용합니다.

  • 정렬 키의 접두사 패턴을 기준으로 항목을 필터링합니다.

SDK for Java 2.x

AWS SDK for Java 2.x로 정렬 키에 begins_with 조건을 사용하여 DynamoDB 테이블을 쿼리합니다.

import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; public QueryResponse queryWithBeginsWithCondition( final String tableName, final String partitionKeyName, final String partitionKeyValue, final String sortKeyName, final String sortKeyPrefix) { CodeSampleUtils.validateTableParameters(tableName, partitionKeyName, partitionKeyValue); CodeSampleUtils.validateStringParameter("Sort key name", sortKeyName); CodeSampleUtils.validateStringParameter("Sort key prefix", sortKeyPrefix); // Create expression attribute names for the column names final Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_PK, partitionKeyName); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_SK, sortKeyName); // Create expression attribute values for the column values final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_PK, AttributeValue.builder().s(partitionKeyValue).build()); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_SK_PREFIX, AttributeValue.builder().s(sortKeyPrefix).build()); // Create the query request final QueryRequest queryRequest = QueryRequest.builder() .tableName(tableName) .keyConditionExpression(KEY_CONDITION_EXPRESSION) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .build(); try { final QueryResponse response = dynamoDbClient.query(queryRequest); LOGGER.log(Level.INFO, "Query with begins_with condition successful. Found {0} items", response.count()); return response; } catch (ResourceNotFoundException e) { LOGGER.log(Level.SEVERE, "Table not found: {0}", tableName); throw e; } catch (DynamoDbException e) { LOGGER.log(Level.SEVERE, "Error querying with begins_with condition", e); throw e; } }

AWS SDK for Java 2.x로 다양한 접두사 길이의 begins_with를 사용하는 방법을 보여줍니다.

public static void main(String[] args) { try { CodeSampleUtils.BeginsWithQueryConfig config = CodeSampleUtils.BeginsWithQueryConfig.fromArgs(args); LOGGER.log(Level.INFO, "Querying items where {0} = {1} and {2} begins with ''{3}''", new Object[] { config.getPartitionKeyName(), config.getPartitionKeyValue(), config.getSortKeyName(), config.getSortKeyPrefix() }); // Using the builder pattern to create and execute the query final QueryResponse response = new BeginsWithQueryBuilder() .withTableName(config.getTableName()) .withPartitionKeyName(config.getPartitionKeyName()) .withPartitionKeyValue(config.getPartitionKeyValue()) .withSortKeyName(config.getSortKeyName()) .withSortKeyPrefix(config.getSortKeyPrefix()) .withRegion(config.getRegion()) .execute(); // Process the results LOGGER.log(Level.INFO, "Found {0} items:", response.count()); response.items().forEach(item -> LOGGER.info(item.toString())); // Demonstrate with a different prefix if (!config.getSortKeyPrefix().isEmpty()) { String shorterPrefix = config.getSortKeyPrefix() .substring(0, Math.max(1, config.getSortKeyPrefix().length() / 2)); LOGGER.log(Level.INFO, "\nNow querying with a shorter prefix: ''{0}''", shorterPrefix); final QueryResponse response2 = new BeginsWithQueryBuilder() .withTableName(config.getTableName()) .withPartitionKeyName(config.getPartitionKeyName()) .withPartitionKeyValue(config.getPartitionKeyValue()) .withSortKeyName(config.getSortKeyName()) .withSortKeyPrefix(shorterPrefix) .withRegion(config.getRegion()) .execute(); LOGGER.log(Level.INFO, "Found {0} items with shorter prefix:", response2.count()); response2.items().forEach(item -> LOGGER.info(item.toString())); } } catch (IllegalArgumentException e) { LOGGER.log(Level.SEVERE, "Invalid input: {0}", e.getMessage()); printUsage(); } catch (ResourceNotFoundException e) { LOGGER.log(Level.SEVERE, "Table not found", e); } catch (DynamoDbException e) { LOGGER.log(Level.SEVERE, "DynamoDB error", e); } catch (Exception e) { LOGGER.log(Level.SEVERE, "Unexpected error", e); } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조Query를 참조하세요.

다음 코드 예제에서는 정렬 키의 날짜 범위를 사용하여 테이블을 쿼리하는 방법을 보여줍니다.

  • 특정 날짜 범위 내의 항목을 쿼리합니다.

  • 날짜 형식 정렬 키에 비교 연산자를 사용합니다.

SDK for Java 2.x

DynamoDB 테이블에서 날짜 범위 내의 항목을 쿼리합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.time.LocalDate; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; public QueryResponse queryWithDateRange( final String tableName, final String partitionKeyName, final String partitionKeyValue, final String dateKeyName, final LocalDate startDate, final LocalDate endDate) { // Focus on query logic, assuming parameters are valid if (startDate == null || endDate == null) { throw new IllegalArgumentException("Start date and end date cannot be null"); } if (endDate.isBefore(startDate)) { throw new IllegalArgumentException("End date must be after start date"); } // Format dates as ISO strings for DynamoDB (using just the date part) final String formattedStartDate = startDate.toString(); final String formattedEndDate = endDate.toString(); // Create expression attribute names for the column names final Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_PK, partitionKeyName); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_SK, dateKeyName); // Create expression attribute values for the column values final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_PK, AttributeValue.builder().s(partitionKeyValue).build()); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_START_DATE, AttributeValue.builder().s(formattedStartDate).build()); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_END_DATE, AttributeValue.builder().s(formattedEndDate).build()); // Create the query request final QueryRequest queryRequest = QueryRequest.builder() .tableName(tableName) .keyConditionExpression(KEY_CONDITION_EXPRESSION) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .build(); try { final QueryResponse response = dynamoDbClient.query(queryRequest); LOGGER.log(Level.INFO, "Query by date range successful. Found {0} items", response.count()); return response; } catch (ResourceNotFoundException e) { LOGGER.log(Level.SEVERE, "Table not found: {0}", tableName); throw e; } catch (DynamoDbException e) { LOGGER.log(Level.SEVERE, "Error querying by date range: {0}", e.getMessage()); throw e; } }

날짜 범위 필터링을 사용하여 DynamoDB 테이블을 쿼리하는 방법을 보여줍니다.

public static void main(String[] args) { final String usage = """ Usage: <tableName> <partitionKeyName> <partitionKeyValue> <dateKeyName> <startDate> <endDate> [region] Where: tableName - The Amazon DynamoDB table to query. partitionKeyName - The name of the partition key attribute. partitionKeyValue - The value of the partition key to query. dateKeyName - The name of the date attribute to filter on. startDate - The start date for the range query (YYYY-MM-DD). endDate - The end date for the range query (YYYY-MM-DD). region (optional) - The AWS region where the table exists. (Default: us-east-1) """; if (args.length < 6) { System.out.println(usage); System.exit(1); } try { // Parse command line arguments into a config object CodeSampleUtils.DateRangeQueryConfig config = CodeSampleUtils.DateRangeQueryConfig.fromArgs(args); LOGGER.log( Level.INFO, "Querying items from {0} to {1}", new Object[] {config.getStartDate(), config.getEndDate() }); // Using the builder pattern to create and execute the query final QueryResponse response = new DateRangeQueryBuilder() .withTableName(config.getTableName()) .withPartitionKeyName(config.getPartitionKeyName()) .withPartitionKeyValue(config.getPartitionKeyValue()) .withDateKeyName(config.getDateKeyName()) .withStartDate(config.getStartDate()) .withEndDate(config.getEndDate()) .withRegion(config.getRegion()) .execute(); // Process the results LOGGER.log(Level.INFO, "Found {0} items:", response.count()); response.items().forEach(item -> { LOGGER.info(item.toString()); // Extract and display the date attribute for clarity if (item.containsKey(config.getDateKeyName())) { LOGGER.log( Level.INFO, " Date attribute: {0}", item.get(config.getDateKeyName()).s()); } }); // Demonstrate with a different date range LocalDate narrowerStartDate = config.getStartDate().plusDays(1); LocalDate narrowerEndDate = config.getEndDate().minusDays(1); if (!narrowerStartDate.isAfter(narrowerEndDate)) { LOGGER.log(Level.INFO, "\nNow querying with a narrower date range: {0} to {1}", new Object[] { narrowerStartDate, narrowerEndDate }); final QueryResponse response2 = new DateRangeQueryBuilder() .withTableName(config.getTableName()) .withPartitionKeyName(config.getPartitionKeyName()) .withPartitionKeyValue(config.getPartitionKeyValue()) .withDateKeyName(config.getDateKeyName()) .withStartDate(narrowerStartDate) .withEndDate(narrowerEndDate) .withRegion(config.getRegion()) .execute(); LOGGER.log(Level.INFO, "Found {0} items with narrower date range:", response2.count()); response2.items().forEach(item -> LOGGER.info(item.toString())); } LOGGER.info("\nNote: When storing dates in DynamoDB:"); LOGGER.info("1. Use ISO format (YYYY-MM-DD) for lexicographical ordering"); LOGGER.info("2. Use the BETWEEN operator for inclusive date range queries"); LOGGER.info("3. Consider using ISO-8601 format for timestamps with time components"); } catch (IllegalArgumentException e) { LOGGER.log(Level.SEVERE, "Invalid input: {0}", e.getMessage()); System.exit(1); } catch (ResourceNotFoundException e) { LOGGER.log(Level.SEVERE, "Table not found: {0}", e.getMessage()); System.exit(1); } catch (DynamoDbException e) { LOGGER.log(Level.SEVERE, "DynamoDB error: {0}", e.getMessage()); System.exit(1); } catch (Exception e) { LOGGER.log(Level.SEVERE, "Unexpected error: {0}", e.getMessage()); System.exit(1); } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조Query를 참조하세요.

다음 코드 예제에서는 복잡한 필터 표현식을 사용하여 테이블을 쿼리하는 방법을 보여줍니다.

  • 쿼리 결과에 복잡한 필터 표현식을 적용합니다.

  • 논리적 연산자를 사용하여 여러 조건을 결합합니다.

  • 키가 아닌 속성을 기준으로 항목을 필터링합니다.

SDK for Java 2.x

를 사용하여 복잡한 필터 표현식을 사용하여 DynamoDB 테이블을 쿼리합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; public QueryResponse queryWithComplexFilter( final String tableName, final String partitionKeyName, final String partitionKeyValue, final String statusAttrName, final String activeStatus, final String pendingStatus, final String priceAttrName, final double minPrice, final double maxPrice, final String categoryAttrName) { // Validate parameters CodeSampleUtils.validateTableParameters(tableName, partitionKeyName, partitionKeyValue); CodeSampleUtils.validateStringParameter("Status attribute name", statusAttrName); CodeSampleUtils.validateStringParameter("Active status", activeStatus); CodeSampleUtils.validateStringParameter("Pending status", pendingStatus); CodeSampleUtils.validateStringParameter("Price attribute name", priceAttrName); CodeSampleUtils.validateStringParameter("Category attribute name", categoryAttrName); CodeSampleUtils.validateNumericRange("Minimum price", minPrice, 0.0, Double.MAX_VALUE); CodeSampleUtils.validateNumericRange("Maximum price", maxPrice, minPrice, Double.MAX_VALUE); // Create expression attribute names for the column names final Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put("#pk", partitionKeyName); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_STATUS, statusAttrName); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_PRICE, priceAttrName); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_CATEGORY, categoryAttrName); // Create expression attribute values for the column values final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put( ":pkValue", AttributeValue.builder().s(partitionKeyValue).build()); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_ACTIVE, AttributeValue.builder().s(activeStatus).build()); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_PENDING, AttributeValue.builder().s(pendingStatus).build()); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_MIN_PRICE, AttributeValue.builder().n(String.valueOf(minPrice)).build()); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_MAX_PRICE, AttributeValue.builder().n(String.valueOf(maxPrice)).build()); // Create the query request final QueryRequest queryRequest = QueryRequest.builder() .tableName(tableName) .keyConditionExpression(KEY_CONDITION_EXPRESSION) .filterExpression(FILTER_EXPRESSION) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .build(); return dynamoDbClient.query(queryRequest); }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조Query를 참조하세요.

다음 코드 예제에서는 동적 필터 표현식을 사용하여 테이블을 쿼리하는 방법을 보여줍니다.

  • 런타임에 동적으로 필터 표현식을 작성합니다.

  • 사용자 입력 또는 애플리케이션 상태를 기반으로 필터 조건을 구성합니다.

  • 조건부로 필터 기준을 추가하거나 제거합니다.

SDK for Java 2.x

를 사용하여 동적으로 구성된 필터 표현식을 사용하여 DynamoDB 테이블을 쿼리합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.util.HashMap; import java.util.Map; public static QueryResponse queryWithDynamicFilter( final String tableName, final String partitionKeyName, final String partitionKeyValue, final Map<String, Object> filterCriteria, final Region region, final DynamoDbClient dynamoDbClient) { validateParameters(tableName, partitionKeyName, partitionKeyValue, filterCriteria); DynamoDbClient ddbClient = dynamoDbClient; boolean shouldClose = false; try { if (ddbClient == null) { ddbClient = createClient(region); shouldClose = true; } final QueryWithDynamicFilter queryHelper = new QueryWithDynamicFilter(ddbClient); return queryHelper.queryWithDynamicFilter(tableName, partitionKeyName, partitionKeyValue, filterCriteria); } catch (ResourceNotFoundException e) { System.err.println("Table not found: " + tableName); throw e; } catch (DynamoDbException e) { System.err.println("Failed to execute dynamic filter query: " + e.getMessage()); throw e; } catch (Exception e) { System.err.println("Unexpected error during query: " + e.getMessage()); throw e; } finally { if (shouldClose && ddbClient != null) { ddbClient.close(); } } }

동적 필터 표현식을와 함께 사용하는 방법을 보여줍니다 AWS SDK for Java 2.x.

public static void main(String[] args) { final String usage = """ Usage: <tableName> <partitionKeyName> <partitionKeyValue> <filterAttrName> <filterAttrValue> [region] Where: tableName - The Amazon DynamoDB table to query. partitionKeyName - The name of the partition key attribute. partitionKeyValue - The value of the partition key to query. filterAttrName - The name of the attribute to filter on. filterAttrValue - The value to filter by. region (optional) - The AWS region where the table exists. (Default: us-east-1) """; if (args.length < 5) { System.out.println(usage); System.exit(1); } final String tableName = args[0]; final String partitionKeyName = args[1]; final String partitionKeyValue = args[2]; final String filterAttrName = args[3]; final String filterAttrValue = args[4]; final Region region = args.length > 5 ? Region.of(args[5]) : Region.US_EAST_1; System.out.println("Querying items with dynamic filter: " + filterAttrName + " = " + filterAttrValue); try { // Using the builder pattern to create and execute the query final QueryResponse response = new DynamicFilterQueryBuilder() .withTableName(tableName) .withPartitionKeyName(partitionKeyName) .withPartitionKeyValue(partitionKeyValue) .withFilterCriterion(filterAttrName, filterAttrValue) .withRegion(region) .execute(); // Process the results System.out.println("Found " + response.count() + " items:"); response.items().forEach(item -> System.out.println(item)); // Demonstrate multiple filter criteria System.out.println("\nNow querying with multiple filter criteria:"); Map<String, Object> multipleFilters = new HashMap<>(); multipleFilters.put(filterAttrName, filterAttrValue); multipleFilters.put("status", "active"); final QueryResponse multiFilterResponse = new DynamicFilterQueryBuilder() .withTableName(tableName) .withPartitionKeyName(partitionKeyName) .withPartitionKeyValue(partitionKeyValue) .withFilterCriteria(multipleFilters) .withRegion(region) .execute(); System.out.println("Found " + multiFilterResponse.count() + " items with multiple filters:"); multiFilterResponse.items().forEach(item -> System.out.println(item)); } catch (IllegalArgumentException e) { System.err.println("Invalid input: " + e.getMessage()); System.exit(1); } catch (ResourceNotFoundException e) { System.err.println("Table not found: " + tableName); System.exit(1); } catch (DynamoDbException e) { System.err.println("DynamoDB error: " + e.getMessage()); System.exit(1); } catch (Exception e) { System.err.println("Unexpected error: " + e.getMessage()); System.exit(1); } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조Query를 참조하세요.

다음 코드 예제에서는 필터 표현식 및 제한이 있는 테이블을 쿼리하는 방법을 보여줍니다.

  • 평가되는 항목에 제한을 두어 쿼리 결과에 필터 표현식을 적용합니다.

  • 제한이 필터링된 쿼리 결과에 미치는 영향을 이해합니다.

  • 쿼리에서 처리되는 최대 항목 수를 제어합니다.

SDK for Java 2.x

를 사용하여 필터 표현식 및 제한으로 DynamoDB 테이블을 쿼리합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; public QueryResponse queryWithFilterAndLimit( final String tableName, final String partitionKeyName, final String partitionKeyValue, final String filterAttrName, final String filterAttrValue, final int limit) { CodeSampleUtils.validateTableParameters(tableName, partitionKeyName, partitionKeyValue); CodeSampleUtils.validateStringParameter("Filter attribute name", filterAttrName); CodeSampleUtils.validateStringParameter("Filter attribute value", filterAttrValue); CodeSampleUtils.validatePositiveInteger("Limit", limit); // Create expression attribute names for the column names final Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_PK, partitionKeyName); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_FILTER, filterAttrName); // Create expression attribute values for the column values final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_PK, AttributeValue.builder().s(partitionKeyValue).build()); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_FILTER, AttributeValue.builder().s(filterAttrValue).build()); // Create the filter expression final String filterExpression = "#filterAttr = :filterValue"; // Create the query request final QueryRequest queryRequest = QueryRequest.builder() .tableName(tableName) .keyConditionExpression(KEY_CONDITION_EXPRESSION) .filterExpression(filterExpression) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .limit(limit) .build(); try { final QueryResponse response = dynamoDbClient.query(queryRequest); LOGGER.log(Level.INFO, "Query with filter and limit successful. Found {0} items", response.count()); LOGGER.log( Level.INFO, "ScannedCount: {0} (total items evaluated before filtering)", response.scannedCount()); return response; } catch (ResourceNotFoundException e) { LOGGER.log(Level.SEVERE, "Table not found: {0}", tableName); throw e; } catch (DynamoDbException e) { LOGGER.log(Level.SEVERE, "Error querying with filter and limit: {0}", e.getMessage()); throw e; } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조Query를 참조하세요.

다음 코드 예제에서는 중첩 속성이 있는 테이블을 쿼리하는 방법을 보여줍니다.

  • DynamoDB 항목의 중첩 속성을 기준으로 액세스하고 필터링합니다.

  • 문서 경로 표현식을 사용하여 중첩된 요소를 참조합니다.

SDK for Java 2.x

를 사용하여 중첩 속성으로 DynamoDB 테이블을 쿼리합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.util.HashMap; import java.util.Map; public QueryResponse queryWithNestedAttributes( final String tableName, final String partitionKeyName, final String partitionKeyValue, final String nestedPath, final String nestedAttr, final String nestedValue) { CodeSampleUtils.validateTableParameters(tableName, partitionKeyName, partitionKeyValue); CodeSampleUtils.validateStringParameter("Nested path", nestedPath); CodeSampleUtils.validateStringParameter("Nested attribute", nestedAttr); CodeSampleUtils.validateStringParameter("Nested value", nestedValue); // Split the nested path into components final String[] pathComponents = nestedPath.split("\\."); // Create expression attribute names for the column names final Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_PK, partitionKeyName); // Build the nested attribute reference using document path notation final StringBuilder nestedAttributeRef = new StringBuilder(); for (int i = 0; i < pathComponents.length; i++) { final String aliasName = "#n" + i; expressionAttributeNames.put(aliasName, pathComponents[i]); if (i > 0) { nestedAttributeRef.append("."); } nestedAttributeRef.append(aliasName); } // Create expression attribute values for the column values final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_PK, AttributeValue.builder().s(partitionKeyValue).build()); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_NESTED, AttributeValue.builder().s(nestedValue).build()); // Create the filter expression using the nested attribute reference final String filterExpression = nestedAttributeRef + " = :nestedValue"; // Create the query request final QueryRequest queryRequest = QueryRequest.builder() .tableName(tableName) .keyConditionExpression(KEY_CONDITION_EXPRESSION) .filterExpression(filterExpression) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .build(); try { final QueryResponse response = dynamoDbClient.query(queryRequest); System.out.println("Query with nested attribute filter successful. Found " + response.count() + " items"); return response; } catch (ResourceNotFoundException e) { System.err.format("Error: The Amazon DynamoDB table \"%s\" can't be found.\n", tableName); throw e; } catch (DynamoDbException e) { System.err.println("Error querying with nested attribute filter: " + e.getMessage()); throw e; } }

중첩 속성을 사용하여 DynamoDB 테이블을 쿼리하는 방법을 보여줍니다.

public static void main(String[] args) { final String usage = """ Usage: <tableName> <partitionKeyName> <partitionKeyValue> <nestedPath> <nestedAttr> <nestedValue> [region] Where: tableName - The Amazon DynamoDB table to query. partitionKeyName - The name of the partition key attribute. partitionKeyValue - The value of the partition key to query. nestedPath - The path to the nested map attribute (e.g., "address"). nestedAttr - The name of the nested attribute (e.g., "city"). nestedValue - The value to filter by (e.g., "Seattle"). region (optional) - The AWS region where the table exists. (Default: us-east-1) """; if (args.length < 6) { System.out.println(usage); System.exit(1); } final String tableName = args[0]; final String partitionKeyName = args[1]; final String partitionKeyValue = args[2]; final String nestedPath = args[3]; final String nestedAttr = args[4]; final String nestedValue = args[5]; final Region region = args.length > 6 ? Region.of(args[6]) : Region.US_EAST_1; System.out.println("Querying items where " + partitionKeyName + " = " + partitionKeyValue + " and " + nestedPath + "." + nestedAttr + " = " + nestedValue); try { // Using the builder pattern to create and execute the query final QueryResponse response = new NestedAttributeQueryBuilder() .withTableName(tableName) .withPartitionKeyName(partitionKeyName) .withPartitionKeyValue(partitionKeyValue) .withNestedPath(nestedPath) .withNestedAttribute(nestedAttr) .withNestedValue(nestedValue) .withRegion(region) .execute(); // Process the results System.out.println("Found " + response.count() + " items:"); response.items().forEach(item -> { System.out.println(item); // Extract and display the nested attribute for clarity if (item.containsKey(nestedPath) && item.get(nestedPath).hasM()) { Map<String, AttributeValue> nestedMap = item.get(nestedPath).m(); if (nestedMap.containsKey(nestedAttr)) { System.out.println(" Nested attribute " + nestedPath + "." + nestedAttr + ": " + formatAttributeValue(nestedMap.get(nestedAttr))); } } }); System.out.println("\nNote: When working with nested attributes in DynamoDB:"); System.out.println("1. Use dot notation in filter expressions to access nested attributes"); System.out.println("2. Use expression attribute names for each component of the path"); System.out.println("3. Check if the nested attribute exists before accessing it"); } catch (IllegalArgumentException e) { System.err.println("Invalid input: " + e.getMessage()); System.exit(1); } catch (ResourceNotFoundException e) { System.err.println("Table not found: " + tableName); System.exit(1); } catch (DynamoDbException e) { System.err.println("DynamoDB error: " + e.getMessage()); System.exit(1); } catch (Exception e) { System.err.println("Unexpected error: " + e.getMessage()); System.exit(1); } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조Query를 참조하세요.

다음 코드 예제에서는 페이지 매김을 사용하여 테이블을 쿼리하는 방법을 보여줍니다.

  • DynamoDB 쿼리 결과에 페이지 매김을 구현합니다.

  • LastEvaluatedKey를 사용하여 후속 페이지를 검색합니다.

  • Limit 파라미터를 사용하여 페이지당 항목 수를 제어합니다.

SDK for Java 2.x

를 사용하여 페이지 매김으로 DynamoDB 테이블을 쿼리합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public List<Map<String, AttributeValue>> queryWithPagination( final String tableName, final String partitionKeyName, final String partitionKeyValue, final int pageSize) { CodeSampleUtils.validateTableParameters(tableName, partitionKeyName, partitionKeyValue); CodeSampleUtils.validatePositiveInteger("Page size", pageSize); // Create expression attribute names for the column names final Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_PK, partitionKeyName); // Create expression attribute values for the column values final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_PK, AttributeValue.builder().s(partitionKeyValue).build()); // Create the query request QueryRequest.Builder queryRequestBuilder = QueryRequest.builder() .tableName(tableName) .keyConditionExpression(KEY_CONDITION_EXPRESSION) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .limit(pageSize); // List to store all items from all pages final List<Map<String, AttributeValue>> allItems = new ArrayList<>(); // Map to store the last evaluated key for pagination Map<String, AttributeValue> lastEvaluatedKey = null; int pageNumber = 1; try { do { // If we have a last evaluated key, use it for the next page if (lastEvaluatedKey != null) { queryRequestBuilder.exclusiveStartKey(lastEvaluatedKey); } // Execute the query final QueryResponse response = dynamoDbClient.query(queryRequestBuilder.build()); // Process the current page of results final List<Map<String, AttributeValue>> pageItems = response.items(); allItems.addAll(pageItems); // Get the last evaluated key for the next page lastEvaluatedKey = response.lastEvaluatedKey(); if (lastEvaluatedKey != null && lastEvaluatedKey.isEmpty()) { lastEvaluatedKey = null; } System.out.println("Page " + pageNumber + ": Retrieved " + pageItems.size() + " items (Running total: " + allItems.size() + ")"); pageNumber++; } while (lastEvaluatedKey != null); System.out.println("Query with pagination complete. Retrieved a total of " + allItems.size() + " items across " + (pageNumber - 1) + " pages"); return allItems; } catch (ResourceNotFoundException e) { System.err.format("Error: The Amazon DynamoDB table \"%s\" can't be found.\n", tableName); throw e; } catch (DynamoDbException e) { System.err.println("Error querying with pagination: " + e.getMessage()); throw e; } }

페이지 매김을 사용하여 DynamoDB 테이블을 쿼리하는 방법을 보여줍니다.

public static void main(String[] args) { final String usage = """ Usage: <tableName> <partitionKeyName> <partitionKeyValue> [pageSize] [region] Where: tableName - The Amazon DynamoDB table to query. partitionKeyName - The name of the partition key attribute. partitionKeyValue - The value of the partition key to query. pageSize (optional) - The maximum number of items to return per page. (Default: 10) region (optional) - The AWS region where the table exists. (Default: us-east-1) """; if (args.length < 3) { System.out.println(usage); System.exit(1); } final String tableName = args[0]; final String partitionKeyName = args[1]; final String partitionKeyValue = args[2]; final int pageSize = args.length > 3 ? Integer.parseInt(args[3]) : 10; final Region region = args.length > 4 ? Region.of(args[4]) : Region.US_EAST_1; System.out.println("Querying items with pagination (page size: " + pageSize + ")"); try { // Using the builder pattern to create and execute the query final List<Map<String, AttributeValue>> allItems = new PaginationQueryBuilder() .withTableName(tableName) .withPartitionKeyName(partitionKeyName) .withPartitionKeyValue(partitionKeyValue) .withPageSize(pageSize) .withRegion(region) .executeWithPagination(); // Process the results System.out.println("\nSummary: Retrieved a total of " + allItems.size() + " items"); // Display the first few items as a sample final int sampleSize = Math.min(5, allItems.size()); if (sampleSize > 0) { System.out.println("\nSample of retrieved items (first " + sampleSize + "):"); for (int i = 0; i < sampleSize; i++) { System.out.println(allItems.get(i)); } if (allItems.size() > sampleSize) { System.out.println("... and " + (allItems.size() - sampleSize) + " more items"); } } } catch (IllegalArgumentException e) { System.err.println("Invalid input: " + e.getMessage()); System.exit(1); } catch (ResourceNotFoundException e) { System.err.println("Table not found: " + tableName); System.exit(1); } catch (DynamoDbException e) { System.err.println("DynamoDB error: " + e.getMessage()); System.exit(1); } catch (Exception e) { System.err.println("Unexpected error: " + e.getMessage()); System.exit(1); } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조Query를 참조하세요.

다음 코드 예제에서는 강력히 일관된 읽기로 테이블을 쿼리하는 방법을 보여줍니다.

  • DynamoDB 쿼리의 일관성 수준을 구성합니다.

  • 강력하게 일관된 읽기를 사용하여 최신 데이터를 가져옵니다.

  • 최종 일관성과 강력한 일관성의 장단점을 이해합니다.

SDK for Java 2.x

를 사용하여 구성 가능한 읽기 일관성으로 DynamoDB 테이블을 쿼리합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; public QueryResponse queryWithConsistentReads( final String tableName, final String partitionKeyName, final String partitionKeyValue, final boolean useConsistentRead) { CodeSampleUtils.validateTableParameters(tableName, partitionKeyName, partitionKeyValue); // Create expression attribute names for the column names final Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_PK, partitionKeyName); // Create expression attribute values for the column values final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_PK, AttributeValue.builder().s(partitionKeyValue).build()); // Create the query request final QueryRequest queryRequest = QueryRequest.builder() .tableName(tableName) .keyConditionExpression(KEY_CONDITION_EXPRESSION) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .consistentRead(useConsistentRead) .build(); try { final QueryResponse response = dynamoDbClient.query(queryRequest); LOGGER.log(Level.INFO, "Query successful. Found {0} items", response.count()); return response; } catch (ResourceNotFoundException e) { LOGGER.log(Level.SEVERE, "Table not found: {0}", tableName); throw e; } catch (DynamoDbException e) { LOGGER.log(Level.SEVERE, "Error querying with consistent reads", e); throw e; } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조Query를 참조하세요.

다음 코드 예제에서는 TTL 항목을 쿼리하는 방법을 보여줍니다.

SDK for Java 2.x

필터링된 표현식을 쿼리하여를 사용하여 DynamoDB 테이블에서 TTL 항목을 수집합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.util.Map; import java.util.Optional; final QueryRequest request = QueryRequest.builder() .tableName(tableName) .keyConditionExpression(KEY_CONDITION_EXPRESSION) .filterExpression(FILTER_EXPRESSION) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .build(); try (DynamoDbClient ddb = dynamoDbClient != null ? dynamoDbClient : DynamoDbClient.builder().region(region).build()) { final QueryResponse response = ddb.query(request); System.out.println("Query successful. Found " + response.count() + " items that have not expired yet."); // Print each item response.items().forEach(item -> { System.out.println("Item: " + item); }); return 0; } catch (ResourceNotFoundException e) { System.err.format(TABLE_NOT_FOUND_ERROR, tableName); throw e; } catch (DynamoDbException e) { System.err.println(e.getMessage()); throw e; }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조Query를 참조하세요.

다음 코드 예제에서는 날짜 및 시간 패턴을 사용하여 테이블을 쿼리하는 방법을 보여줍니다.

  • DynamoDB에 날짜/시간 값을 저장하고 쿼리합니다.

  • 정렬 키를 사용하여 날짜 범위 쿼리를 구현합니다.

  • 효과적인 쿼리를 위해 날짜 문자열의 형식을 지정합니다.

SDK for Java 2.x

에서 정렬 키의 날짜 범위를 사용하여 쿼리합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.time.LocalDate; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; public QueryResponse queryWithDateRange( final String tableName, final String partitionKeyName, final String partitionKeyValue, final String dateKeyName, final LocalDate startDate, final LocalDate endDate) { // Focus on query logic, assuming parameters are valid if (startDate == null || endDate == null) { throw new IllegalArgumentException("Start date and end date cannot be null"); } if (endDate.isBefore(startDate)) { throw new IllegalArgumentException("End date must be after start date"); } // Format dates as ISO strings for DynamoDB (using just the date part) final String formattedStartDate = startDate.toString(); final String formattedEndDate = endDate.toString(); // Create expression attribute names for the column names final Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_PK, partitionKeyName); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_SK, dateKeyName); // Create expression attribute values for the column values final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_PK, AttributeValue.builder().s(partitionKeyValue).build()); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_START_DATE, AttributeValue.builder().s(formattedStartDate).build()); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_END_DATE, AttributeValue.builder().s(formattedEndDate).build()); // Create the query request final QueryRequest queryRequest = QueryRequest.builder() .tableName(tableName) .keyConditionExpression(KEY_CONDITION_EXPRESSION) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .build(); try { final QueryResponse response = dynamoDbClient.query(queryRequest); LOGGER.log(Level.INFO, "Query by date range successful. Found {0} items", response.count()); return response; } catch (ResourceNotFoundException e) { LOGGER.log(Level.SEVERE, "Table not found: {0}", tableName); throw e; } catch (DynamoDbException e) { LOGGER.log(Level.SEVERE, "Error querying by date range: {0}", e.getMessage()); throw e; } }

에서 날짜-시간 변수를 사용하여 쿼리합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.util.HashMap; import java.util.Map; public QueryResponse queryWithDateTime( final String tableName, final String partitionKeyName, final String partitionKeyValue, final String dateKeyName, final String startDate, final String endDate) { CodeSampleUtils.validateTableParameters(tableName, partitionKeyName, partitionKeyValue); CodeSampleUtils.validateDateRangeParameters(dateKeyName, startDate, endDate); CodeSampleUtils.validateDateFormat("Start date", startDate); CodeSampleUtils.validateDateFormat("End date", endDate); // Create expression attribute names for the column names final Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_PK, partitionKeyName); expressionAttributeNames.put("#dateKey", dateKeyName); // Create expression attribute values for the column values final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_PK, AttributeValue.builder().s(partitionKeyValue).build()); expressionAttributeValues.put( ":startDate", AttributeValue.builder().s(startDate).build()); expressionAttributeValues.put( ":endDate", AttributeValue.builder().s(endDate).build()); // Create the query request final QueryRequest queryRequest = QueryRequest.builder() .tableName(tableName) .keyConditionExpression(KEY_CONDITION_EXPRESSION) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .build(); try { final QueryResponse response = dynamoDbClient.query(queryRequest); System.out.println("Query successful. Found " + response.count() + " items"); return response; } catch (ResourceNotFoundException e) { System.err.format("Error: The Amazon DynamoDB table \"%s\" can't be found.\n", tableName); throw e; } catch (DynamoDbException e) { System.err.println("Error querying with date range: " + e.getMessage()); throw e; } }

AWS SDK for Java 2.x로 Unix 에포크 타임스탬프의 날짜 범위 내에서 쿼리합니다.

import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.util.HashMap; import java.util.Map; public QueryResponse queryWithDateTimeEpoch( final String tableName, final String partitionKeyName, final String partitionKeyValue, final String dateKeyName, final long startEpoch, final long endEpoch) { CodeSampleUtils.validateTableParameters(tableName, partitionKeyName, partitionKeyValue); CodeSampleUtils.validateStringParameter("Date key name", dateKeyName); CodeSampleUtils.validateEpochTimestamp("Start epoch", startEpoch); CodeSampleUtils.validateEpochTimestamp("End epoch", endEpoch); // Create expression attribute names for the column names final Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_PK, partitionKeyName); expressionAttributeNames.put("#dateKey", dateKeyName); // Create expression attribute values for the column values final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_PK, AttributeValue.builder().s(partitionKeyValue).build()); expressionAttributeValues.put( ":startDate", AttributeValue.builder().n(String.valueOf(startEpoch)).build()); expressionAttributeValues.put( ":endDate", AttributeValue.builder().n(String.valueOf(endEpoch)).build()); // Create the query request final QueryRequest queryRequest = QueryRequest.builder() .tableName(tableName) .keyConditionExpression(KEY_CONDITION_EXPRESSION) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .build(); try { final QueryResponse response = dynamoDbClient.query(queryRequest); System.out.println("Query successful. Found " + response.count() + " items"); return response; } catch (ResourceNotFoundException e) { System.err.format("Error: The Amazon DynamoDB table \"%s\" can't be found.\n", tableName); throw e; } catch (DynamoDbException e) { System.err.println("Error querying with epoch timestamps: " + e.getMessage()); throw e; } }

LocalDateTime 객체를와 함께 사용하여 날짜 범위 내에서 쿼리합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.util.HashMap; import java.util.Map; public QueryResponse queryWithDateTimeLocalDateTime( final String tableName, final String partitionKeyName, final String partitionKeyValue, final String dateKeyName, final LocalDateTime startDateTime, final LocalDateTime endDateTime) { CodeSampleUtils.validateTableParameters(tableName, partitionKeyName, partitionKeyValue); CodeSampleUtils.validateStringParameter("Date key name", dateKeyName); if (startDateTime == null || endDateTime == null) { throw new IllegalArgumentException("Start and end LocalDateTime must not be null"); } // Convert LocalDateTime to ISO-8601 strings in UTC with the correct format final String startDate = startDateTime.atZone(ZoneOffset.UTC).format(DATE_TIME_FORMATTER); final String endDate = endDateTime.atZone(ZoneOffset.UTC).format(DATE_TIME_FORMATTER); return queryWithDateTime(tableName, partitionKeyName, partitionKeyValue, dateKeyName, startDate, endDate); }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조Query를 참조하세요.

다음 코드 예제에서는 업데이트 표현식 순서를 이해하는 방법을 보여줍니다.

  • DynamoDB가 업데이트 표현식을 처리하는 방법을 알아봅니다.

  • 업데이트 표현식의 작업 순서를 이해합니다.

  • 표현식 평가를 이해하여 예상치 못한 결과를 방지합니다.

SDK for Java 2.x

를 사용하여 업데이트 표현식 순서를 보여줍니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.GetItemRequest; import software.amazon.awssdk.services.dynamodb.model.GetItemResponse; import software.amazon.awssdk.services.dynamodb.model.ReturnValue; import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest; import software.amazon.awssdk.services.dynamodb.model.UpdateItemResponse; import java.util.HashMap; import java.util.Map; /** * Demonstrates the effect of update expression order. * * <p>This method shows how the order of operations in an update expression * affects the result of the update. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @return Map containing the results of different update orders * @throws DynamoDbException if an error occurs during the operation */ public static Map<String, Object> demonstrateUpdateOrder( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key) { Map<String, Object> results = new HashMap<>(); try { // Initialize the item with a counter UpdateItemRequest initRequest = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("SET Counter = :zero, OldCounter = :zero") .expressionAttributeValues( Map.of(":zero", AttributeValue.builder().n("0").build())) .returnValues(ReturnValue.UPDATED_NEW) .build(); dynamoDbClient.updateItem(initRequest); // Example 1: SET first, then ADD UpdateItemRequest setFirstRequest = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("SET Counter = :value ADD OldCounter :increment") .expressionAttributeValues(Map.of( ":value", AttributeValue.builder().n("10").build(), ":increment", AttributeValue.builder().n("5").build())) .returnValues(ReturnValue.UPDATED_NEW) .build(); UpdateItemResponse setFirstResponse = dynamoDbClient.updateItem(setFirstRequest); results.put("setFirstResponse", setFirstResponse); // Reset the item dynamoDbClient.updateItem(initRequest); // Example 2: ADD first, then SET UpdateItemRequest addFirstRequest = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("ADD Counter :increment SET OldCounter = :value") .expressionAttributeValues(Map.of( ":value", AttributeValue.builder().n("10").build(), ":increment", AttributeValue.builder().n("5").build())) .returnValues(ReturnValue.UPDATED_NEW) .build(); UpdateItemResponse addFirstResponse = dynamoDbClient.updateItem(addFirstRequest); results.put("addFirstResponse", addFirstResponse); // Reset the item dynamoDbClient.updateItem(initRequest); // Example 3: SET with multiple attributes UpdateItemRequest multiSetRequest = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("SET Counter = :value, OldCounter = Counter") .expressionAttributeValues( Map.of(":value", AttributeValue.builder().n("10").build())) .returnValues(ReturnValue.UPDATED_NEW) .build(); UpdateItemResponse multiSetResponse = dynamoDbClient.updateItem(multiSetRequest); results.put("multiSetResponse", multiSetResponse); // Reset the item dynamoDbClient.updateItem(initRequest); // Example 4: SET with expression using the same attribute UpdateItemRequest selfReferenceRequest = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("SET Counter = Counter + :increment, OldCounter = Counter") .expressionAttributeValues( Map.of(":increment", AttributeValue.builder().n("5").build())) .returnValues(ReturnValue.UPDATED_NEW) .build(); UpdateItemResponse selfReferenceResponse = dynamoDbClient.updateItem(selfReferenceRequest); results.put("selfReferenceResponse", selfReferenceResponse); results.put("success", true); } catch (DynamoDbException e) { results.put("success", false); results.put("error", e.getMessage()); } return results; } /** * Updates an item with SET first, then REMOVE. * * <p>This method demonstrates updating an item with SET operation first, * followed by a REMOVE operation. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param attributeToSet The attribute to set * @param setValue The value to set * @param attributeToRemove The attribute to remove * @return The response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static UpdateItemResponse updateWithSetFirst( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String attributeToSet, AttributeValue setValue, String attributeToRemove) { // Define the update parameters UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("SET #setAttr = :setValue REMOVE #removeAttr") .expressionAttributeNames(Map.of( "#setAttr", attributeToSet, "#removeAttr", attributeToRemove)) .expressionAttributeValues(Map.of(":setValue", setValue)) .returnValues(ReturnValue.UPDATED_NEW) .build(); // Perform the update operation try { return dynamoDbClient.updateItem(request); } catch (DynamoDbException e) { throw DynamoDbException.builder() .message("Failed to update item with SET first: " + e.getMessage()) .cause(e) .build(); } } /** * Updates an item with REMOVE first, then SET. * * <p>This method demonstrates updating an item with REMOVE operation first, * followed by a SET operation. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param attributeToSet The attribute to set * @param setValue The value to set * @param attributeToRemove The attribute to remove * @return The response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static UpdateItemResponse updateWithRemoveFirst( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String attributeToSet, AttributeValue setValue, String attributeToRemove) { // Define the update parameters UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("REMOVE #removeAttr SET #setAttr = :setValue") .expressionAttributeNames(Map.of( "#setAttr", attributeToSet, "#removeAttr", attributeToRemove)) .expressionAttributeValues(Map.of(":setValue", setValue)) .returnValues(ReturnValue.UPDATED_NEW) .build(); // Perform the update operation try { return dynamoDbClient.updateItem(request); } catch (DynamoDbException e) { throw DynamoDbException.builder() .message("Failed to update item with REMOVE first: " + e.getMessage()) .cause(e) .build(); } } /** * Updates an item with all operation types in a specific order. * * <p>This method demonstrates using all operation types (SET, REMOVE, ADD, DELETE) * in a specific order in a single update expression. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @return The response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static UpdateItemResponse updateWithAllOperationTypes( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key) { // Define the update parameters UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("SET #stringAttr = :stringVal, #mapAttr.#nestedAttr = :nestedVal " + "REMOVE #oldAttr " + "ADD #counterAttr :increment " + "DELETE #stringSetAttr :stringSetVal") .expressionAttributeNames(Map.of( "#stringAttr", "StringAttribute", "#mapAttr", "MapAttribute", "#nestedAttr", "NestedAttribute", "#oldAttr", "OldAttribute", "#counterAttr", "CounterAttribute", "#stringSetAttr", "StringSetAttribute")) .expressionAttributeValues(Map.of( ":stringVal", AttributeValue.builder().s("New Value").build(), ":nestedVal", AttributeValue.builder().s("Nested Value").build(), ":increment", AttributeValue.builder().n("1").build(), ":stringSetVal", AttributeValue.builder().ss("Value1").build())) .returnValues(ReturnValue.UPDATED_NEW) .build(); // Perform the update operation try { return dynamoDbClient.updateItem(request); } catch (DynamoDbException e) { throw DynamoDbException.builder() .message("Failed to update item with all operation types: " + e.getMessage()) .cause(e) .build(); } } /** * Gets the current state of an item. * * <p>Helper method to retrieve the current state of an item. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to get * @return The item or null if not found * @throws DynamoDbException if an error occurs during the operation */ public static Map<String, AttributeValue> getItem( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key) { // Define the get parameters GetItemRequest request = GetItemRequest.builder().tableName(tableName).key(key).build(); // Perform the get operation try { GetItemResponse response = dynamoDbClient.getItem(request); // Return the item if it exists, otherwise null return response.item(); } catch (DynamoDbException e) { throw DynamoDbException.builder() .message("Failed to get item: " + e.getMessage()) .cause(e) .build(); } }

를 사용한 업데이트 표현식 순서 사용의 예입니다 AWS SDK for Java 2.x.

public static void exampleUsage(DynamoDbClient dynamoDbClient, String tableName) { // Example key Map<String, AttributeValue> key = new HashMap<>(); key.put("ProductId", AttributeValue.builder().s("P12345").build()); System.out.println("Demonstrating update expression order in DynamoDB"); try { // Example 1: Demonstrate update order effects System.out.println("\nExample 1: Demonstrating update order effects"); Map<String, Object> orderResults = demonstrateUpdateOrder(dynamoDbClient, tableName, key); if ((boolean) orderResults.get("success")) { System.out.println("SET first, then ADD:"); System.out.println(" " + orderResults.get("setFirstResponse")); System.out.println("ADD first, then SET:"); System.out.println(" " + orderResults.get("addFirstResponse")); System.out.println("SET with multiple attributes:"); System.out.println(" " + orderResults.get("multiSetResponse")); System.out.println("SET with self-reference:"); System.out.println(" " + orderResults.get("selfReferenceResponse")); } else { System.out.println("Error: " + orderResults.get("error")); } // Example 2: Update with SET first, then REMOVE System.out.println("\nExample 2: Update with SET first, then REMOVE"); UpdateItemResponse setFirstResponse = updateWithSetFirst( dynamoDbClient, tableName, key, "Status", AttributeValue.builder().s("Active").build(), "OldStatus"); System.out.println("Updated attributes: " + setFirstResponse.attributes()); // Example 3: Update with REMOVE first, then SET System.out.println("\nExample 3: Update with REMOVE first, then SET"); UpdateItemResponse removeFirstResponse = updateWithRemoveFirst( dynamoDbClient, tableName, key, "Status", AttributeValue.builder().s("Inactive").build(), "OldStatus"); System.out.println("Updated attributes: " + removeFirstResponse.attributes()); // Example 4: Update with all operation types System.out.println("\nExample 4: Update with all operation types"); UpdateItemResponse allOpsResponse = updateWithAllOperationTypes(dynamoDbClient, tableName, key); System.out.println("Updated attributes: " + allOpsResponse.attributes()); // Example 5: Get the current state of the item System.out.println("\nExample 5: Current state of the item"); Map<String, AttributeValue> item = getItem(dynamoDbClient, tableName, key); if (item != null) { System.out.println("Item: " + item); } else { System.out.println("Item not found"); } // Explain update expression order System.out.println("\nKey points about update expression order in DynamoDB:"); System.out.println("1. Update expressions are processed in this order: SET, REMOVE, ADD, DELETE"); System.out.println("2. Within each clause, operations are processed from left to right"); System.out.println("3. SET operations use the item state before any updates in the expression"); System.out.println("4. When an attribute is referenced multiple times, the first operation wins"); System.out.println("5. To reference a new value, split the update into multiple operations"); System.out.println("6. The order of clauses in the expression doesn't change the evaluation order"); System.out.println("7. For complex updates, consider using multiple separate update operations"); } catch (DynamoDbException e) { System.err.println("Error: " + e.getMessage()); e.printStackTrace(); } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조UpdateItem을 참조하세요.

다음 코드 예제에서는 테이블의 웜 처리량 설정을 업데이트하는 방법을 보여줍니다.

SDK for Java 2.x

AWS SDK for Java 2.x를 사용하여 기존 DynamoDB 테이블에서 웜 처리량 설정을 업데이트합니다.

import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.GlobalSecondaryIndexUpdate; import software.amazon.awssdk.services.dynamodb.model.UpdateGlobalSecondaryIndexAction; import software.amazon.awssdk.services.dynamodb.model.UpdateTableRequest; import software.amazon.awssdk.services.dynamodb.model.WarmThroughput; public static WarmThroughput buildWarmThroughput(final Long readUnitsPerSecond, final Long writeUnitsPerSecond) { return WarmThroughput.builder() .readUnitsPerSecond(readUnitsPerSecond) .writeUnitsPerSecond(writeUnitsPerSecond) .build(); } /** * Updates a DynamoDB table with warm throughput settings for both the table and a global secondary index. * * @param ddb The DynamoDB client * @param tableName The name of the table to update * @param tableReadUnitsPerSecond Read units per second for the table * @param tableWriteUnitsPerSecond Write units per second for the table * @param globalSecondaryIndexName The name of the global secondary index to update * @param globalSecondaryIndexReadUnitsPerSecond Read units per second for the GSI * @param globalSecondaryIndexWriteUnitsPerSecond Write units per second for the GSI */ public static void updateDynamoDBTable( final DynamoDbClient ddb, final String tableName, final Long tableReadUnitsPerSecond, final Long tableWriteUnitsPerSecond, final String globalSecondaryIndexName, final Long globalSecondaryIndexReadUnitsPerSecond, final Long globalSecondaryIndexWriteUnitsPerSecond) { final WarmThroughput tableWarmThroughput = buildWarmThroughput(tableReadUnitsPerSecond, tableWriteUnitsPerSecond); final WarmThroughput gsiWarmThroughput = buildWarmThroughput(globalSecondaryIndexReadUnitsPerSecond, globalSecondaryIndexWriteUnitsPerSecond); final GlobalSecondaryIndexUpdate globalSecondaryIndexUpdate = GlobalSecondaryIndexUpdate.builder() .update(UpdateGlobalSecondaryIndexAction.builder() .indexName(globalSecondaryIndexName) .warmThroughput(gsiWarmThroughput) .build()) .build(); final UpdateTableRequest request = UpdateTableRequest.builder() .tableName(tableName) .globalSecondaryIndexUpdates(globalSecondaryIndexUpdate) .warmThroughput(tableWarmThroughput) .build(); try { ddb.updateTable(request); } catch (DynamoDbException e) { System.err.println(e.getMessage()); throw e; } System.out.println(SUCCESS_MESSAGE); }
  • API에 대한 세부 정보는 AWS SDK for Java 2.x API 참조UpdateTable을 참조하세요.

다음 코드 예제에서는 항목의 TTL을 업데이트하는 방법을 보여줍니다.

SDK for Java 2.x

테이블의 기존 DynamoDB 항목에서 TTL을 업데이트합니다.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest; import software.amazon.awssdk.services.dynamodb.model.UpdateItemResponse; import java.util.HashMap; import java.util.Map; import java.util.Optional; public UpdateItemResponse updateItemWithTTL( final String tableName, final String primaryKeyValue, final String sortKeyValue) { // Get current time in epoch second format final long currentTime = System.currentTimeMillis() / 1000; // Calculate expiration time 90 days from now in epoch second format final long expireDate = currentTime + (DAYS_TO_EXPIRE * SECONDS_PER_DAY); // Create the key map for the item to update final Map<String, AttributeValue> keyMap = new HashMap<>(); keyMap.put(PRIMARY_KEY_ATTR, AttributeValue.builder().s(primaryKeyValue).build()); keyMap.put(SORT_KEY_ATTR, AttributeValue.builder().s(sortKeyValue).build()); // Create the expression attribute values final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put( ":c", AttributeValue.builder().n(String.valueOf(currentTime)).build()); expressionAttributeValues.put( ":e", AttributeValue.builder().n(String.valueOf(expireDate)).build()); final UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(keyMap) .updateExpression(UPDATE_EXPRESSION) .expressionAttributeValues(expressionAttributeValues) .build(); try { final UpdateItemResponse response = dynamoDbClient.updateItem(request); System.out.println(String.format(SUCCESS_MESSAGE, tableName)); return response; } catch (ResourceNotFoundException e) { System.err.format(TABLE_NOT_FOUND_ERROR, tableName); throw e; } catch (DynamoDbException e) { System.err.println(e.getMessage()); throw e; } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조UpdateItem을 참조하세요.

다음 코드 예제에서는 Amazon API Gateway에서 호출한 AWS Lambda 함수를 생성하는 방법을 보여줍니다.

SDK for Java 2.x

Lambda Java 런타임 API를 사용하여 AWS Lambda 함수를 생성하는 방법을 보여줍니다. 이 예제에서는 다양한 AWS 서비스를 호출하여 특정 사용 사례를 수행합니다. 이 예제에서는 Amazon API Gateway에서 간접 호출한 Lambda 함수를 생성하여 작업 기념일에 대한 Amazon DynamoDB 테이블을 스캔하고 Amazon Simple Notification Service(Amazon SNS)를 사용하여 직원에게 1주년 기념일을 축하하는 문자 메시지를 전송하는 방법을 보여줍니다.

전체 소스 코드와 설정 및 실행 방법에 대한 지침은 GitHub에서 전체 예제를 참조하세요.

이 예제에서 사용되는 서비스
  • API Gateway

  • DynamoDB

  • Lambda

  • Amazon SNS

다음 코드 예제에서는 AWS Lambda 함수를 순차적으로 호출하는 AWS Step Functions 상태 시스템을 생성하는 방법을 보여줍니다.

SDK for Java 2.x

AWS Step Functions 및를 사용하여 AWS 서버리스 워크플로를 생성하는 방법을 보여줍니다 AWS SDK for Java 2.x. 각 워크플로 단계는 AWS Lambda 함수를 사용하여 구현됩니다.

전체 소스 코드와 설정 및 실행 방법에 대한 지침은 GitHub에서 전체 예제를 참조하세요.

이 예제에서 사용되는 서비스
  • DynamoDB

  • Lambda

  • Amazon SES

  • Step Functions

다음 코드 예제에서는 DynamoDB에서 원자성 카운터 작업을 사용하는 방법을 보여줍니다.

  • ADD 및 SET 작업을 사용하여 원자적으로 카운터를 늘립니다.

  • 존재하지 않을 수 있는 카운터를 안전하게 증가시킵니다.

  • 카운터 작업에 대한 낙관적 잠금을 구현합니다.

SDK for Java 2.x

를 사용하여 원자성 카운터 작업을 시연합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.GetItemRequest; import software.amazon.awssdk.services.dynamodb.model.GetItemResponse; import software.amazon.awssdk.services.dynamodb.model.ReturnValue; import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest; import software.amazon.awssdk.services.dynamodb.model.UpdateItemResponse; import java.util.HashMap; import java.util.Map; /** * Increments a counter using the ADD operation. * * <p>This method demonstrates how to use the ADD operation to atomically * increment a counter attribute. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param counterName The name of the counter attribute * @param incrementValue The value to increment by * @return The response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static UpdateItemResponse incrementCounterWithAdd( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String counterName, int incrementValue) { // Define the update parameters UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("ADD #counterName :increment") .expressionAttributeNames(Map.of("#counterName", counterName)) .expressionAttributeValues(Map.of( ":increment", AttributeValue.builder().n(String.valueOf(incrementValue)).build())) .returnValues(ReturnValue.UPDATED_NEW) .build(); // Perform the update operation return dynamoDbClient.updateItem(request); } /** * Increments a counter using the SET operation. * * <p>This method demonstrates how to use the SET operation with an expression * to increment a counter attribute. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param counterName The name of the counter attribute * @param incrementValue The value to increment by * @return The response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static UpdateItemResponse incrementCounterWithSet( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String counterName, int incrementValue) { // Define the update parameters UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("SET #counterName = #counterName + :increment") .expressionAttributeNames(Map.of("#counterName", counterName)) .expressionAttributeValues(Map.of( ":increment", AttributeValue.builder().n(String.valueOf(incrementValue)).build())) .returnValues(ReturnValue.UPDATED_NEW) .build(); // Perform the update operation return dynamoDbClient.updateItem(request); } /** * Increments a counter safely, handling the case where the counter doesn't exist yet. * * <p>This method demonstrates how to use if_not_exists to safely increment a counter * that may not exist yet. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param counterName The name of the counter attribute * @param incrementValue The value to increment by * @return The response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static UpdateItemResponse incrementCounterSafely( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String counterName, int incrementValue) { // Define the update parameters UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("SET #counterName = if_not_exists(#counterName, :zero) + :increment") .expressionAttributeNames(Map.of("#counterName", counterName)) .expressionAttributeValues(Map.of( ":increment", AttributeValue.builder().n(String.valueOf(incrementValue)).build(), ":zero", AttributeValue.builder().n("0").build())) .returnValues(ReturnValue.UPDATED_NEW) .build(); // Perform the update operation return dynamoDbClient.updateItem(request); } /** * Decrements a counter safely, ensuring it doesn't go below zero. * * <p>This method demonstrates how to use a condition expression to safely * decrement a counter without going below zero. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param counterName The name of the counter attribute * @param decrementValue The value to decrement by * @return The response from DynamoDB * @throws DynamoDbException if an error occurs during the operation or if the counter would go below zero */ public static UpdateItemResponse decrementCounterSafely( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String counterName, int decrementValue) { // Define the update parameters UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("SET #counterName = #counterName - :decrement") .conditionExpression("#counterName >= :decrement") .expressionAttributeNames(Map.of("#counterName", counterName)) .expressionAttributeValues(Map.of( ":decrement", AttributeValue.builder().n(String.valueOf(decrementValue)).build())) .returnValues(ReturnValue.UPDATED_NEW) .build(); // Perform the update operation return dynamoDbClient.updateItem(request); } /** * Compares the ADD and SET approaches for incrementing counters. * * <p>This method demonstrates the differences between using ADD and SET * for incrementing counters in DynamoDB. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @return Map containing the comparison results */ public static Map<String, Object> compareAddVsSet( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key) { Map<String, Object> results = new HashMap<>(); try { // Reset counters to ensure a fair comparison UpdateItemRequest resetRequest = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("SET AddCounter = :zero, SetCounter = :zero") .expressionAttributeValues( Map.of(":zero", AttributeValue.builder().n("0").build())) .build(); dynamoDbClient.updateItem(resetRequest); // Increment with ADD long addStartTime = System.nanoTime(); UpdateItemResponse addResponse = incrementCounterWithAdd(dynamoDbClient, tableName, key, "AddCounter", 1); long addEndTime = System.nanoTime(); long addDuration = addEndTime - addStartTime; // Increment with SET long setStartTime = System.nanoTime(); UpdateItemResponse setResponse = incrementCounterWithSet(dynamoDbClient, tableName, key, "SetCounter", 1); long setEndTime = System.nanoTime(); long setDuration = setEndTime - setStartTime; // Record results results.put("addResponse", addResponse); results.put("setResponse", setResponse); results.put("addDuration", addDuration); results.put("setDuration", setDuration); results.put("success", true); } catch (DynamoDbException e) { results.put("success", false); results.put("error", e.getMessage()); } return results; } /** * Gets the current value of a counter attribute. * * <p>Helper method to retrieve the current value of a counter attribute. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to get * @param counterName The name of the counter attribute * @return The counter value or null if not found * @throws DynamoDbException if an error occurs during the operation */ public static Integer getCounterValue( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String counterName) { // Define the get parameters GetItemRequest request = GetItemRequest.builder() .tableName(tableName) .key(key) .projectionExpression(counterName) .build(); // Perform the get operation GetItemResponse response = dynamoDbClient.getItem(request); // Return the counter value if it exists, otherwise null if (response.item() != null && response.item().containsKey(counterName)) { return Integer.parseInt(response.item().get(counterName).n()); } return null; }

에서 원자성 카운터 작업의 사용 예입니다 AWS SDK for Java 2.x.

public static void exampleUsage(DynamoDbClient dynamoDbClient, String tableName) { // Example key Map<String, AttributeValue> key = new HashMap<>(); key.put("ProductId", AttributeValue.builder().s("P12345").build()); System.out.println("Demonstrating atomic counter operations in DynamoDB"); try { // Example 1: Increment a counter using ADD System.out.println("\nExample 1: Incrementing a counter using ADD"); UpdateItemResponse addResponse = incrementCounterWithAdd(dynamoDbClient, tableName, key, "ViewCount", 1); System.out.println("Updated counter: " + addResponse.attributes()); // Example 2: Increment a counter using SET System.out.println("\nExample 2: Incrementing a counter using SET"); UpdateItemResponse setResponse = incrementCounterWithSet(dynamoDbClient, tableName, key, "LikeCount", 1); System.out.println("Updated counter: " + setResponse.attributes()); // Example 3: Increment a counter safely System.out.println("\nExample 3: Incrementing a counter safely"); UpdateItemResponse safeResponse = incrementCounterSafely(dynamoDbClient, tableName, key, "ShareCount", 1); System.out.println("Updated counter: " + safeResponse.attributes()); // Example 4: Decrement a counter safely System.out.println("\nExample 4: Decrementing a counter safely"); try { UpdateItemResponse decrementResponse = decrementCounterSafely(dynamoDbClient, tableName, key, "InventoryCount", 1); System.out.println("Updated counter: " + decrementResponse.attributes()); } catch (DynamoDbException e) { if (e.getMessage().contains("ConditionalCheckFailed")) { System.out.println("Cannot decrement counter below zero"); } else { throw e; } } // Example 5: Compare ADD vs SET System.out.println("\nExample 5: Comparing ADD vs SET"); Map<String, Object> comparison = compareAddVsSet(dynamoDbClient, tableName, key); if ((boolean) comparison.get("success")) { System.out.println("ADD duration: " + comparison.get("addDuration") + " ns"); System.out.println("SET duration: " + comparison.get("setDuration") + " ns"); System.out.println("ADD response: " + comparison.get("addResponse")); System.out.println("SET response: " + comparison.get("setResponse")); } else { System.out.println("Comparison failed: " + comparison.get("error")); } // Explain atomic counter operations System.out.println("\nKey points about DynamoDB atomic counter operations:"); System.out.println("1. Both ADD and SET can be used for atomic counters"); System.out.println("2. ADD is more concise for simple increments"); System.out.println("3. SET with an expression is more flexible for complex operations"); System.out.println("4. Use if_not_exists to handle the case where the counter doesn't exist yet"); System.out.println("5. Use condition expressions to prevent counters from going below zero"); System.out.println("6. Atomic operations are guaranteed to be isolated from other writes"); System.out.println("7. ADD can only be used with number and set data types"); } catch (DynamoDbException e) { System.err.println("Error: " + e.getMessage()); e.printStackTrace(); } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조UpdateItem을 참조하세요.

다음 코드 예제에서는 DynamoDB에서 조건부 작업을 사용하는 방법을 보여줍니다.

  • 조건부 쓰기를 구현하여 데이터 덮어쓰기를 방지합니다.

  • 조건식을 사용하여 비즈니스 규칙을 적용합니다.

  • 조건부 검사 실패를 정상적으로 처리합니다.

SDK for Java 2.x

를 사용하여 조건부 작업을 시연합니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.ConditionalCheckFailedException; import software.amazon.awssdk.services.dynamodb.model.DeleteItemRequest; import software.amazon.awssdk.services.dynamodb.model.DeleteItemResponse; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.GetItemRequest; import software.amazon.awssdk.services.dynamodb.model.GetItemResponse; import software.amazon.awssdk.services.dynamodb.model.ReturnValue; import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest; import software.amazon.awssdk.services.dynamodb.model.UpdateItemResponse; import java.util.HashMap; import java.util.Map; /** * Performs a conditional update on an item. * * <p>This method demonstrates how to use a condition expression to update an item * only if a specific condition is met. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param conditionAttribute The attribute to check in the condition * @param conditionValue The value to compare against * @param updateAttribute The attribute to update * @param updateValue The new value to set * @return Map containing the operation result and status */ public static Map<String, Object> conditionalUpdate( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String conditionAttribute, AttributeValue conditionValue, String updateAttribute, AttributeValue updateValue) { Map<String, Object> result = new HashMap<>(); try { // Define the update parameters UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("SET #updateAttr = :updateVal") .conditionExpression("#condAttr = :condVal") .expressionAttributeNames(Map.of( "#condAttr", conditionAttribute, "#updateAttr", updateAttribute)) .expressionAttributeValues(Map.of( ":condVal", conditionValue, ":updateVal", updateValue)) .returnValues(ReturnValue.UPDATED_NEW) .build(); // Perform the update operation UpdateItemResponse response = dynamoDbClient.updateItem(request); // Record success result result.put("success", true); result.put("message", "Condition was met and update was performed"); result.put("attributes", response.attributes()); } catch (ConditionalCheckFailedException e) { // Record failure due to condition not being met result.put("success", false); result.put("message", "Condition was not met, update was not performed"); result.put("error", "ConditionalCheckFailedException"); } catch (DynamoDbException e) { // Record failure due to other errors result.put("success", false); result.put("message", "Error occurred: " + e.getMessage()); result.put("error", e.getClass().getSimpleName()); } return result; } /** * Performs a conditional delete on an item. * * <p>This method demonstrates how to use a condition expression to delete an item * only if a specific condition is met. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to delete * @param conditionAttribute The attribute to check in the condition * @param conditionValue The value to compare against * @return Map containing the operation result and status */ public static Map<String, Object> conditionalDelete( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String conditionAttribute, AttributeValue conditionValue) { Map<String, Object> result = new HashMap<>(); try { // Define the delete parameters DeleteItemRequest request = DeleteItemRequest.builder() .tableName(tableName) .key(key) .conditionExpression("#condAttr = :condVal") .expressionAttributeNames(Map.of("#condAttr", conditionAttribute)) .expressionAttributeValues(Map.of(":condVal", conditionValue)) .returnValues(ReturnValue.ALL_OLD) .build(); // Perform the delete operation DeleteItemResponse response = dynamoDbClient.deleteItem(request); // Record success result result.put("success", true); result.put("message", "Condition was met and delete was performed"); result.put("attributes", response.attributes()); } catch (ConditionalCheckFailedException e) { // Record failure due to condition not being met result.put("success", false); result.put("message", "Condition was not met, delete was not performed"); result.put("error", "ConditionalCheckFailedException"); } catch (DynamoDbException e) { // Record failure due to other errors result.put("success", false); result.put("message", "Error occurred: " + e.getMessage()); result.put("error", e.getClass().getSimpleName()); } return result; } /** * Demonstrates optimistic locking using a version attribute. * * <p>This method shows how to implement optimistic locking by using a version * attribute that is incremented with each update. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param versionAttribute The name of the version attribute * @return Map containing the operation result */ public static Map<String, Object> optimisticLockingExample( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String versionAttribute) { Map<String, Object> result = new HashMap<>(); try { // Get the current version of the item GetItemRequest getRequest = GetItemRequest.builder() .tableName(tableName) .key(key) .projectionExpression(versionAttribute) .build(); GetItemResponse getResponse = dynamoDbClient.getItem(getRequest); // Check if the item exists if (getResponse.item() == null || !getResponse.item().containsKey(versionAttribute)) { // Item doesn't exist or doesn't have a version attribute // Initialize with version 1 UpdateItemRequest initRequest = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("SET #verAttr = :newVer, #dataAttr = :data") .expressionAttributeNames(Map.of("#verAttr", versionAttribute, "#dataAttr", "Data")) .expressionAttributeValues(Map.of( ":newVer", AttributeValue.builder().n("1").build(), ":data", AttributeValue.builder().s("Initial data").build())) .returnValues(ReturnValue.UPDATED_NEW) .build(); UpdateItemResponse initResponse = dynamoDbClient.updateItem(initRequest); result.put("operation", "initialize"); result.put("success", true); result.put("attributes", initResponse.attributes()); return result; } // Get the current version number int currentVersion = Integer.parseInt(getResponse.item().get(versionAttribute).n()); int newVersion = currentVersion + 1; // Update the item with a condition on the version UpdateItemRequest updateRequest = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("SET #verAttr = :newVer, #dataAttr = :newData") .conditionExpression("#verAttr = :curVer") .expressionAttributeNames(Map.of("#verAttr", versionAttribute, "#dataAttr", "Data")) .expressionAttributeValues(Map.of( ":curVer", AttributeValue.builder() .n(String.valueOf(currentVersion)) .build(), ":newVer", AttributeValue.builder().n(String.valueOf(newVersion)).build(), ":newData", AttributeValue.builder() .s("Updated data at version " + newVersion) .build())) .returnValues(ReturnValue.UPDATED_NEW) .build(); UpdateItemResponse updateResponse = dynamoDbClient.updateItem(updateRequest); // Record success result result.put("operation", "update"); result.put("success", true); result.put("oldVersion", currentVersion); result.put("newVersion", newVersion); result.put("attributes", updateResponse.attributes()); } catch (ConditionalCheckFailedException e) { // Record failure due to version mismatch result.put("operation", "update"); result.put("success", false); result.put("message", "Version mismatch, another process may have updated the item"); result.put("error", "ConditionalCheckFailedException"); } catch (DynamoDbException e) { // Record failure due to other errors result.put("operation", "update"); result.put("success", false); result.put("message", "Error occurred: " + e.getMessage()); result.put("error", e.getClass().getSimpleName()); } return result; } /** * Performs a conditional update with multiple conditions. * * <p>This method demonstrates how to use multiple conditions in a condition expression. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param conditions Map of attribute names to values for conditions * @param updateAttribute The attribute to update * @param updateValue The new value to set * @return Map containing the operation result and status */ public static Map<String, Object> conditionalUpdateWithMultipleConditions( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, Map<String, AttributeValue> conditions, String updateAttribute, AttributeValue updateValue) { Map<String, Object> result = new HashMap<>(); try { // Build the condition expression and attribute names/values StringBuilder conditionExpression = new StringBuilder(); Map<String, String> expressionAttributeNames = new HashMap<>(); Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); // Add update attribute expressionAttributeNames.put("#updateAttr", updateAttribute); expressionAttributeValues.put(":updateVal", updateValue); // Add conditions int i = 0; for (Map.Entry<String, AttributeValue> condition : conditions.entrySet()) { String attrName = condition.getKey(); AttributeValue attrValue = condition.getValue(); String nameKey = "#cond" + i; String valueKey = ":val" + i; expressionAttributeNames.put(nameKey, attrName); expressionAttributeValues.put(valueKey, attrValue); // Add AND between conditions (except for the first one) if (i > 0) { conditionExpression.append(" AND "); } conditionExpression.append(nameKey).append(" = ").append(valueKey); i++; } // Define the update parameters UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("SET #updateAttr = :updateVal") .conditionExpression(conditionExpression.toString()) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .returnValues(ReturnValue.UPDATED_NEW) .build(); // Perform the update operation UpdateItemResponse response = dynamoDbClient.updateItem(request); // Record success result result.put("success", true); result.put("message", "All conditions were met and update was performed"); result.put("attributes", response.attributes()); } catch (ConditionalCheckFailedException e) { // Record failure due to condition not being met result.put("success", false); result.put("message", "One or more conditions were not met, update was not performed"); result.put("error", "ConditionalCheckFailedException"); } catch (DynamoDbException e) { // Record failure due to other errors result.put("success", false); result.put("message", "Error occurred: " + e.getMessage()); result.put("error", e.getClass().getSimpleName()); } return result; }

에서 조건부 작업을 사용하는 예입니다 AWS SDK for Java 2.x.

public static void exampleUsage(DynamoDbClient dynamoDbClient, String tableName) { // Example key Map<String, AttributeValue> key = new HashMap<>(); key.put("ProductId", AttributeValue.builder().s("P12345").build()); System.out.println("Demonstrating conditional operations in DynamoDB"); try { // Example 1: Conditional update System.out.println("\nExample 1: Conditional update"); Map<String, Object> updateResult = conditionalUpdate( dynamoDbClient, tableName, key, "InStock", AttributeValue.builder().bool(true).build(), "Status", AttributeValue.builder().s("Available").build()); System.out.println("Update result: " + updateResult.get("message")); if ((boolean) updateResult.get("success")) { System.out.println("Updated attributes: " + updateResult.get("attributes")); } // Example 2: Conditional delete System.out.println("\nExample 2: Conditional delete"); Map<String, Object> deleteResult = conditionalDelete( dynamoDbClient, tableName, key, "Status", AttributeValue.builder().s("Discontinued").build()); System.out.println("Delete result: " + deleteResult.get("message")); if ((boolean) deleteResult.get("success")) { System.out.println("Deleted item: " + deleteResult.get("attributes")); } // Example 3: Optimistic locking System.out.println("\nExample 3: Optimistic locking"); Map<String, Object> lockingResult = optimisticLockingExample(dynamoDbClient, tableName, key, "Version"); System.out.println("Optimistic locking result:"); System.out.println(" Operation: " + lockingResult.get("operation")); System.out.println(" Success: " + lockingResult.get("success")); if (lockingResult.get("operation").equals("update") && (boolean) lockingResult.get("success")) { System.out.println(" Old version: " + lockingResult.get("oldVersion")); System.out.println(" New version: " + lockingResult.get("newVersion")); } System.out.println(" Attributes: " + lockingResult.get("attributes")); // Example 4: Multiple conditions System.out.println("\nExample 4: Multiple conditions"); Map<String, AttributeValue> conditions = new HashMap<>(); conditions.put("Price", AttributeValue.builder().n("199.99").build()); conditions.put("Category", AttributeValue.builder().s("Electronics").build()); Map<String, Object> multiConditionResult = conditionalUpdateWithMultipleConditions( dynamoDbClient, tableName, key, conditions, "OnSale", AttributeValue.builder().bool(true).build()); System.out.println("Multiple conditions result: " + multiConditionResult.get("message")); if ((boolean) multiConditionResult.get("success")) { System.out.println("Updated attributes: " + multiConditionResult.get("attributes")); } // Explain conditional operations System.out.println("\nKey points about DynamoDB conditional operations:"); System.out.println("1. Conditional operations only succeed if the condition is met"); System.out.println("2. ConditionalCheckFailedException is thrown when the condition fails"); System.out.println("3. No changes are made to the item if the condition fails"); System.out.println("4. Conditions can be used with update, delete, and put operations"); System.out.println("5. Multiple conditions can be combined with AND and OR"); System.out.println("6. Optimistic locking can be implemented using a version attribute"); System.out.println( "7. Conditional operations consume the same amount of write capacity whether they succeed or fail"); } catch (DynamoDbException e) { System.err.println("Error: " + e.getMessage()); e.printStackTrace(); } }

다음 코드 예제에서는 DynamoDB에서 표현식 속성 이름을 사용하는 방법을 보여줍니다.

  • DynamoDB 표현식에서 예약된 단어로 작업합니다.

  • 표현식 속성 이름 자리 표시자를 사용합니다.

  • 속성 이름의 특수 문자를 처리합니다.

SDK for Java 2.x

를 사용하여 표현식 속성 이름을 보여줍니다 AWS SDK for Java 2.x.

import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ScanRequest; import software.amazon.awssdk.services.dynamodb.model.ScanResponse; import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest; import software.amazon.awssdk.services.dynamodb.model.UpdateItemResponse; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Updates an attribute that is a reserved word in DynamoDB. * * <p>This method demonstrates how to use expression attribute names to update * attributes that are reserved words in DynamoDB. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param reservedWordAttribute The reserved word attribute to update * @param value The value to set * @return The response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static UpdateItemResponse updateReservedWordAttribute( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String reservedWordAttribute, AttributeValue value) { // Define the update parameters using expression attribute names UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("SET #attr = :value") .expressionAttributeNames(Map.of("#attr", reservedWordAttribute)) .expressionAttributeValues(Map.of(":value", value)) .returnValues("UPDATED_NEW") .build(); // Perform the update operation return dynamoDbClient.updateItem(request); } /** * Updates an attribute that contains special characters. * * <p>This method demonstrates how to use expression attribute names to update * attributes that contain special characters. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param specialCharAttribute The attribute with special characters to update * @param value The value to set * @return The response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static UpdateItemResponse updateSpecialCharacterAttribute( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, String specialCharAttribute, AttributeValue value) { // Define the update parameters using expression attribute names UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("SET #attr = :value") .expressionAttributeNames(Map.of("#attr", specialCharAttribute)) .expressionAttributeValues(Map.of(":value", value)) .returnValues("UPDATED_NEW") .build(); // Perform the update operation return dynamoDbClient.updateItem(request); } /** * Queries items using an attribute that is a reserved word. * * <p>This method demonstrates how to use expression attribute names in a query * when the attribute is a reserved word. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param partitionKeyName The name of the partition key attribute * @param partitionKeyValue The value of the partition key * @param reservedWordAttribute The reserved word attribute to filter on * @param value The value to compare against * @return The response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static QueryResponse queryWithReservedWordAttribute( DynamoDbClient dynamoDbClient, String tableName, String partitionKeyName, AttributeValue partitionKeyValue, String reservedWordAttribute, AttributeValue value) { // Define the query parameters using expression attribute names Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put("#pkName", partitionKeyName); expressionAttributeNames.put("#attr", reservedWordAttribute); Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put(":pkValue", partitionKeyValue); expressionAttributeValues.put(":value", value); QueryRequest request = QueryRequest.builder() .tableName(tableName) .keyConditionExpression("#pkName = :pkValue") .filterExpression("#attr = :value") .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .build(); // Perform the query operation return dynamoDbClient.query(request); } /** * Updates a nested attribute with a path that contains reserved words. * * <p>This method demonstrates how to use expression attribute names to update * nested attributes where the path contains reserved words. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param key The key of the item to update * @param attributePath The path to the nested attribute as an array * @param value The value to set * @return The response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static UpdateItemResponse updateNestedReservedWordAttribute( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> key, List<String> attributePath, AttributeValue value) { // Create expression attribute names for each part of the path Map<String, String> expressionAttributeNames = new HashMap<>(); for (int i = 0; i < attributePath.size(); i++) { expressionAttributeNames.put("#attr" + i, attributePath.get(i)); } // Build the attribute path using the expression attribute names StringBuilder attributePathExpression = new StringBuilder(); for (int i = 0; i < attributePath.size(); i++) { if (i > 0) { attributePathExpression.append("."); } attributePathExpression.append("#attr").append(i); } // Define the update parameters UpdateItemRequest request = UpdateItemRequest.builder() .tableName(tableName) .key(key) .updateExpression("SET " + attributePathExpression.toString() + " = :value") .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(Map.of(":value", value)) .returnValues("UPDATED_NEW") .build(); // Perform the update operation return dynamoDbClient.updateItem(request); } /** * Scans a table with multiple attribute name placeholders. * * <p>This method demonstrates how to use multiple expression attribute names * in a complex filter expression. * * @param dynamoDbClient The DynamoDB client * @param tableName The name of the DynamoDB table * @param filters Object mapping attribute names to filter values * @return The response from DynamoDB * @throws DynamoDbException if an error occurs during the operation */ public static ScanResponse scanWithMultipleAttributeNames( DynamoDbClient dynamoDbClient, String tableName, Map<String, AttributeValue> filters) { // Create expression attribute names and values Map<String, String> expressionAttributeNames = new HashMap<>(); Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); StringBuilder filterExpression = new StringBuilder(); // Build the filter expression int index = 0; for (Map.Entry<String, AttributeValue> entry : filters.entrySet()) { String attrName = entry.getKey(); AttributeValue attrValue = entry.getValue(); String nameKey = "#attr" + index; String valueKey = ":val" + index; expressionAttributeNames.put(nameKey, attrName); expressionAttributeValues.put(valueKey, attrValue); // Add AND between conditions (except for the first one) if (index > 0) { filterExpression.append(" AND "); } filterExpression.append(nameKey).append(" = ").append(valueKey); index++; } // Define the scan parameters ScanRequest request = ScanRequest.builder() .tableName(tableName) .filterExpression(filterExpression.toString()) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .build(); // Perform the scan operation return dynamoDbClient.scan(request); }

에서 표현식 속성 이름의 사용 예제입니다 AWS SDK for Java 2.x.

public static void exampleUsage(DynamoDbClient dynamoDbClient, String tableName) { // Example key Map<String, AttributeValue> key = new HashMap<>(); key.put("ProductId", AttributeValue.builder().s("P12345").build()); System.out.println("Demonstrating expression attribute names in DynamoDB"); try { // Example 1: Update an attribute that is a reserved word System.out.println("\nExample 1: Updating an attribute that is a reserved word"); UpdateItemResponse response1 = updateReservedWordAttribute( dynamoDbClient, tableName, key, "Size", // "SIZE" is a reserved word in DynamoDB AttributeValue.builder().s("Large").build()); System.out.println("Updated attribute: " + response1.attributes()); // Example 2: Update an attribute with special characters System.out.println("\nExample 2: Updating an attribute with special characters"); UpdateItemResponse response2 = updateSpecialCharacterAttribute( dynamoDbClient, tableName, key, "Product-Type", // Contains a hyphen, which is a special character AttributeValue.builder().s("Electronics").build()); System.out.println("Updated attribute: " + response2.attributes()); // Example 3: Query with a reserved word attribute System.out.println("\nExample 3: Querying with a reserved word attribute"); QueryResponse response3 = queryWithReservedWordAttribute( dynamoDbClient, tableName, "Category", AttributeValue.builder().s("Electronics").build(), "Count", // "COUNT" is a reserved word in DynamoDB AttributeValue.builder().n("10").build()); System.out.println("Found " + response3.count() + " items"); // Example 4: Update a nested attribute with reserved words in the path System.out.println("\nExample 4: Updating a nested attribute with reserved words in the path"); UpdateItemResponse response4 = updateNestedReservedWordAttribute( dynamoDbClient, tableName, key, Arrays.asList("Dimensions", "Size", "Height"), // "SIZE" is a reserved word AttributeValue.builder().n("30").build()); System.out.println("Updated nested attribute: " + response4.attributes()); // Example 5: Scan with multiple attribute name placeholders System.out.println("\nExample 5: Scanning with multiple attribute name placeholders"); Map<String, AttributeValue> filters = new HashMap<>(); filters.put("Size", AttributeValue.builder().s("Large").build()); filters.put("Count", AttributeValue.builder().n("10").build()); filters.put( "Product-Type", AttributeValue.builder().s("Electronics").build()); ScanResponse response5 = scanWithMultipleAttributeNames(dynamoDbClient, tableName, filters); System.out.println("Found " + response5.count() + " items"); // Show some common reserved words System.out.println("\nSome common DynamoDB reserved words:"); List<String> commonReservedWords = getDynamoDBReservedWords(); System.out.println(String.join(", ", commonReservedWords)); // Explain expression attribute names System.out.println("\nKey points about expression attribute names:"); System.out.println("1. Use expression attribute names (#name) for reserved words"); System.out.println("2. Use expression attribute names for attributes with special characters"); System.out.println( "3. Special characters include: spaces, hyphens, dots, and other non-alphanumeric characters"); System.out.println("4. Expression attribute names are required for nested attributes with reserved words"); System.out.println("5. You can use multiple expression attribute names in a single expression"); System.out.println("6. Expression attribute names are case-sensitive"); System.out.println("7. Expression attribute names are only used in expressions, not in the actual data"); } catch (DynamoDbException e) { System.err.println("Error: " + e.getMessage()); e.printStackTrace(); } }
  • API 세부 정보는 AWS SDK for Java 2.x API 참조의 다음 주제를 참조하세요.

다음 코드 예제에서는 Amazon EventBridge 예약 이벤트에 의해 호출된 AWS Lambda 함수를 생성하는 방법을 보여줍니다.

SDK for Java 2.x

AWS Lambda 함수를 호출하는 Amazon EventBridge 예약 이벤트를 생성하는 방법을 보여줍니다. Lambda 함수가 간접 호출될 때 cron 표현식을 사용하여 일정을 예약하도록 EventBridge를 구성합니다. 이 예제에서는 Lambda Java 런타임 API를 사용하여 Lambda 함수를 생성합니다. 이 예제에서는 다양한 AWS 서비스를 호출하여 특정 사용 사례를 수행합니다. 이 예제에서는 1주년 기념일에 직원에게 축하하는 모바일 문자 메시지를 전송하는 앱을 생성하는 방법을 보여줍니다.

전체 소스 코드와 설정 및 실행 방법에 대한 지침은 GitHub에서 전체 예제를 참조하세요.

이 예시에서 사용되는 서비스
  • CloudWatch Logs

  • DynamoDB

  • EventBridge

  • Lambda

  • Amazon SNS

서버리스 예제

다음 코드 예제에서는 DynamoDB 스트림에서 레코드를 수신하여 트리거된 이벤트를 수신하는 Lambda 함수를 구현하는 방법을 보여줍니다. 이 함수는 DynamoDB 페이로드를 검색하고 레코드 콘텐츠를 로깅합니다.

SDK for Java 2.x
참고

GitHub에 더 많은 내용이 있습니다. 서버리스 예제 리포지토리에서 전체 예제를 찾아보고 설정 및 실행 방법을 알아봅니다.

Java를 사용하여 Lambda로 DynamoDB 이벤트 소비

import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; import com.amazonaws.services.lambda.runtime.events.DynamodbEvent; import com.amazonaws.services.lambda.runtime.events.DynamodbEvent.DynamodbStreamRecord; import com.google.gson.Gson; import com.google.gson.GsonBuilder; public class example implements RequestHandler<DynamodbEvent, Void> { private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); @Override public Void handleRequest(DynamodbEvent event, Context context) { System.out.println(GSON.toJson(event)); event.getRecords().forEach(this::logDynamoDBRecord); return null; } private void logDynamoDBRecord(DynamodbStreamRecord record) { System.out.println(record.getEventID()); System.out.println(record.getEventName()); System.out.println("DynamoDB Record: " + GSON.toJson(record.getDynamodb())); } }

다음 코드 예제에서는 DynamoDB 스트림에서 이벤트를 수신하는 Lambda 함수에 대해 부분 배치 응답을 구현하는 방법을 보여줍니다. 이 함수는 응답으로 배치 항목 실패를 보고하고 나중에 해당 메시지를 다시 시도하도록 Lambda에 신호를 보냅니다.

SDK for Java 2.x
참고

GitHub에 더 많은 내용이 있습니다. 서버리스 예제 리포지토리에서 전체 예제를 찾아보고 설정 및 실행 방법을 알아봅니다.

Java를 사용하여 Lambda로 DynamoDB 배치 항목 실패 보고.

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; import com.amazonaws.services.lambda.runtime.events.DynamodbEvent; import com.amazonaws.services.lambda.runtime.events.StreamsEventResponse; import com.amazonaws.services.lambda.runtime.events.models.dynamodb.StreamRecord; import java.util.ArrayList; import java.util.List; public class ProcessDynamodbRecords implements RequestHandler<DynamodbEvent, StreamsEventResponse> { @Override public StreamsEventResponse handleRequest(DynamodbEvent input, Context context) { List<StreamsEventResponse.BatchItemFailure> batchItemFailures = new ArrayList<>(); String curRecordSequenceNumber = ""; for (DynamodbEvent.DynamodbStreamRecord dynamodbStreamRecord : input.getRecords()) { try { //Process your record StreamRecord dynamodbRecord = dynamodbStreamRecord.getDynamodb(); curRecordSequenceNumber = dynamodbRecord.getSequenceNumber(); } catch (Exception e) { /* Since we are working with streams, we can return the failed item immediately. Lambda will immediately begin to retry processing from this failed item onwards. */ batchItemFailures.add(new StreamsEventResponse.BatchItemFailure(curRecordSequenceNumber)); return new StreamsEventResponse(batchItemFailures); } } return new StreamsEventResponse(); } }

AWS 커뮤니티 기여

다음 코드 예제에서는 Lambda 및 DynamoDB와 함께 API Gateway를 사용하여 서버리스 애플리케이션을 빌드하고 테스트하는 방법을 보여줍니다.

SDK for Java 2.x

Java SDK를 사용하여 Lambda 및 DynamoDB가 포함된 API 게이트웨이로 구성된 서버리스 애플리케이션을 빌드하고 테스트하는 방법을 보여줍니다.

전체 소스 코드와 설정 및 실행 방법에 대한 지침은 GitHub에서 전체 예제를 참조하세요.

이 예제에서 사용되는 서비스
  • API Gateway

  • DynamoDB

  • Lambda