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 , мы можем запросить пример:
FluxaccountFlux = repository .findAll(Example.of(new Account(null, "owner", null)));
В результате мы получим каждый Аккаунт , который совпадает с переданным примером.
С созданием наших репозиториев у них уже есть определенные методы для выполнения некоторых операций с базой данных, которые нам не нужно реализовывать:
MonoaccountMono = 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(); FluxaccountFlux = 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 MonofindById(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 .