

# 항목 작업: Java
<a name="JavaDocumentAPIItemCRUD"></a>

AWS SDK for Java Document API를 사용하여 테이블의 Amazon DynamoDB 항목에 대한 일반적인 생성, 읽기, 업데이트 및 삭제(CRUD) 작업을 수행할 수 있습니다.

**참고**  
또한 SDK for Java에서는 객체 지속성 모델을 제공하므로 DynamoDB 테이블로 클라이언트 측 클래스를 매핑할 수 있습니다. 이러한 접근 방식을 활용하면 작성해야 할 코드가 줄어듭니다. 자세한 내용은 [Java 1.x: DynamoDBMapper](DynamoDBMapper.md) 섹션을 참조하세요.

이 단원에는 몇 가지 Java 문서 API 항목 작업을 수행하기 위한 Java 예제와 몇 가지 완전한 작업 예제가 나와 있습니다.

**Topics**
+ [항목 추가](#PutDocumentAPIJava)
+ [항목 가져오기](#JavaDocumentAPIGetItem)
+ [일괄 쓰기 - 여러 항목 추가 및 삭제](#BatchWriteDocumentAPIJava)
+ [일괄 가져오기: 여러 항목 가져오기](#JavaDocumentAPIBatchGetItem)
+ [항목 업데이트](#JavaDocumentAPIItemUpdate)
+ [항목 삭제](#DeleteMidLevelJava)
+ [예: AWS SDK for Java 문서 API를 사용하는 CRUD 작업](JavaDocumentAPICRUDExample.md)
+ [예: AWS SDK for Java Document API를 사용하는 일괄 작업](batch-operation-document-api-java.md)
+ [예: AWS SDK for Java 문서 API를 사용하여 이진 형식 속성 처리](JavaDocumentAPIBinaryTypeExample.md)

## 항목 추가
<a name="PutDocumentAPIJava"></a>

`putItem` 메서드는 항목을 테이블에 저장합니다. 항목이 존재하는 경우 전체 항목을 바꿉니다. 전체 항목을 변경하지 않고 특정 속성만 업데이트하는 경우에는 `updateItem` 메서드를 사용하면 됩니다. 자세한 내용은 [항목 업데이트](#JavaDocumentAPIItemUpdate) 섹션을 참조하세요.

------
#### [ Java v2 ]

```
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);
        }
    }
}
```

------
#### [ Java v1 ]

다음 단계를 따릅니다.

1. `DynamoDB` 클래스의 인스턴스를 만듭니다. 

1. `Table` 클래스의 인스턴스를 만들어 사용할 테이블을 표시합니다.

1. `Item` 클래스 인스턴스를 생성하여 새로운 항목을 표시합니다. 새 항목의 기본 키와 그 속성을 지정해야 합니다.

1. 이전 단계에서 생성한 `putItem`을 사용하여 `Table` 객체의 `Item` 메서드를 호출합니다.

다음은 위에서 설명한 작업을 실행하는 Java 코드 예제입니다. 이 코드는 `ProductCatalog` 테이블에 새 항목을 씁니다.

**Example**  

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

Table table = dynamoDB.getTable("ProductCatalog");

// Build a list of related items
List<Number> relatedItems = new ArrayList<Number>();
relatedItems.add(341);
relatedItems.add(472);
relatedItems.add(649);

//Build a map of product pictures
Map<String, String> pictures = new HashMap<String, String>();
pictures.put("FrontView", "http://example.com/products/123_front.jpg");
pictures.put("RearView", "http://example.com/products/123_rear.jpg");
pictures.put("SideView", "http://example.com/products/123_left_side.jpg");

//Build a map of product reviews
Map<String, List<String>> reviews = new HashMap<String, List<String>>();

List<String> fiveStarReviews = new ArrayList<String>();
fiveStarReviews.add("Excellent! Can't recommend it highly enough!  Buy it!");
fiveStarReviews.add("Do yourself a favor and buy this");
reviews.put("FiveStar", fiveStarReviews);

List<String> oneStarReviews = new ArrayList<String>();
oneStarReviews.add("Terrible product!  Do not buy this.");
reviews.put("OneStar", oneStarReviews);

// Build the item
Item item = new Item()
    .withPrimaryKey("Id", 123)
    .withString("Title", "Bicycle 123")
    .withString("Description", "123 description")
    .withString("BicycleType", "Hybrid")
    .withString("Brand", "Brand-Company C")
    .withNumber("Price", 500)
    .withStringSet("Color",  new HashSet<String>(Arrays.asList("Red", "Black")))
    .withString("ProductCategory", "Bicycle")
    .withBoolean("InStock", true)
    .withNull("QuantityOnHand")
    .withList("RelatedItems", relatedItems)
    .withMap("Pictures", pictures)
    .withMap("Reviews", reviews);

// Write the item to the table
PutItemOutcome outcome = table.putItem(item);
```

위의 예에서 항목에는 형식이 스칼라(`String`, `Number`, `Boolean`, `Null`), 집합(`String Set`) 및 문서(`List`, `Map`)인 속성이 있습니다.

------

### 옵션 파라미터 지정
<a name="PutItemJavaDocumentAPIOptions"></a>

필수 파라미터 외에도 `putItem` 메서드에 선택적 파라미터를 지정할 수 있습니다. 예를 들어 다음 Java 코드 예제는 선택적 파라미터를 사용하여 항목을 업로드하기 위한 조건을 지정합니다. 지정하는 조건을 충족하지 못하면 AWS SDK for Java가 `ConditionalCheckFailedException`을 내보냅니다. 이 코드 예제는 `putItem` 메서드에 다음과 같은 선택적 파라미터를 지정합니다.
+ 요청에 대한 조건을 정의하는 `ConditionExpression`. 이 코드는 특정 값과 동일한 ISBN 속성을 가진 경우에만 동일한 기본 키를 가진 기존 항목이 대체되는 조건을 정의합니다.
+ 조건에 사용되는 `ExpressionAttributeValues`에 대한 지도. 이 경우 단 한 번의 대체만 필요합니다. 런타임에 조건 표현식의 자리 표시자 `:val`이 검사할 실제 ISBN 값으로 대체됩니다.

다음 예제에서는 이 선택적 파라미터를 사용하여 새로운 책 항목을 추가합니다.

**Example**  

```
Item item = new Item()
    .withPrimaryKey("Id", 104)
    .withString("Title", "Book 104 Title")
    .withString("ISBN", "444-4444444444")
    .withNumber("Price", 20)
    .withStringSet("Authors",
        new HashSet<String>(Arrays.asList("Author1", "Author2")));

Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":val", "444-4444444444");

PutItemOutcome outcome = table.putItem(
    item,
    "ISBN = :val", // ConditionExpression parameter
    null,          // ExpressionAttributeNames parameter - we're not using it for this example
    expressionAttributeValues);
```

### PutItem 및 JSON 문서
<a name="PutItemJavaDocumentAPI.JSON"></a>

DynamoDB 테이블에 속성으로 JSON 문서를 저장할 수 있습니다. 그러려면 `withJSON`의 `Item` 메서드를 사용합니다. 이 메서드가 JSON 문서를 구문 분석하고 각 요소를 기본 DynamoDB 데이터 형식에 매핑합니다.

특정 제품에 대한 주문을 이행할 수 있는 공급업체를 포함하여 다음 JSON 문서를 저장한다고 가정해 보십시오.

**Example**  

```
{
    "V01": {
        "Name": "Acme Books",
        "Offices": [ "Seattle" ]
    },
    "V02": {
        "Name": "New Publishers, Inc.",
        "Offices": ["London", "New York"
        ]
    },
    "V03": {
        "Name": "Better Buy Books",
        "Offices": [ "Tokyo", "Los Angeles", "Sydney"
        ]
    }
}
```

`withJSON` 메서드를 사용하여 이 항목을 `ProductCatalog` 테이블의 `Map`라는 `VendorInfo` 속성에 저장할 수 있습니다. 다음은 이 작업을 수행하는 방법을 보여 주는 Java 코드 예제입니다.

```
// Convert the document into a String.  Must escape all double-quotes.
String vendorDocument = "{"
    + "    \"V01\": {"
    + "        \"Name\": \"Acme Books\","
    + "        \"Offices\": [ \"Seattle\" ]"
    + "    },"
    + "    \"V02\": {"
    + "        \"Name\": \"New Publishers, Inc.\","
    + "        \"Offices\": [ \"London\", \"New York\"" + "]" + "},"
    + "    \"V03\": {"
    + "        \"Name\": \"Better Buy Books\","
    +          "\"Offices\": [ \"Tokyo\", \"Los Angeles\", \"Sydney\""
    + "            ]"
    + "        }"
    + "    }";

Item item = new Item()
    .withPrimaryKey("Id", 210)
    .withString("Title", "Book 210 Title")
    .withString("ISBN", "210-2102102102")
    .withNumber("Price", 30)
    .withJSON("VendorInfo", vendorDocument);

PutItemOutcome outcome = table.putItem(item);
```

## 항목 가져오기
<a name="JavaDocumentAPIGetItem"></a>

단일 항목을 검색하려면 `getItem` 객체의 `Table` 메서드를 사용합니다. 다음 단계를 따릅니다.

1. `DynamoDB` 클래스의 인스턴스를 만듭니다. 

1. `Table` 클래스의 인스턴스를 만들어 사용할 테이블을 표시합니다.

1. `getItem` 인스턴스의 `Table` 메서드를 호출합니다. 검색하려는 항목의 기본 키를 지정해야 합니다.

다음 Java 코드 예는 앞의 단계를 보여줍니다. 이 코드는 지정된 파티션 기본 키가 있는 항목을 가져옵니다.

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

Table table = dynamoDB.getTable("ProductCatalog");

Item item = table.getItem("Id", 210);
```

### 옵션 파라미터 지정
<a name="GetItemJavaDocumentAPIOptions"></a>

필수 파라미터 외에도 `getItem` 메서드에 대해 선택적 파라미터를 지정할 수 있습니다. 예를 들어 다음 Java 코드 예제는 선택적 메서드를 사용하여 특정 속성 목록만 검색하고 강력하게 일관된 읽기를 지정합니다. 읽기 일관성에 대한 자세한 내용은 [DynamoDB 읽기 일관성](HowItWorks.ReadConsistency.md)를 참조하십시오.

`ProjectionExpression`을 사용하여 전체 항목이 아닌 특정 속성이나 요소만 검색할 수 있습니다. `ProjectionExpression`은 문서 경로를 사용하여 최상위 또는 중첩된 속성을 지정할 수 있습니다. 자세한 내용은 [DynamoDB에서 프로젝션 표현식 사용](Expressions.ProjectionExpressions.md) 섹션을 참조하세요.

`getItem` 메서드의 파라미터는 읽기 일관성을 지정할 수 없도록 합니다. 그러나 하위 수준 `GetItemSpec` 작업에 대한 모든 입력에 전체 액세스 권한을 제공하는 `GetItem`를 생성할 수 있습니다. 아래의 코드 예제에서는 `GetItemSpec`을 생성하고 그 사양을 `getItem` 메서드에 대한 입력으로 사용합니다.

**Example**  

```
GetItemSpec spec = new GetItemSpec()
    .withPrimaryKey("Id", 206)
    .withProjectionExpression("Id, Title, RelatedItems[0], Reviews.FiveStar")
    .withConsistentRead(true);

Item item = table.getItem(spec);

System.out.println(item.toJSONPretty());
```

 사람이 읽을 수 있는 형식으로 `Item`을 인쇄하려면 `toJSONPretty` 메서드를 사용하십시오. 이전 예제의 출력은 다음과 같습니다.

```
{
  "RelatedItems" : [ 341 ],
  "Reviews" : {
    "FiveStar" : [ "Excellent! Can't recommend it highly enough! Buy it!", "Do yourself a favor and buy this" ]
  },
  "Id" : 123,
  "Title" : "20-Bicycle 123"
}
```

### GetItem 및 JSON 문서
<a name="GetItemJavaDocumentAPI.JSON"></a>

[PutItem 및 JSON 문서](#PutItemJavaDocumentAPI.JSON) 단원에서는 JSON 문서를 `Map`라는 `VendorInfo` 속성에 저장했습니다. `getItem` 메서드를 사용하여 JSON 형식으로 전체 문서를 검색할 수 있습니다. 또는 문서 경로 표기법을 사용하여 문서에서 일부 요소만 검색할 수도 있습니다. 다음 Java 코드 예제는 이러한 기법을 보여줍니다.

```
GetItemSpec spec = new GetItemSpec()
    .withPrimaryKey("Id", 210);

System.out.println("All vendor info:");
spec.withProjectionExpression("VendorInfo");
System.out.println(table.getItem(spec).toJSON());

System.out.println("A single vendor:");
spec.withProjectionExpression("VendorInfo.V03");
System.out.println(table.getItem(spec).toJSON());

System.out.println("First office location for this vendor:");
spec.withProjectionExpression("VendorInfo.V03.Offices[0]");
System.out.println(table.getItem(spec).toJSON());
```

이전 예제의 출력은 다음과 같습니다.

```
All vendor info:
{"VendorInfo":{"V03":{"Name":"Better Buy Books","Offices":["Tokyo","Los Angeles","Sydney"]},"V02":{"Name":"New Publishers, Inc.","Offices":["London","New York"]},"V01":{"Name":"Acme Books","Offices":["Seattle"]}}}
A single vendor:
{"VendorInfo":{"V03":{"Name":"Better Buy Books","Offices":["Tokyo","Los Angeles","Sydney"]}}}
First office location for a single vendor:
{"VendorInfo":{"V03":{"Offices":["Tokyo"]}}}
```

**참고**  
`toJSON` 메서드를 사용하여 임의의 항목 또는 해당 속성을 JSON 형식 문자열로 변환할 수 있습니다. 다음 코드 예제에서는 여러 최상위 및 중첩 속성을 검색하여 결과를 JSON으로 인쇄합니다.  

```
GetItemSpec spec = new GetItemSpec()
    .withPrimaryKey("Id", 210)
    .withProjectionExpression("VendorInfo.V01, Title, Price");

Item item = table.getItem(spec);
System.out.println(item.toJSON());
```
출력은 다음과 같습니다.  

```
{"VendorInfo":{"V01":{"Name":"Acme Books","Offices":["Seattle"]}},"Price":30,"Title":"Book 210 Title"}
```

## 일괄 쓰기 - 여러 항목 추가 및 삭제
<a name="BatchWriteDocumentAPIJava"></a>

*배치 쓰기*란 다수의 항목을 배치로 입력 및 삭제하는 것을 말합니다. `batchWriteItem` 메서드를 사용하면 단 한 번의 호출로 하나 이상의 테이블에 다수의 항목을 업로드하거나 삭제할 수 있습니다. 다음은 AWS SDK for Java Document API를 사용하여 여러 항목을 일괄하거나 삭제하는 단계입니다.

1. `DynamoDB` 클래스의 인스턴스를 만듭니다. 

1. 테이블의 모든 일괄 및 삭제 작업을 설명하는 `TableWriteItems` 클래스의 인스턴스를 만듭니다. 단일 일괄 쓰기 작업에서 여러 테이블에 쓰려면 테이블마다 `TableWriteItems` 인스턴스 하나를 생성해야 합니다.

1. 이전 단계에서 생성한 `batchWriteItem` 객체를 제공하여 `TableWriteItems` 메서드를 호출합니다.

1. 응답을 처리합니다. 응답과 함께 반환되는 요청 항목 중 처리하지 않은 항목이 있는지 확인해야 합니다. 프로비저닝된 처리량이 할당량에 이르거나 일시적 오류가 발생하면 이러한 경우가 발생할 수 있습니다. 또한 DynamoDB는 요청 시 지정하는 요청 크기나 작업 수를 제한합니다. 따라서 이러한 제한을 초과할 경우 DynamoDB가 요청을 거부하기도 합니다. 자세한 내용은 [Amazon DynamoDB의 할당량](ServiceQuotas.md) 섹션을 참조하세요.

다음 Java 코드 예는 앞의 단계를 보여줍니다. 예제에서는 두 테이블 `batchWriteItem` 및 `Forum`에서 `Thread` 작업을 수행합니다. 해당 `TableWriteItems` 객체가 다음 작업을 정의합니다.
+ `Forum` 테이블에 항목을 업로드합니다.
+ `Thread` 테이블에서 항목을 업로드하고 삭제합니다.

그런 다음 코드가 `batchWriteItem`을 호출하여 작업을 수행합니다.

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

TableWriteItems forumTableWriteItems = new TableWriteItems("Forum")
    .withItemsToPut(
        new Item()
            .withPrimaryKey("Name", "Amazon RDS")
            .withNumber("Threads", 0));

TableWriteItems threadTableWriteItems = new TableWriteItems("Thread")
    .withItemsToPut(
        new Item()
            .withPrimaryKey("ForumName","Amazon RDS","Subject","Amazon RDS Thread 1")
    .withHashAndRangeKeysToDelete("ForumName","Some partition key value", "Amazon S3", "Some sort key value");

BatchWriteItemOutcome outcome = dynamoDB.batchWriteItem(forumTableWriteItems, threadTableWriteItems);

// Code for checking unprocessed items is omitted in this example
```

사용 가능한 예제는 [예: AWS SDK for Java 문서 API를 사용하는 일괄 쓰기 작업](batch-operation-document-api-java.md#JavaDocumentAPIBatchWrite) 섹션을 참조하세요.

## 일괄 가져오기: 여러 항목 가져오기
<a name="JavaDocumentAPIBatchGetItem"></a>

`batchGetItem` 메서드를 사용하면 하나 이상의 테이블에서 여러 항목을 검색할 수 있습니다. 단일 항목을 검색하려면 `getItem` 메서드를 사용합니다.

다음 단계를 따릅니다.

1. `DynamoDB` 클래스의 인스턴스를 만듭니다. 

1. 테이블에서 검색할 기본 키 값 목록을 설명하는 `TableKeysAndAttributes` 클래스의 인스턴스를 만듭니다. 단일 일괄 가져오기 작업에서 여러 테이블로부터 읽으려면 테이블마다 `TableKeysAndAttributes` 인스턴스 하나를 만들어야 합니다.

1. 이전 단계에서 생성한 `batchGetItem` 객체를 제공하여 `TableKeysAndAttributes` 메서드를 호출합니다.

다음 Java 코드 예는 앞의 단계를 보여줍니다. 이 예제에서는 `Forum` 테이블에서 항목 2개, `Thread` 테이블에서 항목 3개를 검색합니다.

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

    TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes(forumTableName);
    forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name",
    "Amazon S3",
    "Amazon DynamoDB");

TableKeysAndAttributes threadTableKeysAndAttributes = new TableKeysAndAttributes(threadTableName);
threadTableKeysAndAttributes.addHashAndRangePrimaryKeys("ForumName", "Subject",
    "Amazon DynamoDB","DynamoDB Thread 1",
    "Amazon DynamoDB","DynamoDB Thread 2",
    "Amazon S3","S3 Thread 1");

BatchGetItemOutcome outcome = dynamoDB.batchGetItem(
    forumTableKeysAndAttributes, threadTableKeysAndAttributes);

for (String tableName : outcome.getTableItems().keySet()) {
    System.out.println("Items in table " + tableName);
    List<Item> items = outcome.getTableItems().get(tableName);
    for (Item item : items) {
        System.out.println(item);
    }
}
```

### 옵션 파라미터 지정
<a name="BatchGetItemJavaDocumentAPIOptions"></a>

`batchGetItem`을 사용할 때 필수 파라미터 외에도 선택적 파라미터를 지정할 수 있습니다. 예를 들어 `ProjectionExpression`를 정의할 때마다 `TableKeysAndAttributes`을 제공할 수 있습니다. 그러면 테이블에서 검색하려는 속성을 지정할 수 있습니다.

다음 코드 예제에서는 `Forum` 테이블에서 두 개의 항목을 검색합니다. `withProjectionExpression` 파라미터가 `Threads` 속성만 검색하도록 지정합니다.

**Example**  

```
TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes("Forum")
    .withProjectionExpression("Threads");

forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name",
    "Amazon S3",
    "Amazon DynamoDB");

BatchGetItemOutcome outcome = dynamoDB.batchGetItem(forumTableKeysAndAttributes);
```

## 항목 업데이트
<a name="JavaDocumentAPIItemUpdate"></a>

`updateItem` 객체의 `Table` 메서드는 기존의 속성 값을 업데이트하거나, 새 속성을 추가하거나, 기존 항목에서 속성을 삭제할 수 있습니다.

`updateItem` 메서드는 다음과 같이 동작합니다.
+ 항목이 없으면(테이블에 지정된 기본 키를 가진 항목이 없음) `updateItem`이 테이블에 새 항목을 추가합니다.
+ 항목이 있으면 `updateItem` 파라미터가 지정한 대로 `UpdateExpression`이 업데이트를 수행합니다.

**참고**  
`putItem`을 사용하여 항목을 "업데이트"할 수도 있습니다. 예를 들어 `putItem`을 호출하여 테이블에 항목을 추가할 경우 지정된 기본 키를 가진 항목이 이미 있으면 `putItem`이 전체 항목을 바꿉니다. 입력에 지정되지 않은 속성이 기존 항목에 있으면 `putItem`이 항목에서 그 속성을 제거합니다.  
일반적으로 항목 속성을 수정할 때마다 `updateItem`을 사용하는 것이 좋습니다. `updateItem` 메서드는 입력에 지정한 항목 속성만 수정하며, 항목에 있는 다른 속성은 변경되지 않고 남아 있습니다.

다음 단계를 따릅니다.

1. `Table` 클래스의 인스턴스를 만들어 사용할 테이블을 표시합니다.

1. `updateTable` 인스턴스의 `Table` 메서드를 호출합니다. 수정할 속성과 수정 방법을 설명하는 `UpdateExpression`과 함께 검색하려는 항목의 기본 키를 지정해야 합니다.

다음은 위에서 설명한 작업을 실행하는 Java 코드 예제입니다. 이 코드에서는 `ProductCatalog` 테이블의 book 항목을 업데이트합니다. 새로운 작성자를 `Authors` 집합에 추가하고 기존 `ISBN` 속성을 삭제합니다. 또한 가격을 1만큼 내립니다.

`ExpressionAttributeValues` 맵이 `UpdateExpression`에 사용됩니다. 런타임에 자리 표시자 `:val1` 및 `:val2`가 `Authors` 및 `Price`의 실제 값으로 바뀝니다.

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

Table table = dynamoDB.getTable("ProductCatalog");

Map<String, String> expressionAttributeNames = new HashMap<String, String>();
expressionAttributeNames.put("#A", "Authors");
expressionAttributeNames.put("#P", "Price");
expressionAttributeNames.put("#I", "ISBN");

Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":val1",
    new HashSet<String>(Arrays.asList("Author YY","Author ZZ")));
expressionAttributeValues.put(":val2", 1);   //Price

UpdateItemOutcome outcome =  table.updateItem(
    "Id",          // key attribute name
    101,           // key attribute value
    "add #A :val1 set #P = #P - :val2 remove #I", // UpdateExpression
    expressionAttributeNames,
    expressionAttributeValues);
```

### 옵션 파라미터 지정
<a name="UpdateItemJavaDocumentAPIOptions"></a>

필수 파라미터 외에도 업데이트가 발생하기 위해 충족되어야 하는 조건 등 `updateItem` 메서드에 대한 선택적 파라미터도 지정할 수 있습니다. 지정하는 조건을 충족하지 못하면 AWS SDK for Java가 `ConditionalCheckFailedException`을 내보냅니다. 예를 들어 다음 Java 코드 예제는 book 항목 가격을 25로 조건부 업데이트합니다. 기존 가격이 20일 경우에만 가격이 업데이트 되도록 `ConditionExpression`을 지정합니다.

**Example**  

```
Table table = dynamoDB.getTable("ProductCatalog");

Map<String, String> expressionAttributeNames = new HashMap<String, String>();
expressionAttributeNames.put("#P", "Price");

Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":val1", 25);  // update Price to 25...
expressionAttributeValues.put(":val2", 20);  //...but only if existing Price is 20

UpdateItemOutcome outcome = table.updateItem(
    new PrimaryKey("Id",101),
    "set #P = :val1", // UpdateExpression
    "#P = :val2",     // ConditionExpression
    expressionAttributeNames,
    expressionAttributeValues);
```

### 원자성 카운터
<a name="AtomicCounterJavaDocumentAPI"></a>

`updateItem`을 사용하여 원자성 카운터를 구현할 수 있습니다. 이는 다른 쓰기 요청과 충돌하지 않고도 기존 속성의 값을 증감합니다. 원자성 카운터를 증가시키려면 `UpdateExpression`을 `set` 작업과 함께 사용하여 `Number` 형식의 기존 속성에 숫자 값을 추가합니다.

다음 예제는 `Quantity` 속성을 하나씩 늘리며 이를 보여 줍니다. `ExpressionAttributeNames`에서 `UpdateExpression` 파라미터가 사용되는 방식도 보여 줍니다.

```
Table table = dynamoDB.getTable("ProductCatalog");

Map<String,String> expressionAttributeNames = new HashMap<String,String>();
expressionAttributeNames.put("#p", "PageCount");

Map<String,Object> expressionAttributeValues = new HashMap<String,Object>();
expressionAttributeValues.put(":val", 1);

UpdateItemOutcome outcome = table.updateItem(
    "Id", 121,
    "set #p = #p + :val",
    expressionAttributeNames,
    expressionAttributeValues);
```

## 항목 삭제
<a name="DeleteMidLevelJava"></a>

`deleteItem` 메서드는 테이블에서 항목을 삭제합니다. 삭제할 항목의 기본 키를 제공해야 합니다.

다음 단계를 따릅니다.

1. `DynamoDB` 클라이언트의 인스턴스를 만듭니다.

1. 삭제하려는 항목의 키를 제공하여 `deleteItem` 메서드를 호출합니다.

다음은 Java 예제는 이러한 작업을 보여줍니다.

**Example**  

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

Table table = dynamoDB.getTable("ProductCatalog");

DeleteItemOutcome outcome = table.deleteItem("Id", 101);
```

### 옵션 파라미터 지정
<a name="DeleteItemJavaDocumentAPIOptions"></a>

`deleteItem`에 대해 선택적 파라미터를 지정할 수 있습니다. 예를 들어 다음 Java 코드 예제는 책이 더 이상 출판되지 않는 경우에만(`ConditionExpression` 속성이 false임) `ProductCatalog`의 book 항목을 삭제하도록 `InPublication`을 지정합니다.

**Example**  

```
Map<String,Object> expressionAttributeValues = new HashMap<String,Object>();
expressionAttributeValues.put(":val", false);

DeleteItemOutcome outcome = table.deleteItem("Id",103,
    "InPublication = :val",
    null, // ExpressionAttributeNames - not used in this example
    expressionAttributeValues);
```