Java (AWS SDK v2) ile DynamoDB UpdateItem

Güncellemenin kendisi tek bir oluşturucu çağrısıdır. Java geliştiricilerine zaman kaybettiren, etrafındaki her şeydir: asla null döndürmeyen bir yanıt nesnesi, ilginç başarısızlığın muhtemelen yakaladığınızın alt sınıfı olduğu bir istisna hiyerarşisi ve bu işlemi hiç ifade edemeyen üst düzey bir istemci.

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.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.ReturnValue;
import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest;
import software.amazon.awssdk.services.dynamodb.model.UpdateItemResponse;

public class UpdateItemExample {
    public static void main(String[] args) {
        try (DynamoDbClient ddb = DynamoDbClient.builder()
                .region(Region.US_EAST_1)
                .build()) {

            Map<String, AttributeValue> key = new HashMap<>();
            key.put("Artist", AttributeValue.builder().s("Arturo Sandoval").build());
            key.put("SongTitle", AttributeValue.builder().s("Cubano Chant").build());

            Map<String, String> names = new HashMap<>();
            names.put("#upd0", "Genre");
            names.put("#upd1", "Year");
            names.put("#upd2", "Awards");

            Map<String, AttributeValue> values = new HashMap<>();
            values.put(":updValue0", AttributeValue.builder().s("Latin Jazz").build());
            values.put(":updValue1", AttributeValue.builder().n("1994").build());
            values.put(":updValue2", AttributeValue.builder().n("1").build());

            UpdateItemRequest request = UpdateItemRequest.builder()
                    .tableName("Music")
                    .key(key)
                    .updateExpression("SET #upd0 = :updValue0, #upd1 = :updValue1 ADD #upd2 :updValue2")
                    .expressionAttributeNames(names)
                    .expressionAttributeValues(values)
                    .returnValues(ReturnValue.ALL_NEW)
                    .build();

            UpdateItemResponse response = ddb.updateItem(request);
            System.out.println(response.attributes()); // the item after the update
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
        }
    }
}

Açıklama

  • AttributeValue.builder().n("1994") bir String alır, kısa hâli AttributeValue.fromN("1994") de öyle. n(int) aşırı yüklemesi yoktur, çünkü DynamoDB sayıları 38 anlamlı basamak tutar ve hiçbir Java ilkeli bunu yapmaz. Geri okurken attributes().get("Awards").n() de bir String'dir; yanlış tür için erişimci bir hata fırlatmak yerine null döndürür, dolayısıyla bir sayı üzerinde .s() sessiz bir null'dur ve hangisinin ayarlı olduğunu .type() söyler.

  • response.attributes() asla null döndürmez. ReturnValue.NONE ile boş ama null olmayan bir DefaultSdkAutoConstructMap döndürür, dolayısıyla bir null denetimi asla ateşlenmez ve bir isEmpty() denetimi "hizmet hiçbir şey göndermedi" ile "öğenin özniteliği yok" arasını ayıramaz. Farkı bilen erişimci, üretilen hasAttributes()'tır. Bu SDK'daki her koleksiyon üyesinin böyle bir erişimcisi vardır.

  • Oluşturucu, önemli olan kısım dışında her şeyi tür denetler. updateExpression(String) herhangi bir dizeyi kabul eder; derleyici SET'i bir yazım hatasından ayırt edemez, dolayısıyla ifade hataları çalışma zamanı 400'leridir. ADD #upd2 :updValue2 atomik artırmadır, attribute_exists(Artist) içeren bir conditionExpression çağrıyı yalnızca-güncelle yapar ve gramer güncelleme ifadeleri içindedir.

  • İfadeyi eski attributeUpdates haritasına yeğleyin. Eski örnekler onu hâlâ gösterir; birden çok yan tümce türünü, takma adları ya da tek istekte bir koşulu ifade edemez.

  • getMessage() hizmetin mesajı değildir. SDK kendi taşıma ayrıntısını ekler:

    The conditional request failed (Service: DynamoDb, Status Code: 400, Request ID: d99b117c-edd6-4dc9-8d3a-a5fa4fe9666c) (SDK Attempt Count: 1)

    Bir destek talebi için istek kimliğini istiyorsanız bunu günlükleyin. Karşılaştırmayı bunun yerine awsErrorDetails().errorCode() üzerinden yapın ve çıplak dizeyi istediğinizde awsErrorDetails().errorMessage() kullanın.

Yakalama sırası burada her zamankinden daha önemlidir

ConditionalCheckFailedException extends DynamoDbException, dolayısıyla önce yerleştirilen bir catch (DynamoDbException e), neredeyse kesinlikle üzerinde dallanmak istediğiniz tek başarısızlığı yutar. Önce belirli türü yakalayın ve hazır oradayken öğeyi de alın:

} catch (ConditionalCheckFailedException e) {
    // with .returnValuesOnConditionCheckFailure(ReturnValuesOnConditionCheckFailure.ALL_OLD)
    if (e.hasItem()) {
        Map<String, AttributeValue> loser = e.item();  // the item as it actually was
    }
} catch (DynamoDbException e) {
    // everything else
}

Bunda e.retryable() false'tur ve bu doğrudur: başarısız bir koşulu yeniden denemek yalnızca yine başarısız olur.

Akılda tutulması gereken asimetri şudur: bu SDK'da ValidationException'ın sınıfı yoktur. dynamodb-2.35.9.jar içinde arayın, yakalayacak bir şey yoktur. Bir ayrılmış sözcük, hatalı biçimlendirilmiş bir ifade, kısmi bir anahtar: hepsi, awsErrorDetails().errorCode() değeri tesadüfen ValidationException okuyan düz bir DynamoDbException olarak gelir. Statik türlenmiş bir dilde bu sarsıcı bir boşluktur ve ifade hatalarının çalışma zamanı dize karşılaştırmaları olduğu anlamına gelir.

DynamoDB'nin ayrılmış sözcüklerinin yayına almadan sonra değil önce bir gözden geçirmeyi hak etmesinin nedeni de budur: liste 573 girdiye ulaşır ve bir Java bean'inde hiçbiri tehlikeli görünmeyen Year, Name ve Status'ü içerir. Üzerindeki bean eşlemesi yerine ham tabloya göz atmak için DynoTable'ı indirin.

Enhanced client bunu ifade edemez

Geri kalan veri erişiminiz DynamoDbEnhancedClient ve açıklama içeren bean'ler üzerinden geçiyorsa, sizi DynamoDbClient'a geri düşüren işlem budur. UpdateItemEnhancedRequest.Builder üzerinde yansıma yapmak item, conditionExpression, ignoreNulls, ignoreNullsMode, returnValues, returnValuesOnConditionCheckFailure, returnConsumedCapacity ve returnItemCollectionMetrics ortaya çıkarır. Bir güncelleme ifadesi kabul eden hiçbir yöntem yoktur.

Pratik sonuç atomik sayaçtır. ADD #upd2 :updValue2, Awards'ı önce okumadan sunucu tarafında artırır; enhanced client ise size eşlenmiş bir bean ve yok olan alanların kaldırılıp kaldırılmayacağına karar veren ignoreNulls verir, ADD'e derlenen hiçbir şey vermez. Bir bean üzerinden oku-değiştir-yaz, eşzamanlılık altında kayıp güncelleme yarışıdır ve bu sayfanın parçacığının tam olarak kaçındığı şey de budur.

İlgili örnekler

Kaynaklar

En son 2026-07-28 tarihinde yukarıda bağlantısı verilen resmi AWS belgelerine karşı doğrulandı.

Console olmadan DynamoDB ile çalış

DynamoDB’nin çalıştıramadığı gerçek SQL’i çalıştıran hızlı bir DynamoDB masaüstü istemcisi — JOINs, GROUP BY, toplamalar — görsel düzenleme ve kendi Bedrock anahtarların üzerinde bir yapay zekâ aracısıyla.

30 günlük ücretsiz deneme, kredi kartı yok — ardından süre sınırı olmayan Ücretsiz plan.