Java'da (AWS SDK v2) DynamoDB PutItem
PutItem, bir öğenin tamamını yazar ve aynı birincil anahtara sahip mevcut her öğenin yerini alır (öğe tabanlı eylemler bunun UpdateItem'dan nasıl ayrıldığını ele alıyor). AWS SDK for Java 2.x'te her öznitelik bir PutItemRequest'e tipli bir AttributeValue olarak girer ve oluşturucu, hiçbir şekilde geçerli olamayacak bir tane kurmanıza izin verir.
Kod
import java.util.HashMap;
import java.util.Map;
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.PutItemRequest;
public class PutItemExample {
public static void main(String[] args) {
try (DynamoDbClient ddb = DynamoDbClient.builder()
.region(Region.US_EAST_1)
.build()) {
Map<String, AttributeValue> item = new HashMap<>();
item.put("Artist", AttributeValue.builder().s("Arturo Sandoval").build());
item.put("SongTitle", AttributeValue.builder().s("Cubano Chant").build());
item.put("AlbumTitle", AttributeValue.builder().s("Danzon").build());
item.put("Year", AttributeValue.builder().n("1994").build());
item.put("Awards", AttributeValue.builder().n("0").build());
Map<String, String> names = new HashMap<>();
names.put("#cond0", "Artist");
names.put("#cond1", "SongTitle");
PutItemRequest request = PutItemRequest.builder()
.tableName("Music")
.item(item)
.conditionExpression("attribute_not_exists(#cond0) AND attribute_not_exists(#cond1)")
.expressionAttributeNames(names)
.build();
try {
ddb.putItem(request);
System.out.println("Song written");
} catch (ConditionalCheckFailedException e) {
System.out.println("A song with that key already exists — not overwritten");
}
} catch (DynamoDbException e) {
System.err.println(e.getMessage());
}
}
}Açıklama
AttributeValue.builder().build() derlenir. Aynı zamanda gönderilemez. Oluşturucunun zorunlu alanı yoktur, dolayısıyla .s(...)'i unuttuğunuz bir öznitelik tür denetiminden kusursuzca geçer ve hizmette başarısız olur:
DynamoDbException | ValidationException | Supplied AttributeValue is empty, must contain exactly one of the supported datatypesBu, başka SDK'ların olanaksız kıldığı bir hatanın Java'ya özgü biçimidir: Go'nun types.AttributeValueMember* tipleri ayrı türlerdir, dolayısıyla ayarlanmadan bırakılacak bir şey yoktur. Daha geniş çözüm için bkz. "Supplied AttributeValue is empty".
.s(...)'e verilen bir Java null'ı DynamoDB NULL'ına dönüşmez. Asıl canınızı yakan sürüm budur, çünkü bir değer gibi görünür:
AttributeValue.builder().s(customer.getNotes()).build() // getNotes() returned nullKurulum sırasında hiçbir NullPointerException fırlatılmaz. Oluşturucu yalnızca hiçbir şey kaydetmez ve istek, hiç şüphelenmediğiniz bir özniteliği işaret eden, birebir aynı Supplied AttributeValue is empty mesajıyla başarısız olur. Gerçek bir null istiyorsanız o AttributeValue.builder().nul(true).build()'dır; çoğu zaman istediğiniz şey ise girdiyi hiç yazmamaktır. Bunun, nil bir işaretçinin NULL'a marshal edilip sessizce bir öznitelik yarattığı Go SDK'sının tam tersi olduğuna dikkat edin; ikisi de aynı gün aynı motora karşı çalıştırıldı.
getMessage() hizmetin mesajı değildir. SDK kendi bağlamını ekler, dolayısıyla dize şudur:
The conditional request failed (Service: DynamoDb, Status Code: 400, Request ID: 77a08ef1-a3a9-4f97-b309-4cb0741edd1a) (SDK Attempt Count: 1)e.awsErrorDetails().errorCode() üzerinden eşleştirin ve çıplak metin için e.awsErrorDetails().errorMessage() okuyun. getMessage()'ı bir sabitle karşılaştıran her şey, deneme sayısını değiştiren bir yeniden denemeyle bozulur.
ConditionalCheckFailedException'ı DynamoDbException'dan önce yakalayın ve taşıdığı şeyi okuyun. O, DynamoDbException'ı genişletir; dolayısıyla catch bloklarını ters sırada dizmek özel işleyiciyi erişilemez kılar. Yakalanan nesnede: statusCode() 400, retryable() ise false döndürdü — bir iş mantığı reddi için dürüst yanıt budur. İsteğe .returnValuesOnConditionCheckFailure("ALL_OLD") ekleyin; e.item(), yazmayı engelleyen öğeyle dolu olarak geri gelir (yukarıdaki çalıştırmada beş öznitelik, Year ise AttributeValue(N=1994) olarak), dolayısıyla kimin kazandığını öğrenmek için ardından bir getItem'a ihtiyacınız kalmaz.
Sayılar .n(...) üzerinden dize olarak girer. DynamoDB'nin N türü kabloda ondalık metindir; 1994'ün bir double'a dönüşmesini engelleyen de budur. Deyim .n(String.valueOf(year))'dır; uzanacağınız bir .n(int) aşırı yüklemesi yoktur.
İstemci Closeable'dır ve uzun ömürlüdür. Yukarıdaki try-with-resources tek seferlik bir program için doğru, bir hizmet için yanlıştır: DynamoDbClient bir HTTP bağlantı havuzuna sahiptir ve iş parçacığı güvenlidir, dolayısıyla uygulama başına bir tane kurun ve yaşamasına izin verin. İstek başına bir tane kurmak bu API'deki en yaygın Java performans hatasıdır.
AttributeValue eşlemeleri yerine bean'leri mi tercih edersiniz? DynamoDB Enhanced Client (software.amazon.awssdk.enhanced.dynamodb), açıklamalı bir sınıfı doğrudan bir öğeye eşler ve boş oluşturucu tuzağını tamamen ortadan kaldırır. Bedeli başlangıçta yansımalı bir TableSchema.fromBean taramasıdır; bu sizin için önemliyse StaticTableSchema bundan kaçınır.
Görsel olarak yapın
Yukarıdaki her başarısızlık elle kurulmuş tipli değerlerle başlıyor. Ücretsiz DynamoDB JSON dönüştürücüsü sıradan JSON alır ve tipli biçimi döndürür; böylece tek bir AttributeValue.builder() yazmadan önce öğenin kabloda tam olarak nasıl görünmesi gerektiğini görebilirsiniz.
Kendi tablolarınıza karşı öğe yazmak ve düzenlemek — öznitelik başına bir form, tür seçiciler, sonucu Java olarak geri kopyalama — için DynoTable'ı indirin.
İlgili örnekler
- Go'da DynamoDB PutItem — AWS SDK for Go v2 ile aynı koşullu yazma; orada nil bir işaretçi tam tersi şekilde başarısız olur.
- Java'da DynamoDB UpdateItem — öğeyi değiştirmek yerine belirli öznitelikleri değiştirin.
- DynamoDB koşul ifadeleri —
attribute_not_exists, iyimser kilitleme ve dahası. - DynamoDB ConditionalCheckFailedException — öğe zaten varken yalnızca-oluştur koşulunun fırlattığı şey.
- DynamoDB ValidationException — bozuk bir öğe ya da ifade için genel karşılık.
Kaynaklar
- PutItem — Amazon DynamoDB API Reference
- Use PutItem with an AWS SDK or CLI — Amazon DynamoDB Developer Guide
- DynamoDbClient — AWS SDK for Java 2.x API Reference
- AttributeValue — AWS SDK for Java 2.x API Reference
- PutItemRequest — AWS SDK for Java 2.x API Reference
- Condition expressions — Amazon DynamoDB Developer Guide
2026-07-28 tarihinde AWS SDK for Java 2.49.4 ile OpenJDK 26.0.1 üzerinde, 9000 numaralı bağlantı noktasındaki DynamoDB Local'a (amazon/dynamodb-local) karşı yeniden üretildi. Yukarıdaki istisna metni, durum kodu ve öğe içerikleri yakalanan çıktıdır, birebir kopyalanmıştır.