DynamoDB Query di Java (AWS SDK v2)
queryPaginator di AWS SDK for Java 2.x terlihat seperti koleksi padahal bukan. Ia adalah iterable malas yang bisa diulang, dan bedanya muncul di tagihan Anda saat kedua kalinya Anda melakukan loop atasnya. Untuk menentukan apakah Query memang pembacaan yang tepat, lihat Query vs. Scan.
Kode
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
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.QueryRequest;
import software.amazon.awssdk.services.dynamodb.model.QueryResponse;
public class QueryExample {
public static void main(String[] args) {
try (DynamoDbClient ddb = DynamoDbClient.builder()
.region(Region.US_EAST_1)
.build()) {
Map<String, String> names = new HashMap<>();
names.put("#hashKey", "Artist");
names.put("#rangeKey", "SongTitle");
Map<String, AttributeValue> values = new HashMap<>();
values.put(":hashKeyValue", AttributeValue.builder().s("Arturo Sandoval").build());
values.put(":rangeKeyValue", AttributeValue.builder().s("C").build());
QueryRequest request = QueryRequest.builder()
.tableName("Music")
.keyConditionExpression(
"#hashKey = :hashKeyValue AND begins_with(#rangeKey, :rangeKeyValue)")
.expressionAttributeNames(names)
.expressionAttributeValues(values)
.build();
List<Map<String, AttributeValue>> items = new ArrayList<>();
for (QueryResponse page : ddb.queryPaginator(request)) {
items.addAll(page.items());
}
System.out.println("Found " + items.size() + " items");
} catch (DynamoDbException e) {
System.err.println(e.getMessage());
}
}
}QueryIterable menjalankan ulang query-nya setiap kali Anda mengiterasi
Terhadap fixture 600 lagu, tiap lagu ~3,9 KB dan semuanya di bawah Artist = "Arturo Sandoval", ddb.queryPaginator(request) kembali dalam 2,6 ms dan tidak mengirim apa pun. Lalu objek QueryIterable yang sama di-loop dua kali:
queryPaginator(request) returned in 2.60 ms (class QueryIterable, 0 requests)
iteration 1: pages=3 items=600 capacity=284.5
iteration 2: pages=3 items=600 capacity=284.5 <- same objectDua loop for atas satu variabel, 569 read unit. Halamannya tidak pernah di-cache; setiap iterasi menyusuri LastEvaluatedKey dari awal lagi. Kalau Anda butuh item-nya dua kali, tuang iterable itu ke sebuah List sekali saja, seperti yang dilakukan contoh ini.
Sisi lain dari kemalasan yang sama adalah tempat error muncul. Bangun request yang key condition-nya menghilangkan partition key dan queryPaginator menerimanya tanpa protes, karena belum ada panggilan yang terjadi:
queryPaginator(bad) constructed without throwing
threw on iteration: DynamoDbException / ValidationException /
Query condition missed key schema element / http 400Try-catch yang membungkus builder tidak menangkap apa pun. Ia harus membungkus loop-nya, dan itulah sebabnya contoh ini menaruh seluruh blok di dalam satu try.
Diukur 2026-07-28 terhadap DynamoDB Local (amazon/dynamodb-local) dengan software.amazon.awssdk:dynamodb 2.49.4 pada OpenJDK 26.0.1.
Penjelasan
ddb.queryPaginator(request).items()meratakan halaman-halamannya menjadiIterable<Map<String, AttributeValue>>dan mempaginasi di belakang Anda, jadi loop dua tingkat pada contoh menciut jadi satu ketika Anda hanya menginginkan item-nya. Ia juga sebuahSdkIterable, jadi.stream()berfungsi.- Angka bertipe
Stringdi builder.AttributeValue.builder().n("1994")bukan salah ketik untuk.n(1994)— settern()menerimajava.lang.String, karena DynamoDB mengangkut angka sebagai teks desimal untuk menghindari pembulatan float biner. MengoperintJava tidak akan ter-compile. keyConditionExpressionmenerima satu kesamaan pada partition key plus paling banyak satu kondisi sort key (=,<,<=,>,>=,BETWEEN,begins_with);.scanIndexForward(false)membalik urutannya dan.indexName("...")mengarahkannya ke secondary index.- Enhanced Client adalah ergonomi yang lain.
software.amazon.awssdk.enhanced.dynamodbmemetakan bean beranotasi alih-alihMap<String, AttributeValue>, danquery-nya mengembalikanPageIterable<T>dengan semantik iterasi-ulang malas yang sama seperti yang diukur di atas.
Lakukan secara visual
Baik #hashKey maupun #rangeKey dalam contoh ini adalah alias yang tidak dipaksakan kepada Anda: Artist maupun SongTitle tidak ada dalam daftar 573 reserved word milik AWS. Pemeriksa reserved word memberi tahu nama atribut mana yang benar-benar butuh perlakuan #, sehingga peta alias berhenti menjadi kebiasaan tanpa alasan.
Untuk mencoba sebuah key condition terhadap tabel sungguhan sebelum Anda membangun QueryRequest, unduh DynoTable dan susuri hasilnya dalam sebuah grid.
Contoh terkait
- DynamoDB Query di Go — query yang sama dengan AWS SDK for Go v2.
- DynamoDB Scan di Java — ketika Anda tidak bisa masuk ke sebuah partisi lewat key.
- Query vs. Scan — mengapa
Queryadalah default yang benar. - Key condition expression — setiap operator partition/sort key yang sah.
- "Query condition missed key schema element" — key condition menyebut atribut yang salah atau melewatkan partition key.
- "Query key condition not supported" — operator yang tidak bisa dipakai key condition, seperti contains atau kondisi sort key kedua.