Java'da DynamoDB Query (AWS SDK v2)
AWS SDK for Java 2.x'teki queryPaginator bir koleksiyon gibi görünür ama değildir. Tembel ve yeniden yinelenebilir bir yapıdır ve fark, üzerinde ikinci kez döngü kurduğunuzda faturanızda ortaya çıkar. Query'nin ne zaman doğru okuma olduğu için bkz. Query ile Scan.
Kod
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 her yinelemede sorguyu yeniden çalıştırır
Her şarkısı ~3,9 KB olan ve hepsi Artist = "Arturo Sandoval" altında bulunan 600 şarkılık bir düzenekte ddb.queryPaginator(request) 2,6 ms'de döndü ve hiçbir şey göndermedi. Sonra aynı QueryIterable nesnesi üzerinde iki kez döngü kuruldu:
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 objectTek bir değişken üzerinde iki for döngüsü, 569 okuma birimi. Sayfalar hiç önbelleğe alınmadı; her yineleme LastEvaluatedKey'i baştan yeniden yürür. Öğelere iki kez ihtiyacınız varsa, örnekte yapıldığı gibi yinelenebiliri bir kez bir List'e boşaltın.
Aynı tembelliğin diğer yüzü, hataların nerede yüzeye çıktığıdır. Anahtar koşulu bölüm anahtarını atlayan bir istek kurun; queryPaginator onu şikâyet etmeden kabul eder, çünkü henüz hiçbir çağrı gerçekleşmemiştir:
queryPaginator(bad) constructed without throwing
threw on iteration: DynamoDbException / ValidationException /
Query condition missed key schema element / http 400Kurucunun etrafına sarılmış bir try-catch hiçbir şey yakalamaz. Döngüyü sarmalamak zorundadır; örneğin tüm bloğu tek bir try içine koymasının nedeni budur.
2026-07-28 tarihinde OpenJDK 26.0.1 üzerinde software.amazon.awssdk:dynamodb 2.49.4 ile, DynamoDB Local'e (amazon/dynamodb-local) karşı ölçüldü.
Açıklama
ddb.queryPaginator(request).items()sayfaları birIterable<Map<String, AttributeValue>>içinde düzleştirir ve sayfalamayı sizin arkanızda yapar; dolayısıyla yalnızca öğeleri istediğinizde örnekteki iki düzeyli döngü tek düzeye iner. Ayrıca birSdkIterable'dır, yani.stream()de çalışır.- Kurucuda sayılar
String'dir.AttributeValue.builder().n("1994"),.n(1994)için bir yazım hatası değildir —n()ayarlayıcısı birjava.lang.Stringalır, çünkü DynamoDB ikili float yuvarlamasından kaçınmak için sayıları ondalık metin olarak taşır. Javaintgeçirmek derlenmez. keyConditionExpressionbölüm anahtarında bir eşitlik artı en fazla bir sıralama anahtarı koşulu alır (=,<,<=,>,>=,BETWEEN,begins_with);.scanIndexForward(false)sırayı tersine çevirir ve.indexName("...")ikincil bir indeksi hedefler.- Enhanced Client diğer ergonomidir.
software.amazon.awssdk.enhanced.dynamodb,Map<String, AttributeValue>yerine açıklamalı bean'leri eşler vequery'si yukarıda ölçülen aynı tembel yeniden yineleme semantiğine sahip birPageIterable<T>döndürür.
Görsel olarak yapın
Bu örnekteki hem #hashKey hem de #rangeKey, hiçbir şeyin size dayatmadığı takma adlardır: ne Artist ne de SongTitle AWS'nin 573 sözcüklük ayrılmış listesindedir. Ayrılmış sözcük denetleyicisi, öznitelik adlarınızdan hangilerinin gerçekten # muamelesine ihtiyacı olduğunu söyler; böylece takma ad eşlemesi bir yük olmaktan çıkar.
QueryRequest'i kurmadan önce bir anahtar koşulunu gerçek bir tabloya karşı denemek için DynoTable'ı indirin ve sonuçlarda bir ızgarada sayfalayın.
İlgili örnekler
- Go'da DynamoDB Query — AWS SDK for Go v2 ile aynı sorgu.
- Java'da DynamoDB Scan — bir bölüme anahtarla giremediğinizde.
- Query ile Scan —
Queryneden doğru varsayılandır. - Anahtar koşulu ifadeleri — her geçerli bölüm/sıralama anahtarı operatörü.
- "Query condition missed key schema element" — anahtar koşulu yanlış özniteliği adlandırıyor ya da bölüm anahtarını atlıyor.
- "Query key condition not supported" — anahtar koşulunun kullanamayacağı bir operatör, contains ya da ikinci bir sıralama anahtarı koşulu gibi.