Рубрики
Без рубрики

Реактивные репозитории данных Spring с MongoDB

Узнайте, как вы можете использовать реактивные репозитории Spring с MongoDB в конце сохранения

Автор оригинала: baeldung.

1. введение

В этом уроке мы рассмотрим, как настроить и реализовать операции с базами данных с помощью реактивного программирования через реактивные хранилища данных Spring с помощью MongoDB.

Мы рассмотрим основные способы использования Reactive Crud Repository, Reactive Mongo Repository , , а также ReactiveMongoTemplate.

Несмотря на то , что эти реализации используют реактивное программирование, это не является основным направлением данного руководства.

2. Окружающая среда

Чтобы использовать реактивный MongoDB, нам нужно добавить зависимость в ваш pom.xml.

Мы также добавим встроенный MongoDB для тестирования:


    // ...
    
        org.springframework.boot
        spring-boot-starter-data-mongodb-reactive
    
    
        de.flapdoodle.embed
        de.flapdoodle.embed.mongo
        test
    

3. Конфигурация

Чтобы активировать реактивную поддержку, нам нужно использовать @EnableReactiveMongoRepositories наряду с некоторыми настройками инфраструктуры:

@EnableReactiveMongoRepositories
public class MongoReactiveApplication
  extends AbstractReactiveMongoConfiguration {

    @Bean
    public MongoClient mongoClient() {
        return MongoClients.create();
    }

    @Override
    protected String getDatabaseName() {
        return "reactive";
    }
}

Обратите внимание, что вышесказанное было бы необходимо, если бы мы использовали автономную установку MongoDB. Но, поскольку в нашем примере мы используем Spring Boot со встроенным MongoDB, приведенная выше конфигурация не требуется.

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

Для приведенных ниже примеров давайте создадим класс Account и аннотируем его с помощью @Document , чтобы использовать его в операциях с базой данных:

@Document
public class Account {
 
    @Id
    private String id;
    private String owner;
    private Double value;
 
    // getters and setters
}

5. Использование реактивных Репозиториев

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

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

5.1. Реактивная грубая репозиция

Мы можем использовать этот репозиторий так же, как блокирующий CrudRepository :

@Repository
public interface AccountCrudRepository 
  extends ReactiveCrudRepository {
 
    Flux findAllByValue(String value);
    Mono findFirstByOwner(Mono owner);
}

Мы можем передавать различные типы аргументов, такие как простые ( String ), обернутые ( Необязательные , Stream ) или реактивные ( Mono , Flux ), как мы видим в методе findFirstByOwner () .

5.2. Реактивный репозиторий Mongo

Существует также интерфейс Reactive Mongo Repository , который наследуется от Reactive CrudRepository и добавляет некоторые новые методы запросов:

@Repository
public interface AccountReactiveRepository 
  extends ReactiveMongoRepository { }

Используя репозиторий Reactive Mongo , мы можем запросить пример:

Flux accountFlux = repository
  .findAll(Example.of(new Account(null, "owner", null)));

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

С созданием наших репозиториев у них уже есть определенные методы для выполнения некоторых операций с базой данных, которые нам не нужно реализовывать:

Mono accountMono 
  = repository.save(new Account(null, "owner", 12.3));
Mono accountMono2 = repository
  .findById("123456");

5.3. RxJava2CrudRepository

С RxJava2CrudRepository, мы имеем то же поведение, что и с Реактивным CrudRepository, но с результатами и типами параметров из RxJava :

@Repository
public interface AccountRxJavaRepository 
  extends RxJava2CrudRepository {
 
    Observable findAllByValue(Double value);
    Single findFirstByOwner(Single owner);
}

5.4. Тестирование Наших Основных Операций

Чтобы протестировать наши методы репозитория, мы будем использовать тестовый подписчик:

@Test
public void givenValue_whenFindAllByValue_thenFindAccount() {
    repository.save(new Account(null, "Bill", 12.3)).block();
    Flux accountFlux = repository.findAllByValue(12.3);

    StepVerifier
      .create(accountFlux)
      .assertNext(account -> {
          assertEquals("Bill", account.getOwner());
          assertEquals(Double.valueOf(12.3) , account.getValue());
          assertNotNull(account.getId());
      })
      .expectComplete()
      .verify();
}

@Test
public void givenOwner_whenFindFirstByOwner_thenFindAccount() {
    repository.save(new Account(null, "Bill", 12.3)).block();
    Mono accountMono = repository
      .findFirstByOwner(Mono.just("Bill"));

    StepVerifier
      .create(accountMono)
      .assertNext(account -> {
          assertEquals("Bill", account.getOwner());
          assertEquals(Double.valueOf(12.3) , account.getValue());
          assertNotNull(account.getId());
      })
      .expectComplete()
      .verify();
}

@Test
public void givenAccount_whenSave_thenSaveAccount() {
    Mono accountMono = repository.save(new Account(null, "Bill", 12.3));

    StepVerifier
      .create(accountMono)
      .assertNext(account -> assertNotNull(account.getId()))
      .expectComplete()
      .verify();
}

6. Шаблон ReactiveMongo

Помимо подхода к репозиториям, у нас есть шаблон ReactiveMongo .

Прежде всего, нам нужно зарегистрировать Шаблон ReactiveMongo в качестве боба:

@Configuration
public class ReactiveMongoConfig {
 
    @Autowired
    MongoClient mongoClient;

    @Bean
    public ReactiveMongoTemplate reactiveMongoTemplate() {
        return new ReactiveMongoTemplate(mongoClient, "test");
    }
}

А затем мы можем внедрить этот компонент в наш сервис для выполнения операций с базой данных:

@Service
public class AccountTemplateOperations {
 
    @Autowired
    ReactiveMongoTemplate template;

    public Mono findById(String id) {
        return template.findById(id, Account.class);
    }
 
    public Flux findAll() {
        return template.findAll(Account.class);
    } 
    public Mono save(Mono account) {
        return template.save(account);
    }
}

Шаблон ReactiveMongo также имеет ряд методов, которые не относятся к нашему домену, вы можете проверить их в документации .

7. Заключение

В этом кратком руководстве мы рассмотрели использование репозиториев и шаблонов с использованием реактивного программирования с помощью MongoDB с помощью Spring Data Reactive Repositories framework.

Полный исходный код примеров доступен на GitHub .