DynamoDB Query in Java (AWS SDK v2)

Query reads every item that shares one partition key, optionally narrowing by the sort key. In AWS SDK for Java 2.x you build a QueryRequest with a keyConditionExpression, and the built-in queryPaginator follows LastEvaluatedKey across every result page for you.

Code

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());
        }
    }
}

Explanation

  • keyConditionExpression — must include an equality on the partition key (#hashKey = :hashKeyValue) plus at most one sort-key condition (=, <, <=, >, >=, BETWEEN, or begins_with). The #hashKey/#rangeKey aliases resolve to Artist/SongTitle via expressionAttributeNames (reserved-word-safe).
  • expressionAttributeValues — the :placeholder → typed-AttributeValue map.
  • Pagination — one Query returns at most 1 MB. ddb.queryPaginator(request) returns a QueryIterable that lazily issues follow-up requests as you iterate the pages; each QueryResponse page carries an items() list. (Doing it by hand? Feed lastEvaluatedKey() back as .exclusiveStartKey(...) until it's empty.)
  • Add .scanIndexForward(false) to reverse the sort-key order (ascending is the default).
  • Query a secondary index by adding .indexName("...").
  • Prefer plain Java objects? The DynamoDB Enhanced Client (software.amazon.awssdk.enhanced.dynamodb) exposes the same query with annotated bean classes.

Do it visually

The DynamoDB Expression Builder assembles the key condition and copies runnable code, so you don't hand-write placeholder and value maps.

To run queries against real tables in a GUI — key-condition form, paginated grid, copy-as-code — download DynoTable.

References

Last verified 2026-07-13 against the official AWS documentation linked above.

Build this request visually

Compose this operation in the free DynamoDB Query Builder — key condition, filter, index, Limit, sort order, and a pagination loop — and copy it back as a runnable SDK v3, CLI, or boto3 program.

Open the DynamoDB Query Builder

Work with DynamoDB without the Console

DynoTable is a fast desktop client for DynamoDB — browse tables, run SQL-style queries, and edit items locally.