

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 페이지 매김된 결과 작업: 스캔 및 쿼리
<a name="ddb-en-client-use-multirecord"></a>

DynamoDB 향상된 클라이언트 API의 `scan`, `query` 및 `batch` 메서드는 하나 이상의 *페이지*가 포함된 응답을 반환합니다. 페이지에는 하나 이상의 항목이 포함되어 있습니다. 코드는 페이지별로 응답을 처리하거나 개별 항목을 처리할 수 있습니다.

동기 `DynamoDbEnhancedClient` 클라이언트가 반환한 페이지 단위 응답은 [PageIterable](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/PageIterable.html) 객체를 반환하고, 비동기 `DynamoDbEnhancedAsyncClient`에서 반환한 응답은 [PagePublisher](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/PagePublisher.html) 객체를 반환합니다.

이 단원에서는 페이지를 매긴 결과 처리를 살펴보고 스캔 및 쿼리 API를 사용하는 예제를 제공합니다.

## 테이블 스캔
<a name="ddb-en-client-use-multirecord-scan"></a>

SDK의 [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbAsyncTable.html#scan(java.util.function.Consumer)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbAsyncTable.html#scan(java.util.function.Consumer)) 메서드는 동일한 이름의 [DynamoDB 작업](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html)에 해당합니다. DynamoDB 향상된 클라이언트 API는 동일한 옵션을 제공하지만 익숙한 객체 모델을 사용하고 페이지 매김을 자동으로 처리합니다.

먼저 동기 매핑 클래스 [DynamoDBTable](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbTable.html)의 `scan` 메서드를 살펴보면서 `PageIterable` 인터페이스를 살펴봅니다.

### 동기식 API를 사용
<a name="ddb-en-client-use-multirecord-scan-sync"></a>

다음 예제는 [표현식](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/Expression.html)을 사용하여 반환되는 항목을 필터링하는 `scan` 메서드를 보여줍니다. [ProductCatalog](ddb-en-client-use.md#ddb-en-client-use-compare-cs3)는 이전에 표시된 모델 객체입니다.

주석 줄 2 뒤에 표시되는 필터링 표현식은 반환되는 `ProductCatalog` 항목을 가격 값이 8.00\$180.00인 항목으로 제한합니다.

또한이 예제에서는 주석 줄 1 다음에 표시된 `attributesToProject` 메서드를 사용하여 `isbn` 값을 제외합니다.

주석 줄 3 이후에는 `scan` 메서드가 `PageIterable` 객체, `pagedResults`를 반환합니다. `PageIterable`의 `stream` 메서드는 페이지를 처리하는 데 사용할 수 있는 [https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html) 객체를 반환합니다. 이 예제는 페이지 수를 세고 기록합니다.

이 예제는 주석 줄 4부터 시작하여 `ProductCatalog` 항목 액세스의 두 가지 변형을 보여줍니다. 주석 줄 4a 이후의 버전은 각 페이지를 스트리밍하고 각 페이지의 항목을 정렬하고 로깅합니다. 주석 줄 4b 이후의 버전은 페이지 반복을 건너뛰고 항목에 직접 액세스합니다.

`PageIterable` 인터페이스는 2개의 상위 인터페이스 [https://docs.oracle.com/javase/8/docs/api/java/lang/Iterable.html](https://docs.oracle.com/javase/8/docs/api/java/lang/Iterable.html) 및 [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/pagination/sync/SdkIterable.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/pagination/sync/SdkIterable.html)로 결과를 처리하는 다양한 방법을 제공합니다. `Iterable`은 `forEach`, `iterator` 및 `spliterator` 메서드를 가져오고 `SdkIterable`은 `stream` 메서드를 가져옵니다.

```
    public static void scanSync(DynamoDbTable<ProductCatalog> productCatalog) {

        Map<String, AttributeValue> expressionValues = Map.of(
                ":min_value", numberValue(8.00),
                ":max_value", numberValue(80.00));

        ScanEnhancedRequest request = ScanEnhancedRequest.builder()
                .consistentRead(true)
                // 1. the 'attributesToProject()' method allows you to specify which values you want returned.
                .attributesToProject("id", "title", "authors", "price")
                // 2. Filter expression limits the items returned that match the provided criteria.
                .filterExpression(Expression.builder()
                        .expression("price >= :min_value AND price <= :max_value")
                        .expressionValues(expressionValues)
                        .build())
                .build();

        // 3. A PageIterable object is returned by the scan method.
        PageIterable<ProductCatalog> pagedResults = productCatalog.scan(request);
        logger.info("page count: {}", pagedResults.stream().count());

        // 4. Log the returned ProductCatalog items using two variations.
        // 4a. This version sorts and logs the items of each page.
        pagedResults.stream().forEach(p -> p.items().stream()
                .sorted(Comparator.comparing(ProductCatalog::price))
                .forEach(
                        item -> logger.info(item.toString())
                ));
        // 4b. This version sorts and logs all items for all pages.
        pagedResults.items().stream()
                .sorted(Comparator.comparing(ProductCatalog::price))
                .forEach(
                        item -> logger.info(item.toString())
                );
    }
```

### 비동기 API 사용
<a name="ddb-en-client-use-multirecord-scan-async"></a>

비동기 `scan` 메서드는 결과를 `PagePublisher` 객체로 반환합니다. `PagePublisher` 인터페이스에는 응답 페이지를 처리하는 데 사용할 수 있는 두 가지 `subscribe` 메서드가 있습니다. 한 가지 `subscribe` 메서드는 `org.reactivestreams.Publisher` 상위 인터페이스에서 가져온 것입니다. 이 첫 번째 옵션을 사용하여 페이지를 처리하려면 `subscribe` 메서드에 `[Subscriber](https://www.reactive-streams.org/reactive-streams-1.0.0-javadoc/org/reactivestreams/Subscriber.html)` 인스턴스를 전달하세요. 다음 예제는 `subscribe` 메서드 사용을 보여 줍니다.

두 번째 `subscribe` 메서드는 [SdkPublisher](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/SdkPublisher.html) 인터페이스에서 가져온 것입니다. `subscribe`의 이 버전에서는 `Subscriber`가 아닌 [https://docs.oracle.com/javase/8/docs/api/java/util/function/Consumer.html](https://docs.oracle.com/javase/8/docs/api/java/util/function/Consumer.html)를 받아들입니다. 이 `subscribe` 메서드 변형은 다음 두 번째 예제에 나와 있습니다.

다음 예제는 이전 예제와 동일한 필터 표현식을 사용하는 `scan` 메서드의 비동기 버전을 보여줍니다.

주석 줄 3번 다음에 `DynamoDbAsyncTable.scan`는 `PagePublisher` 객체를 반환합니다. 다음 줄에서 코드는 `org.reactivestreams.Subscriber` 인터페이스의 인스턴스를 만들고, `ProductCatalogSubscriber`는 주석 줄 4 뒤 `PagePublisher`를 구독합니다.

`Subscriber` 객체는 `ProductCatalogSubscriber` 클래스 예제의 주석 줄 8 다음에 있는 `onNext` 메서드의 각 페이지에서 `ProductCatalog` 항목을 수집합니다. 항목은 전용 `List` 변수에 저장되며 `ProductCatalogSubscriber.getSubscribedItems()` 메서드를 사용하여 호출 코드에서 액세스할 수 있습니다. 이는 주석 줄 5 이후에 호출됩니다.

목록이 검색되면 코드는 모든 `ProductCatalog` 항목을 가격별로 정렬하고 각 항목을 기록합니다.

`ProductCatalogSubscriber` 클래스의 [CountDownLatch](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html)는 모든 항목이 목록에 추가될 때까지 호출 스레드를 차단한 다음 주석 줄 5 이후에 계속합니다.

```
    public static void scanAsync(DynamoDbAsyncTable productCatalog) {
        ScanEnhancedRequest request = ScanEnhancedRequest.builder()
                .consistentRead(true)
                .attributesToProject("id", "title", "authors", "price")
                .filterExpression(Expression.builder()
                        // 1. :min_value and :max_value are placeholders for the values provided by the map
                        .expression("price >= :min_value AND price <= :max_value")
                        // 2. Two values are needed for the expression and each is supplied as a map entry.
                        .expressionValues(
                                Map.of( ":min_value", numberValue(8.00),
                                        ":max_value", numberValue(400_000.00)))
                        .build())
                .build();

        // 3. A PagePublisher object is returned by the scan method.
        PagePublisher<ProductCatalog> pagePublisher = productCatalog.scan(request);
        ProductCatalogSubscriber subscriber = new ProductCatalogSubscriber();
        // 4. Subscribe the ProductCatalogSubscriber to the PagePublisher.
        pagePublisher.subscribe(subscriber);
        // 5. Retrieve all collected ProductCatalog items accumulated by the subscriber.
        subscriber.getSubscribedItems().stream()
                .sorted(Comparator.comparing(ProductCatalog::price))
                .forEach(item ->
                        logger.info(item.toString()));
        // 6. Use a Consumer to work through each page.
        pagePublisher.subscribe(page -> page
                        .items().stream()
                        .sorted(Comparator.comparing(ProductCatalog::price))
                        .forEach(item ->
                                logger.info(item.toString())))
                .join(); // If needed, blocks the subscribe() method thread until it is finished processing.
        // 7. Use a Consumer to work through each ProductCatalog item.
        pagePublisher.items()
                .subscribe(product -> logger.info(product.toString()))
                .exceptionally(failure -> {
                    logger.error("ERROR  - ", failure);
                    return null;
                })
                .join(); // If needed, blocks the subscribe() method thread until it is finished processing.
    }
```

```
    private static class ProductCatalogSubscriber implements Subscriber<Page<ProductCatalog>> {
        private CountDownLatch latch = new CountDownLatch(1);
        private Subscription subscription;
        private List<ProductCatalog> itemsFromAllPages = new ArrayList<>();

        @Override
        public void onSubscribe(Subscription sub) {
            subscription = sub;
            subscription.request(1L);
            try {
                latch.await(); // Called by main thread blocking it until latch is released.
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

        @Override
        public void onNext(Page<ProductCatalog> productCatalogPage) {
            // 8. Collect all the ProductCatalog instances in the page, then ask the publisher for one more page.
            itemsFromAllPages.addAll(productCatalogPage.items());
            subscription.request(1L);
        }

        @Override
        public void onError(Throwable throwable) {
        }

        @Override
        public void onComplete() {
            latch.countDown(); // Call by subscription thread; latch releases.
        }

        List<ProductCatalog> getSubscribedItems() {
            return this.itemsFromAllPages;
        }
    }
```

다음 코드 조각 예제는 주석 줄 6을 다음에 `Consumer`를 받아들이는 `PagePublisher.subscribe` 메서드의 버전을 사용합니다. Java 람다 매개변수는 각 항목을 추가로 처리하는 페이지를 사용합니다. 이 예에서는 각 페이지가 처리되고 각 페이지의 항목이 정렬된 후 기록됩니다.

```
        // 6. Use a Consumer to work through each page.
        pagePublisher.subscribe(page -> page
                        .items().stream()
                        .sorted(Comparator.comparing(ProductCatalog::price))
                        .forEach(item ->
                                logger.info(item.toString())))
                .join(); // If needed, blocks the subscribe() method thread until it is finished processing.
```

`PagePublisher`의 `items` 메서드는 모델 인스턴스를 언래핑하여 코드가 항목을 직접 처리할 수 있도록 합니다. 이 접근 방법은 다음 코드 조각에 나와 있습니다.

```
        // 7. Use a Consumer to work through each ProductCatalog item.
        pagePublisher.items()
                .subscribe(product -> logger.info(product.toString()))
                .exceptionally(failure -> {
                    logger.error("ERROR  - ", failure);
                    return null;
                })
                .join(); // If needed, blocks the subscribe() method thread until it is finished processing.
```

## 테이블 쿼리
<a name="ddb-en-client-use-multirecord-query"></a>

DynamoDB 향상된 클라이언트를 사용하여 테이블을 쿼리하고 특정 기준과 일치하는 여러 항목을 검색할 수 있습니다. [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbTable.html#query(software.amazon.awssdk.enhanced.dynamodb.model.QueryEnhancedRequest)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbTable.html#query(software.amazon.awssdk.enhanced.dynamodb.model.QueryEnhancedRequest)) 메서드는 데이터 클래스에 정의된 `@DynamoDbPartitionKey` 및 `@DynamoDbSortKey` 주석(선택 사항)을 사용하여 프라이머리 키 값을 기반으로 항목을 찾습니다.

`query()` 메서드에는 파티션 키 값이 필요하며 경우에 따라 정렬 키 조건을 수락하여 결과를 추가로 구체화합니다. `scan` API와 마찬가지로 쿼리는 동기식 호출의 `PageIterable`을 반환하고 비동기식 직접 호출의 `PagePublisher`를 반환합니다.

### `Query` 메서드 예제
<a name="ddb-en-client-use-multirecord-query-example"></a>

다음 `query()` 메서드 코드 예제에서는 `MovieActor` 클래스를 사용합니다. 데이터 클래스는 파티션 키의 **`movie`** 속성과 정렬 키의 **`actor`** 속성으로 구성된 복합 프라이머리 키를 정의합니다.

#### `MovieActor` 클래스
<a name="ddb-en-client-use-movieactor-class"></a>

```
package org.example.tests.model;

import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbAttribute;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSecondaryPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSecondarySortKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey;

import java.util.Objects;

@DynamoDbBean
public class MovieActor implements Comparable<MovieActor> {

    private String movieName;
    private String actorName;
    private String actingAward;
    private Integer actingYear;
    private String actingSchoolName;

    @DynamoDbPartitionKey
    @DynamoDbAttribute("movie")
    public String getMovieName() {
        return movieName;
    }

    public void setMovieName(String movieName) {
        this.movieName = movieName;
    }

    @DynamoDbSortKey
    @DynamoDbAttribute("actor")
    public String getActorName() {
        return actorName;
    }

    public void setActorName(String actorName) {
        this.actorName = actorName;
    }

    @DynamoDbSecondaryPartitionKey(indexNames = "acting_award_year")
    @DynamoDbAttribute("actingaward")
    public String getActingAward() {
        return actingAward;
    }

    public void setActingAward(String actingAward) {
        this.actingAward = actingAward;
    }

    @DynamoDbSecondarySortKey(indexNames = {"acting_award_year", "movie_year"})
    @DynamoDbAttribute("actingyear")
    public Integer getActingYear() {
        return actingYear;
    }

    public void setActingYear(Integer actingYear) {
        this.actingYear = actingYear;
    }

    @DynamoDbAttribute("actingschoolname")
    public String getActingSchoolName() {
        return actingSchoolName;
    }

    public void setActingSchoolName(String actingSchoolName) {
        this.actingSchoolName = actingSchoolName;
    }

    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("MovieActor{");
        sb.append("movieName='").append(movieName).append('\'');
        sb.append(", actorName='").append(actorName).append('\'');
        sb.append(", actingAward='").append(actingAward).append('\'');
        sb.append(", actingYear=").append(actingYear);
        sb.append(", actingSchoolName='").append(actingSchoolName).append('\'');
        sb.append('}');
        return sb.toString();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        MovieActor that = (MovieActor) o;
        return Objects.equals(movieName, that.movieName) && Objects.equals(actorName, that.actorName) && Objects.equals(actingAward, that.actingAward) && Objects.equals(actingYear, that.actingYear) && Objects.equals(actingSchoolName, that.actingSchoolName);
    }

    @Override
    public int hashCode() {
        return Objects.hash(movieName, actorName, actingAward, actingYear, actingSchoolName);
    }

    @Override
    public int compareTo(MovieActor o) {
        if (this.movieName.compareTo(o.movieName) != 0){
            return this.movieName.compareTo(o.movieName);
        } else {
            return this.actorName.compareTo(o.actorName);
        }
    }
}
```

다음 항목에 대한 쿼리를 따르는 코드 예제.

#### `MovieActor` 테이블 내 항목
<a name="ddb-en-client-use-movieactor-items"></a>

```
MovieActor{movieName='movie01', actorName='actor0', actingAward='actingaward0', actingYear=2001, actingSchoolName='null'}
MovieActor{movieName='movie01', actorName='actor1', actingAward='actingaward1', actingYear=2001, actingSchoolName='actingschool1'}
MovieActor{movieName='movie01', actorName='actor2', actingAward='actingaward2', actingYear=2001, actingSchoolName='actingschool2'}
MovieActor{movieName='movie01', actorName='actor3', actingAward='actingaward3', actingYear=2001, actingSchoolName='null'}
MovieActor{movieName='movie01', actorName='actor4', actingAward='actingaward4', actingYear=2001, actingSchoolName='actingschool4'}
MovieActor{movieName='movie02', actorName='actor0', actingAward='actingaward0', actingYear=2002, actingSchoolName='null'}
MovieActor{movieName='movie02', actorName='actor1', actingAward='actingaward1', actingYear=2002, actingSchoolName='actingschool1'}
MovieActor{movieName='movie02', actorName='actor2', actingAward='actingaward2', actingYear=2002, actingSchoolName='actingschool2'}
MovieActor{movieName='movie02', actorName='actor3', actingAward='actingaward3', actingYear=2002, actingSchoolName='null'}
MovieActor{movieName='movie02', actorName='actor4', actingAward='actingaward4', actingYear=2002, actingSchoolName='actingschool4'}
MovieActor{movieName='movie03', actorName='actor0', actingAward='actingaward0', actingYear=2003, actingSchoolName='null'}
MovieActor{movieName='movie03', actorName='actor1', actingAward='actingaward1', actingYear=2003, actingSchoolName='actingschool1'}
MovieActor{movieName='movie03', actorName='actor2', actingAward='actingaward2', actingYear=2003, actingSchoolName='actingschool2'}
MovieActor{movieName='movie03', actorName='actor3', actingAward='actingaward3', actingYear=2003, actingSchoolName='null'}
MovieActor{movieName='movie03', actorName='actor4', actingAward='actingaward4', actingYear=2003, actingSchoolName='actingschool4'}
```

다음 코드는 `keyEqual`(주석 줄 1 이후) 및 `sortGreaterThanOrEqualTo`(주석 줄 1a 이후)의 2가지 `QueryConditional` 인스턴스를 정의합니다.

#### 파티션 키로 항목 쿼리
<a name="keyEqual-query-conditional-example"></a>

`keyEqual` 인스턴스는 파티션 키 값이 **`movie01`**인 항목과 일치합니다.

또한 이 예제는 주석 줄 2 이후 **`actingschoolname`**이 없는 항목을 필터링하는 필터 표현식을 정의합니다.

`QueryEnhancedRequest`는 쿼리에 대한 키 조건과 필터 표현식을 통합합니다.

```
    public static void query(DynamoDbTable movieActorTable) {

        // 1. Define a QueryConditional instance to return items matching a partition value.
        QueryConditional keyEqual = QueryConditional.keyEqualTo(b -> b.partitionValue("movie01"));
        // 1a. Define a QueryConditional that adds a sort key criteria to the partition value criteria.
        QueryConditional sortGreaterThanOrEqualTo = QueryConditional.sortGreaterThanOrEqualTo(b -> b.partitionValue("movie01").sortValue("actor2"));
        // 2. Define a filter expression that filters out items whose attribute value is null.
        final Expression filterOutNoActingschoolname = Expression.builder().expression("attribute_exists(actingschoolname)").build();

        // 3. Build the query request.
        QueryEnhancedRequest tableQuery = QueryEnhancedRequest.builder()
                .queryConditional(keyEqual)
                .filterExpression(filterOutNoActingschoolname)
                .build();
        // 4. Perform the query using the "keyEqual" conditional and filter expression.
        PageIterable<MovieActor> pagedResults = movieActorTable.query(tableQuery);
        logger.info("page count: {}", pagedResults.stream().count()); // Log  number of pages.

        pagedResults.items().stream()
                .sorted()
                .forEach(
                        item -> logger.info(item.toString()) // Log the sorted list of items.
                );
```

**Example - `keyEqual` 쿼리 조건부를 사용한 출력**  
다음은 메서드 실행 결과입니다. 출력에는 **movie01**의 `movieName` 값이 있는 항목이 표시되고 **`null`**과 같은 `actingSchoolName`이 있는 항목은 표시되지 않습니다.  

```
2023-03-05 13:11:05 [main] INFO  org.example.tests.QueryDemo:46 - page count: 1
2023-03-05 13:11:05 [main] INFO  org.example.tests.QueryDemo:51 - MovieActor{movieName='movie01', actorName='actor1', actingAward='actingaward1', actingYear=2001, actingSchoolName='actingschool1'}
2023-03-05 13:11:05 [main] INFO  org.example.tests.QueryDemo:51 - MovieActor{movieName='movie01', actorName='actor2', actingAward='actingaward2', actingYear=2001, actingSchoolName='actingschool2'}
2023-03-05 13:11:05 [main] INFO  org.example.tests.QueryDemo:51 - MovieActor{movieName='movie01', actorName='actor4', actingAward='actingaward4', actingYear=2001, actingSchoolName='actingschool4'}
```

#### 파티션 키 및 정렬 키로 항목 쿼리
<a name="sort-type-query-conditional-example"></a>

`sortGreaterThanOrEqualTo` `QueryConditional`은 **actor2**보다 크거나 같은 값에 정렬 키 조건을 추가하여 파티션 키 일치(**movie01**)를 구체화합니다.

`sort`로 시작하는[`QueryConditional` 메서드](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/QueryConditional.html)는 정렬 키 값을 기반으로 비교를 통해 쿼리를 일치시키고 더 구체화해야 합니다. 메서드 이름의 `Sort`는 결과가 정렬되었음을 의미하지 않지만 비교 시 정렬 키 값이 사용됩니다.

다음 코드 조각에서는 주석 줄 3 이후, 앞서 표시된 쿼리 요청을 변경합니다. 이 코드 조각은 ‘keyEqual’ 쿼리 조건을 주석 줄 1a 이후 정의된 ‘sortGreaterThanOrEqualTo’ 쿼리 조건으로 대체합니다. 다음 코드는 또한 필터 표현식을 제거합니다.

```
        QueryEnhancedRequest tableQuery = QueryEnhancedRequest.builder()
                .queryConditional(sortGreaterThanOrEqualTo).build();
```

**Example - `sortGreaterThanOrEqualTo` 쿼리 조건부를 사용한 출력**  
다음 출력은 쿼리 결과를 표시합니다. 쿼리는 `movieName` 값이 **movie01과** 같은 항목을 반환하고 **actor2**보다 크거나 같은 `actorName` 값을 가진 항목만 반환합니다. 필터가 제거되었으므로 쿼리는 `actingSchoolName` 속성 값이 없는 항목을 반환합니다.  

```
2023-03-05 13:15:00 [main] INFO  org.example.tests.QueryDemo:46 - page count: 1
2023-03-05 13:15:00 [main] INFO  org.example.tests.QueryDemo:51 - MovieActor{movieName='movie01', actorName='actor2', actingAward='actingaward2', actingYear=2001, actingSchoolName='actingschool2'}
2023-03-05 13:15:00 [main] INFO  org.example.tests.QueryDemo:51 - MovieActor{movieName='movie01', actorName='actor3', actingAward='actingaward3', actingYear=2001, actingSchoolName='null'}
2023-03-05 13:15:00 [main] INFO  org.example.tests.QueryDemo:51 - MovieActor{movieName='movie01', actorName='actor4', actingAward='actingaward4', actingYear=2001, actingSchoolName='actingschool4'}
```