Упражнение. Создание, чтение, обновление и удаление данных NoSQL программными средствами

Завершено

Вы подключились к Azure Cosmos DB. В этом уроке показано, как создать документы пользователя в вашей коллекции WebCustomers. Затем вы извлечете их по идентификатору, замените и удалите их.

Работа с документами программным способом

Данные хранятся в Azure Cosmos DB в виде документов JSON. Документы можно создавать, извлекать, заменять или удалять на портале или программными средствами. В этом задании основное внимание уделяется программным операциям. Azure Cosmos DB предоставляет клиентские пакеты SDK для .NET, .NET Core, Java, Node.js и Python, каждый из которых поддерживает эти операции. В этом модуле показано, как использовать пакет SDK для Java для выполнения операций CRUD (создание, получение, обновление и удаление) с данными NoSQL, хранимыми в Azure Cosmos DB.

Основные операции с документами Azure Cosmos DB являются частью класса CosmosAsyncContainer.

Upsert выполняет операцию создания или замены в зависимости от того, существует ли документ.

Для выполнения любой из этих операций потребуются вспомогательные классы (классы POJO Java), которые представляют объекты, хранящиеся в базе данных. Так как мы работаем с базой данных пользователей, необходимо иметь класс User, представляющий сущности пользователей. Этот класс хранит основные данные, такие как имя, фамилия и идентификатор пользователя. (Идентификатор обязателен, так как это ключ секции для включения горизонтального масштабирования.)

Для каждого пользователя указаны параметры доставки и купоны на скидку, поэтому вам потребуются типы данных ShippingPreference и CouponsUsed для представления этих сущностей. Наконец, у каждого пользователя может быть неограниченный журнал заказов, поэтому необходимо иметь отдельные сущности OrderHistory с соответствующим классом POJO Java.

Перейдите в каталог src/main/java/com/azure/azure-cosmos-java-sql-app-mslearn и откройте папку datatypes. Вы увидите несколько POJO: User, ShippingPreference, OrderHistory и CouponsUsed. Итак, мы предоставили все POJO сущностей и их вспомогательные классы.

Далее предстоит создать несколько сущностей и выполнить некоторые базовые операции CRUD в контейнере Azure Cosmos DB и содержащихся в нем документах. Вы можете передать в Azure Cosmos DB экземпляр Jackson ObjectNode, который непосредственно определяет документ JSON. Но Azure Cosmos DB также может сериализовать POJO Java в JSON, и мы рекомендуем использовать этот подход как простейший вариант.

Создание документов

  1. Откройте файл User.java и изучите его содержимое. Должно отобразиться примерно следующее:

    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    import java.util.List;
    
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class User {
    
        /** Document ID (required by Azure Cosmos DB). */
        private String id;
    
        /** User ID. */
        private String userId;
    
        /** User last name. */
        private String lastName;
    
        /** User first name. */
        private String firstName;
    
        /** User email address. */
        private String email;
    
        /** User dividend setting. */
        private String dividend;
    
        /** User shipping preferences. */
        private ShippingPreference shippingPreference;
    
        /** User order history. */
        private List<OrderHistory> orderHistory;
    
        /** Coupons recorded by the user. */
        private List<CouponsUsed> coupons;
    }
    

    Обратите внимание, что методы доступа для полей id, userId и т. д. являются неявными (не определены в коде). Такое поведение возможно, так как для их автоматического создания используется аннотация Project Lombok @Data.

    Аннотация @NoArgsConstructor вызывает создание конструктора без аргументов, который задает значения полей по умолчанию. Аннотация @AllArgsConstructor вызывает создание другого конструктора с полным набором аргументов для непосредственного определения всех значений полей.

    Обратите внимание, что User имеет свойство id. Для всех документов Azure Cosmos DB требуется свойство id, поэтому все POJO, которые планируется сериализовать в документы JSON, должны иметь поле id.

  2. Добавьте следующий метод в CosmosApp.java:

    /**
     * Take in list of Java POJOs, check if each exists, and if not insert it.
     * @param users List of User POJOs to insert.
     */
    private static void createUserDocumentsIfNotExist(final List<User> users) {
        Flux.fromIterable(users).flatMap(user -> {
            try {
                container.readItem(user.getId(), new PartitionKey(user.getUserId()), User.class).block();
                logger.info("User {} already exists in the database", user.getId());
                return Mono.empty();
            } catch (Exception err) {
                logger.info("Creating User {}", user.getId());
                return container.createItem(user, new PartitionKey(user.getUserId()), new CosmosItemRequestOptions());
            }
        }).blockLast();
    }
    
  3. Вернитесь к методу basicOperations и добавьте в его конец следующий код (перед вызовом client.close()).

    User maxaxam = new User(
        "1",
        "maxaxam",
        "Axam",
        "Max",
        "maxaxam@contoso.com",
        "2.0",
        new ShippingPreference(
            1,
            "90 W 8th St",
            "",
            "New York",
            "NY",
            "10001",
            "USA"
        ),
        new ArrayList<OrderHistory>(Arrays.asList(
            new OrderHistory(
                "3",
                "1000",
                "08/17/2018",
                "52.49"
            )
        )),
        new ArrayList<CouponsUsed>(Arrays.asList(
            new CouponsUsed(
                "A7B89F"
            )
        ))
    );
    
    User nelapin = new User(
            "2",
            "nelapin",
            "Pindakova",
            "Nela",
            "nelapin@contoso.com",
            "8.50",
            new ShippingPreference(
                1,
                "505 NW 5th St",
                "",
                "New York",
                "NY",
                "10001",
                "USA"
            ),
            new ArrayList<OrderHistory>(Arrays.asList(
                new OrderHistory(
                    "4",
                    "1001",
                    "08/17/2018",
                    "105.89"
                )
            )),
            new ArrayList<CouponsUsed>(Arrays.asList(
                new CouponsUsed(
                    "Fall 2018"
                )
            ))
    );
    
    createUserDocumentsIfNotExist(new ArrayList<User>(Arrays.asList(maxaxam, nelapin)));
    
  4. Выполните сборку и запустите CosmosApp.java в интегрированной среде разработки или запустите программу в терминале:

    mvn clean package
    mvn exec:java -Dexec.mainClass="com.azure.cosmos.examples.mslearnbasicapp.CosmosApp"
    

    Терминал будет отображать выходные данные по мере того, как приложение будет создавать каждый новый документ пользователя.

    INFO: Database and container validation complete
    INFO: Creating User 1
    INFO: Creating User 2
    

    Вы также можете увидеть дополнительный текст, созданный средством ведения журнала, например метки времени.

Поздравляем! Вы создали первые данные в Azure Cosmos DB из приложения Java. Остановитесь на этом моменте и оцените то, что вы сделали.

В basicOperations доступно три новых действия:

  1. Создайте экземпляр maxaxamUser.
  2. Создайте экземпляр nelapinUser.
  3. Вызовите createUserDocumentsIfNotExist, передав maxaxam и nelapin в списке.

Вызов createUserDocumentsIfNotExist вставляет экземпляры User как элементы или документы в Azure Cosmos DB. В случае передачи экземпляров User в виде списка цель состоит в том, чтобы моделировать производительный метод для быстрого приема POJO в Azure Cosmos DB с задействованием минимальных вычислительных ресурсов. createUserDocumentsIfNotExist реализует эффективную асинхронную вставку списка POJO.

Предположим, что нашей целью является максимально увеличить количество запросов в секунду на поток. Для сравнения метод синхронизации для написания createUserDocumentsIfNotExist (игнорирование проверки readItem в течение некоторого времени) выполняет итерацию по каждому экземпляру User в users. Для каждого экземпляра Useru мы создадим блокирующий вызов к createItem:

container.createItem(u, new PartitionKey(u.getUserId()), new CosmosItemRequestOptions()).block(); // <= Note the .block() which loops until request response.

Этот стиль синхронизации реализует интуитивно понятный процесс: запрос на выдачу, ожидание ответа, выдача следующего запроса. Но createUserDocumentsIfNotExist не использует этот подход, так как блокирующие вызовы, по сути, занимают циклы ЦП во время ответа на запрос, что приведет к низкому числу запросов в секунду.

Вы можете решить эту проблему путем порождения нескольких потоков для выполнения параллельных вызовов запросов блокировки. Использование нескольких потоков ускоряет выполнение, но если ваша цель — экономия ресурсов потоков, это все равно приводит к их нерациональному использованию. Каждый поток повторяется во время отклика на запрос и не может выполнять другие задачи, что снижает количество запросов в секунду на поток.

По этой причине, а также для демонстрации эффективной вставки Java POJO мы предоставили асинхронный пример вставки документа. Поддержка асинхронной работы в пакете SDK Azure Cosmos DB для Java версии 4 реализована за счет Project Reactor, платформы приложений Java, которая предоставляет основанную на потоковой передаче декларативную модель программирования потоков данных для асинхронного программирования на основе событий. createDocumentsIfNotExist реализует асинхронное программирование Project Reactor.

В createUserDocumentsIfNotExistFlux.fromIterable(users) является фабричным методом Project Reactor. Он создает экземпляр Flux, который является источником асинхронных событий. В этом случае каждое асинхронное событие включает аргумент экземпляра User. Экземпляр Flux содержит два таких события: одно для maxaxam и одно для nelapin. Код в .flatMap( ... ).blockLast(); определяет конвейер последовательных операций для выполнения с событиями, выдаваемыми экземпляром Flux.

Одна из таких операций — createItem. Идея заключается в том, что этот конвейер практически идентичен синхронной реализации, за исключением того, что мы не выполняем блокировку для вызова createItem. В частности, вызов к blockLast()привязывается к собранному конвейеру, в результате чего Fluxасинхронно выдает свои два события. Затем конвейер в .flatMap( ... ).blockLast(); обрабатывает каждое из таких событий в псевдопараллельном режиме. Когда один запрос выдается и ожидает ответа, Project Reactor будет обрабатывать другие запросы в фоновом режиме, что является важным фактором для достижения наилучших результатов для запросов в секунду на поток.

Теперь, когда мы продемонстрировали эффективные асинхронные запросы к базе данных с помощью Project Reactor, для простоты дальше мы будем использовать блокирующие (синхронные) вызовы. Дополнительные сведения о Project Reactor см. в руководстве по шаблону Reactor для Azure Cosmos DB.

Чтение документов

  1. Для чтения документов из базы данных добавьте следующий метод в CosmosApp:

    /**
     * Take in a Java POJO argument, extract ID and partition key, and read the corresponding document from the container.
     * In this case the ID is the partition key.
     * @param user User POJO to pull ID and partition key from.
     */
    private static CosmosItemResponse<User> readUserDocument(final User user) {
        CosmosItemResponse<User> userReadResponse = null;
    
        try {
            userReadResponse = container.readItem(user.getId(), new PartitionKey(user.getUserId()), User.class).block();
            logger.info("Read user {}", user.getId());
        } catch (CosmosException de) {
            logger.error("Failed to read user {}", user.getId(), de);
        }
    
        return userReadResponse;
    }
    
  2. Скопируйте следующий код и вставьте его в конец метода basicOperations, после кода создания документа.

    readUserDocument(maxaxam);
    
  3. Выполните сборку и запустите CosmosApp.java в интегрированной среде разработки или запустите программу в терминале:

    mvn clean package
    mvn exec:java -Dexec.mainClass="com.azure.cosmos.examples.mslearnbasicapp.CosmosApp"
    

    Терминал отображает следующие выходные данные, где текст Read user 1 означает, что документ извлечен.

    INFO: Database and container validation complete
    INFO: User 1 already exists in the database
    INFO: User 2 already exists in the database
    INFO: Read user 1
    

    Также может появиться дополнительный текст, созданный средством ведения журнала.

Замена документов

Azure Cosmos DB поддерживает замену документов JSON. В этом случае мы обновим запись пользователя, чтобы указать изменение фамилии.

  1. Добавьте метод replaceUserDocument после метода readUserDocument в файле CosmosApp.java.

    /**
     * Take in a Java POJO argument, extract ID and partition key,
     * and replace the existing document with the same ID and partition key to match.
     * @param user User POJO representing the document update.
     */
    private static void replaceUserDocument(final User user) {
        try {
            CosmosItemResponse<User> userReplaceResponse = container.replaceItem(user, user.getId(), new PartitionKey(user.getUserId())).block();
            logger.info("Replaced User {}", user.getId());
        } catch (CosmosException de) {
            logger.error("Failed to replace User {}", user.getUserId());
        }
    }
    
  2. Скопируйте следующий код и вставьте его в конец метода basicOperations, после кода чтения документа.

    maxaxam.setLastName("Suh");
    replaceUserDocument(maxaxam);
    
  3. Выполните сборку и запустите CosmosApp.java в интегрированной среде разработки или запустите программу в терминале:

    mvn clean package
    mvn exec:java -Dexec.mainClass="com.azure.cosmos.examples.mslearnbasicapp.CosmosApp"
    

    В окне терминала отобразятся следующие выходные данные, где текст Replaced last name for Suh означает, что документ был заменен.

    INFO: Database and container validation complete
    INFO: User 1 already exists in the database
    INFO: User 2 already exists in the database
    INFO: Read user 1
    INFO: Replaced last name for Suh
    

Удаление документов

  1. Скопируйте и вставьте метод deleteUserDocument под методом replaceUserDocument.

    /**
     * Take in a Java POJO argument, extract ID and partition key,
     * and delete the corresponding document.
     * @param user User POJO representing the document update.
     */
    private static void deleteUserDocument(final User user) {
        try {
            container.deleteItem(user.getId(), new PartitionKey(user.getUserId())).block();
            logger.info("Deleted user {}", user.getId());
        } catch (CosmosException de) {
            logger.error("User {} could not be deleted.", user.getId());
        }
    }
    
  2. Скопируйте следующий код и вставьте его в конец метода basicOperations.

    deleteUserDocument(maxaxam);
    
  3. Выполните сборку и запустите CosmosApp.java в интегрированной среде разработки или запустите программу в терминале:

    mvn clean package
    mvn exec:java -Dexec.mainClass="com.azure.cosmos.examples.mslearnbasicapp.CosmosApp"
    

    Терминал отображает следующие выходные данные, где текст Deleted user 1 означает, что документ был удален.

    INFO: Database and container validation complete
    INFO: User 1 already exists in the database
    INFO: User 2 already exists in the database
    INFO: Read User 1
    INFO: Replaced last name for Suh
    INFO: Deleted User 1
    

Работа с документами программным способом

Данные хранятся в Azure Cosmos DB в виде документов JSON. Документы можно создавать, извлекать, заменять или удалять на портале или программными средствами. В этом задании основное внимание уделяется программным операциям. Все эти операции доступны в пакете SDK Azure Cosmos DB для Java, а также в модели программирования Spring Data. В этом модуле показано, как использовать Spring Data Azure Cosmos DB для выполнения операций CRUD (создание, получение, обновление и удаление) с данными NoSQL, хранимыми в Azure Cosmos DB.

Основные операции для документов Spring Data Azure Cosmos DB являются базовыми в модели программирования Spring Data:

  • save — запись или обновление документа, в зависимости от того, существует ли уже документ.
  • view — чтение документа.
  • delete — удаление документа.

Для выполнения любой из этих операций потребуются вспомогательные классы (классы POJO Java), которые представляют объекты, хранящиеся в базе данных. Так как мы работаем с базой данных пользователей в сети, необходимо использовать класс WebCustomer, представляющий сущности пользователей. Этот класс хранит основные данные, такие как имя, фамилия и идентификатор пользователя. (Идентификатор обязателен, так как это ключ секции для включения горизонтального масштабирования.)

Для каждого пользователя в сети указаны параметры доставки и купоны на скидку, поэтому вам потребуются типы данных ShippingPreference и CouponsUsed для представления этих сущностей. Наконец, у каждого пользователя в сети может быть неограниченный журнал заказов, поэтому необходимо иметь отдельные сущности OrderHistory с соответствующим классом POJO Java.

Перейдите в папку src/main/java/com/azure/cosmos/examples/springexamples. Вы увидите класс POJO WebCustomer. Теперь перейдите в папку common. Вы увидите несколько POJO: ShippingPreference, OrderHistory и CouponsUsed. Итак, мы предоставили все POJO сущностей и их вспомогательные классы.

Далее предстоит создать несколько сущностей и выполнить некоторые базовые операции CRUD в контейнере Azure Cosmos DB и содержащихся в нем документах. Вы можете передать в Azure Cosmos DB экземпляр Jackson ObjectNode, который непосредственно определяет документ JSON. Но Azure Cosmos DB также может сериализовать POJO Java в JSON, и мы рекомендуем использовать этот подход как простейший вариант.

Создание и обновление документов

  1. Откройте файл WebCustomer.java и изучите его содержимое. Должно отобразиться примерно следующее:

    // Copyright (c) Microsoft Corporation. All rights reserved.
    // Licensed under the MIT License.
    package com.azure.cosmos.examples.springexamples;
    
    import com.azure.cosmos.examples.springexamples.common.CouponsUsed;
    import com.azure.cosmos.examples.springexamples.common.OrderHistory;
    import com.azure.cosmos.examples.springexamples.common.ShippingPreference;
    import com.azure.spring.data.cosmos.core.mapping.Container;
    import com.azure.spring.data.cosmos.core.mapping.PartitionKey;
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    import java.util.List;
    
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Container(containerName = "WebCustomer", ru = "400")
    public class WebCustomer {
    
        /** Document ID (required by Azure Cosmos DB). */
        private String id;
    
        /** WebCustomer ID. */
        private String userId;
    
        /** WebCustomer last name. */
        @PartitionKey
        private String lastName;
    
        /** WebCustomer first name. */
        private String firstName;
    
        /** WebCustomer email address. */
        private String email;
    
        /** WebCustomer dividend setting. */
        private String dividend;
    
        /** WebCustomer shipping preferences. */
        private ShippingPreference shippingPreference;
    
        /** WebCustomer order history. */
        private List<OrderHistory> orderHistory;
    
        /** Coupons recorded by the user. */
        private List<CouponsUsed> coupons;
    }
    

    Обратите внимание, что методы доступа для полей id, userId и т. д. являются неявными (не определены в коде). Такое поведение возможно, так как для их автоматического создания используется аннотация Project Lombok @Data.

    Аннотация @NoArgsConstructor вызывает создание конструктора без аргументов, который задает значения полей по умолчанию. Аннотация @AllArgsConstructor вызывает создание другого конструктора с полным набором аргументов для непосредственного определения всех значений полей.

    Обратите внимание, что WebCustomer имеет свойство id. Для всех документов Azure Cosmos DB требуется свойство id, поэтому все POJO, которые планируется сериализовать в документы JSON, должны иметь поле id.

  2. Добавьте следующий метод в CosmosSample.java:

    /**
     * Take in list of Java POJOs and insert them into the database.
     * @param webCustomers List of WebCustomer POJOs to insert.
     */
    private void createWebCustomerDocumentsIfNotExist(final List<WebCustomer> webCustomers) {
        Flux.fromIterable(webCustomers).flatMap(webCustomer -> {
            logger.info("Creating WebCustomer {}", webCustomer.getId());
            return this.reactiveWebCustomerRepository.save(webCustomer);
        }).blockLast();
    }
    
  3. Найдите метод run и добавьте в его конец следующий код.

    WebCustomer maxaxam = new WebCustomer(
            "1",
            "maxaxam",
            "Axam",
            "Max",
            "maxaxam@contoso.com",
            "2.0",
            new ShippingPreference(
                    1,
                    "90 W 8th St",
                    "",
                    "New York",
                    "NY",
                    "10001",
                    "USA"
            ),
            new ArrayList<OrderHistory>(Arrays.asList(
                    new OrderHistory(
                            "3",
                            "1000",
                            "08/17/2018",
                            "52.49"
                    )
            )),
            new ArrayList<CouponsUsed>(Arrays.asList(
                    new CouponsUsed(
                            "A7B89F"
                    )
            ))
    );
    
    WebCustomer nelapin = new WebCustomer(
            "2",
            "nelapin",
            "Pindakova",
            "Nela",
            "nelapin@contoso.com",
            "8.50",
            new ShippingPreference(
                    1,
                    "505 NW 5th St",
                    "",
                    "New York",
                    "NY",
                    "10001",
                    "USA"
            ),
            new ArrayList<OrderHistory>(Arrays.asList(
                    new OrderHistory(
                            "4",
                            "1001",
                            "08/17/2018",
                            "105.89"
                    )
            )),
            new ArrayList<CouponsUsed>(Arrays.asList(
                    new CouponsUsed(
                            "Fall 2018"
                    )
            ))
    );
    
    createWebCustomerDocumentsIfNotExist(new ArrayList(Arrays.asList(maxaxam, nelapin)));
    
  4. Выполните сборку и запустите CosmosSample.java в интегрированной среде разработки или запустите программу в терминале:

    mvn clean package
    mvn spring-boot:run
    

    Среди прочих выходных данных терминала вы увидите следующее:

    INFO: Creating WebCustomer 1
    INFO: Creating WebCustomer 2
    

Поздравляем! Вы создали и (или) обновили первые данные в Azure Cosmos DB из приложения Java. Остановитесь на этом моменте и оцените то, что вы сделали.

В run доступно три новых действия:

  1. Создайте или обновите экземпляр maxaxamWebCustomer.
  2. Создайте или обновите экземпляр nelapinWebCustomer.
  3. Вызовите createWebCustomerDocumentsIfNotExist, передав maxaxam и nelapin в списке.

Вызов createWebCustomerDocumentsIfNotExist вставляет экземпляры WebCustomer как элементы или документы в Azure Cosmos DB. В случае передачи экземпляров WebCustomer в виде списка цель состоит в том, чтобы моделировать производительный метод для быстрого приема POJO в Azure Cosmos DB с задействованием минимальных вычислительных ресурсов. createWebCustomerDocumentsIfNotExist реализует эффективную асинхронную вставку списка POJO. Если документ уже существует, вместо создания документа save выполнит обновление.

Предположим, что нашей целью является максимально увеличить количество запросов в секунду на поток. Для сравнения метод синхронизации для написания createWebCustomerDocumentsIfNotExist выполняет итерацию по каждому экземпляру WebCustomer в webCustomers. Для каждого экземпляра WebCustomerwebCustomer мы создадим блокирующий вызов к save:

this.reactiveWebCustomerRepository.save(webCustomer).block(); // <= Note the .block() which loops until request response.

Этот стиль синхронизации реализует интуитивно понятный процесс: запрос на выдачу, ожидание ответа, выдача следующего запроса. Но createWebCustomerDocumentsIfNotExist не использует этот подход, так как блокирующие вызовы, по сути, занимают циклы ЦП во время ответа на запрос, что приведет к низкому числу запросов в секунду.

Вы можете решить эту проблему путем порождения нескольких потоков для выполнения параллельных вызовов запросов блокировки. Использование нескольких потоков ускоряет выполнение, но если ваша цель — экономия ресурсов потоков, это все равно приводит к их нерациональному использованию. Каждый поток повторяется во время отклика на запрос и не может выполнять другие задачи, что снижает количество запросов в секунду на поток.

По этой причине, а также для демонстрации эффективной вставки Java POJO мы предоставили асинхронный пример вставки документа. Поддержка асинхронной работы Spring Data реализована за счет Project Reactor, платформы приложений Java, которая предоставляет основанную на потоковой передаче декларативную модель программирования потоков данных для асинхронного программирования на основе событий. createWebCustomerDocumentsIfNotExist реализует асинхронное программирование Project Reactor.

В createWebCustomerDocumentsIfNotExistFlux.fromIterable(webCustomers) является фабричным методом Project Reactor. Он создает экземпляр Flux, который является источником асинхронных событий. В этом случае каждое асинхронное событие включает аргумент экземпляра WebCustomer. Экземпляр Flux содержит два таких события: одно для maxaxam и одно для nelapin. Код в .flatMap( ... ).blockLast(); определяет конвейер последовательных операций для выполнения с событиями, выдаваемыми экземпляром Flux.

В этом случае две операции в конвейере являются вызовами save. Идея заключается в том, что этот конвейер практически идентичен синхронной реализации, за исключением того, что мы не выполняем блокировку для вызова save. В частности, вызов к blockLast()привязывается к собранному конвейеру, в результате чего Fluxасинхронно выдает свои два события. Затем конвейер в .flatMap( ... ).blockLast(); обрабатывает каждое из таких событий в псевдопараллельном режиме. Когда один запрос выдается и ожидает ответа, Project Reactor будет обрабатывать другие запросы в фоновом режиме, что является важным фактором для достижения наилучших результатов для запросов в секунду на поток.

Теперь, когда мы продемонстрировали эффективные асинхронные запросы к базе данных с помощью Project Reactor, для простоты дальше мы будем использовать блокирующие асинхронные (фактически синхронные) вызовы. Дополнительные сведения о Project Reactor см. в руководстве по шаблону Reactor для Azure Cosmos DB.

Чтение документов

  1. Для чтения документов из базы данных добавьте следующий метод в CosmosSample:

    /**
     * Take in a Java POJO argument, extract ID and partition key, and read the corresponding document from the container.
     * In this case the ID is the partition key.
     * @param webCustomer User POJO to pull ID and partition key from.
     */
    private WebCustomer readWebCustomerDocument(final WebCustomer webCustomer) {
        WebCustomer webCustomerResult = null;
    
        try {
            logger.info("Read webCustomer {}", webCustomer.getId());
            webCustomerResult = this.reactiveWebCustomerRepository.findById(webCustomer.getId(), new PartitionKey(webCustomer.getLastName())).block();
        } catch (CosmosException de) {
            logger.error("Failed to read webCustomer {}", webCustomer.getId(), de);
        }
    
        return webCustomer;
    }
    
  2. Скопируйте следующий код и вставьте его в конец метода run, после кода создания документа.

    readWebCustomerDocument(maxaxam);
    
  3. Выполните сборку и запустите CosmosSample.java в интегрированной среде разработки или запустите программу в терминале:

    mvn clean package
    mvn spring-boot:run
    

    Среди других выходных данных в терминале вы должны увидеть следующее: Read user 1 означает, что документ извлечен.

    INFO: Read webCustomer 1
    

Удаление документов

  1. Скопируйте и вставьте метод deleteWebCustomerDocument под методом readWebCustomerDocument.

    /**
     * Take in a Java POJO argument, extract ID and partition key,
     * and delete the corresponding document.
     * @param webCustomer User POJO representing the document update.
     */
    private void deleteWebCustomerDocument(final WebCustomer webCustomer) {
        try {
            this.reactiveWebCustomerRepository.deleteById(webCustomer.getId(),new PartitionKey(webCustomer.getLastName())).block();
            logger.info("Deleted webCustomer {}", webCustomer.getId());
        } catch (CosmosException de) {
            logger.error("User {} could not be deleted.", webCustomer.getId());
        }
    }
    
  2. Скопируйте следующий код и вставьте его в конец метода run.

    deleteWebCustomerDocument(maxaxam);
    
  3. Выполните сборку и запустите CosmosSample.java в интегрированной среде разработки или запустите программу в терминале:

    mvn clean package
    mvn spring-boot:run
    

    Среди других выходных данных в терминале вы должны увидеть следующее: Deleted user 1 означает, что документ был удален.

    INFO: Deleted webCustomer 1
    

В этом уроке показано, как создавать, обновлять, читать и удалять документы в базе данных Azure Cosmos DB.