1. Einführung
In diesem Lernprogramm erfahren Sie, wie Sie Datenbankoperationen mithilfe von reaktiver Programmierung über Spring Data Reactive Repositories mit MongoDB konfigurieren und implementieren.
Wir gehen die grundlegende Verwendung von ReactiveCrud durch Repository, ReactiveMongoRepository , sowie ReactiveMongoTemplate.
Obwohl diese Implementierungen reaktive Programmierung verwenden, ist dies nicht der Hauptfokus dieses Tutorials.
2. Umwelt
Um Reactive MongoDB zu verwenden, müssen wir die Abhängigkeit zu unserer pom.xml. hinzufügen
Wir werden auch eine eingebettete MongoDB zum Testen hinzufügen:
<dependencies>
// ...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
3. Konfiguration
Um die reaktive Unterstützung zu aktivieren, müssen wir die @EnableReactiveMongoRepositories verwenden zusammen mit einigen Infrastruktureinstellungen:
@EnableReactiveMongoRepositories
public class MongoReactiveApplication
extends AbstractReactiveMongoConfiguration {
@Bean
public MongoClient mongoClient() {
return MongoClients.create();
}
@Override
protected String getDatabaseName() {
return "reactive";
}
}
Beachten Sie, dass das Obige erforderlich wäre, wenn wir die eigenständige MongoDB-Installation verwenden würden. Da wir in unserem Beispiel jedoch Spring Boot mit eingebettetem MongoDB verwenden, ist die obige Konfiguration nicht erforderlich.
4. Erstellen eines Dokuments
Lassen Sie uns für die folgenden Beispiele ein Konto erstellen class und kommentieren Sie es mit @Document um es in den Datenbankoperationen zu verwenden:
@Document
public class Account {
@Id
private String id;
private String owner;
private Double value;
// getters and setters
}
5. Reaktive Repositories verwenden
Wir sind bereits mit dem Repository-Programmiermodell vertraut, mit den bereits definierten CRUD-Methoden und der Unterstützung einiger anderer allgemeiner Dinge.
Mit dem reaktiven Modell erhalten wir jetzt dieselben Methoden und Spezifikationen, außer dass wir die Ergebnisse und Parameter auf reaktive Weise behandeln.
5.1. ReactiveCrudRepository
Wir können dieses Repository genauso verwenden wie das blockierende CrudRepository :
@Repository
public interface AccountCrudRepository
extends ReactiveCrudRepository<Account, String> {
Flux<Account> findAllByValue(String value);
Mono<Account> findFirstByOwner(Mono<String> owner);
}
Wir können verschiedene Arten von Argumenten übergeben, z. B. einfach (String ), verpackt (Optional , Streamen ) oder reaktiv (Mono , Fluss ), wie wir in findFirstByOwner() sehen können Methode.
5.2. ReactiveMongoRepository
Es gibt auch das ReactiveMongoRepository Schnittstelle, die von ReactiveCrudRepository erbt und fügt einige neue Abfragemethoden hinzu:
@Repository
public interface AccountReactiveRepository
extends ReactiveMongoRepository<Account, String> { }
Verwenden des ReactiveMongoRepository , können wir beispielsweise abfragen:
Flux<Account> accountFlux = repository
.findAll(Example.of(new Account(null, "owner", null)));
Als Ergebnis erhalten wir jedes Konto das ist dasselbe wie im übergebenen Beispiel.
Nachdem unsere Repositories erstellt wurden, haben sie bereits Methoden definiert, um einige Datenbankoperationen durchzuführen, die wir nicht implementieren müssen:
Mono<Account> accountMono
= repository.save(new Account(null, "owner", 12.3));
Mono<Account> accountMono2 = repository
.findById("123456");
5.3. RxJava2CrudRepository
Mit RxJava2CrudRepository, wir haben das gleiche Verhalten wie das ReactiveCrudRepository, aber mit den Ergebnissen und Parametertypen von RxJava :
@Repository
public interface AccountRxJavaRepository
extends RxJava2CrudRepository<Account, String> {
Observable<Account> findAllByValue(Double value);
Single<Account> findFirstByOwner(Single<String> owner);
}
5.4. Testen unserer grundlegenden Operationen
Um unsere Repository-Methoden zu testen, verwenden wir den Test-Subscriber:
@Test
public void givenValue_whenFindAllByValue_thenFindAccount() {
repository.save(new Account(null, "Bill", 12.3)).block();
Flux<Account> 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<Account> 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<Account> accountMono = repository.save(new Account(null, "Bill", 12.3));
StepVerifier
.create(accountMono)
.assertNext(account -> assertNotNull(account.getId()))
.expectComplete()
.verify();
}
6. ReactiveMongoTemplate
Neben dem Repositories-Ansatz haben wir das ReactiveMongoTemplate .
Zuerst müssen wir ReactiveMongoTemplate registrieren als Bohne:
@Configuration
public class ReactiveMongoConfig {
@Autowired
MongoClient mongoClient;
@Bean
public ReactiveMongoTemplate reactiveMongoTemplate() {
return new ReactiveMongoTemplate(mongoClient, "test");
}
}
Und dann können wir diese Bean in unseren Dienst einfügen, um die Datenbankoperationen auszuführen:
@Service
public class AccountTemplateOperations {
@Autowired
ReactiveMongoTemplate template;
public Mono<Account> findById(String id) {
return template.findById(id, Account.class);
}
public Flux<Account> findAll() {
return template.findAll(Account.class);
}
public Mono<Account> save(Mono<Account> account) {
return template.save(account);
}
}
ReactiveMongoTemplate hat auch eine Reihe von Methoden, die sich nicht auf die Domäne beziehen, die wir haben, Sie können sie in der Dokumentation nachlesen.