DynamoDB UpdateItem di Java (AWS SDK v2)
Update-nya sendiri adalah satu panggilan builder. Yang menghabiskan waktu developer Java adalah semua hal di sekitarnya: objek respons yang tak pernah mengembalikan null, hierarki exception di mana kegagalan yang menarik adalah subclass dari yang mungkin sudah Anda tangkap, dan client tingkat tinggi yang sama sekali tak bisa menyatakan operasi ini.
Kode
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());
}
}
}Penjelasan
AttributeValue.builder().n("1994")menerima sebuahString, begitu pulaAttributeValue.fromN("1994")yang lebih ringkas. Tak ada overloadn(int), karena angka DynamoDB menampung 38 digit signifikan dan tak ada primitif Java yang bisa. Saat membacanya kembali,attributes().get("Awards").n()juga sebuahString; accessor untuk tipe yang salah mengembalikan null alih-alih melempar error, jadi.s()pada sebuah angka adalah null yang senyap, dan.type()memberi tahu Anda yang mana yang terisi.response.attributes()tak pernah mengembalikan null. DenganReturnValue.NONEia mengembalikan sebuahDefaultSdkAutoConstructMapyang kosong tapi bukan null, jadi pemeriksaan null tak pernah menyala dan pemeriksaanisEmpty()tak bisa membedakan "layanan tidak mengirim apa-apa" dari "item-nya tak punya atribut".hasAttributes()yang dihasilkan adalah accessor yang tahu bedanya. Setiap member koleksi di SDK ini punya satu.Builder-nya memeriksa tipe segalanya kecuali bagian yang penting.
updateExpression(String)menerima string apa pun; kompiler tak bisa membedakanSETdari salah ketik, jadi kesalahan expression menjadi 400 saat runtime.ADD #upd2 :updValue2adalah increment atomiknya,conditionExpressionberisiattribute_exists(Artist)membuat panggilan itu hanya-memperbarui, dan tata bahasanya ada di update expression.Utamakan expression daripada map
attributeUpdatesyang legacy. Contoh-contoh lama masih menampilkannya; ia tak bisa menyatakan beberapa jenis klausa, alias, atau sebuah kondisi dalam satu request.getMessage()bukan pesan dari layanan. SDK menambahkan detail transportnya sendiri:The conditional request failed (Service: DynamoDb, Status Code: 400, Request ID: d99b117c-edd6-4dc9-8d3a-a5fa4fe9666c) (SDK Attempt Count: 1)Catat itu kalau Anda ingin request ID untuk keperluan support. Bandingkan pada
awsErrorDetails().errorCode()sebagai gantinya, dan pakaiawsErrorDetails().errorMessage()saat Anda ingin string mentahnya.
Urutan catch lebih penting dari biasanya di sini
ConditionalCheckFailedException extends DynamoDbException, jadi catch (DynamoDbException e) yang diletakkan lebih dulu menelan satu kegagalan yang hampir pasti ingin Anda cabangkan. Tangkap tipe spesifiknya lebih dulu, dan sekalian ambil item-nya:
} 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
}e.retryable() bernilai false pada yang satu ini, dan itu benar: mencoba ulang kondisi yang gagal hanya akan gagal lagi.
Ketimpangan yang perlu diingat adalah bahwa ValidationException tak punya kelas di SDK ini. Telusuri dynamodb-2.35.9.jar dan tak ada apa pun untuk ditangkap. Sebuah reserved word, expression yang bentuknya salah, key yang tak lengkap: semuanya datang sebagai DynamoDbException biasa yang awsErrorDetails().errorCode()-nya kebetulan berbunyi ValidationException. Dalam bahasa bertipe statis itu celah yang mengganggu, dan artinya kesalahan expression menjadi perbandingan string saat runtime.
Itulah sebabnya reserved word DynamoDB layak diperiksa sebelum Anda merilis alih-alih sesudahnya: daftarnya mencapai 573 entri dan mencakup Year, Name dan Status, yang tak satu pun terlihat berbahaya di dalam sebuah bean Java. Untuk menjelajahi tabel mentahnya alih-alih pemetaan bean di atasnya, unduh DynoTable.
Enhanced client tak bisa menyatakan ini
Kalau sisa akses data Anda melewati DynamoDbEnhancedClient dan bean beranotasi, operasi inilah yang menjatuhkan Anda kembali ke DynamoDbClient. Refleksi atas UpdateItemEnhancedRequest.Builder memunculkan item, conditionExpression, ignoreNulls, ignoreNullsMode, returnValues, returnValuesOnConditionCheckFailure, returnConsumedCapacity dan returnItemCollectionMetrics. Tak ada metode yang menerima sebuah update expression.
Konsekuensi praktisnya adalah counter atomik. ADD #upd2 :updValue2 menaikkan Awards di sisi server tanpa pembacaan lebih dulu; enhanced client memberi Anda bean terpetakan dan ignoreNulls untuk menentukan apakah field yang tak ada dihapus, dan tak ada yang terkompilasi menjadi ADD. Read-modify-write lewat sebuah bean adalah balapan lost-update di bawah konkurensi, dan itulah persis yang dihindari cuplikan di halaman ini.
Contoh terkait
- DynamoDB UpdateItem di Go — update yang sama dengan AWS SDK for Go v2.
- DynamoDB PutItem di Java — ganti seluruh item-nya sebagai gantinya.
- Update expression DynamoDB —
SET,ADD,REMOVE,DELETE, dan idiomnya. - Memahami ReturnValues — apa yang diberikan setiap opsi
ReturnValues. - "Attribute name is a reserved keyword" — mengapa map alias di sini tidak opsional.
- Error sintaks "Invalid UpdateExpression" — kesalahan sintaks SET/ADD yang umum, diurai.
Referensi
- UpdateItem — Amazon DynamoDB API Reference
- Use UpdateItem with an AWS SDK or CLI — Amazon DynamoDB Developer Guide
- DynamoDbClient — AWS SDK for Java 2.x API Reference
- UpdateItemRequest — AWS SDK for Java 2.x API Reference
- Update expressions — Amazon DynamoDB Developer Guide
Terakhir diverifikasi 2026-07-28 terhadap dokumentasi resmi AWS yang ditautkan di atas.