Reaktive Spring-Datenrepositorys mit MongoDB
1. Einführung
In diesem Tutorial erfahren Sie, wie Sie Datenbankoperationen mithilfe der reaktiven Programmierung über Spring Data Reactive Repositories mit MongoDB konfigurieren und implementieren.
Wir werden die grundlegenden Verwendungen vonReactiveCrudRepository,ReactiveMongoRepository, sowieReactiveMongoTemplate. durchgehen
Obwohl diese Implementierungenreactive programming verwenden, ist dies nicht der Hauptfokus dieses Tutorials.
2. Umgebung
Um Reactive MongoDB verwenden zu können, müssen wir die Abhängigkeit zu unserenpom.xml. hinzufügen
Wir werden auch eine eingebettete MongoDB zum Testen hinzufügen:
// ...
org.springframework.boot
spring-boot-starter-data-mongodb-reactive
de.flapdoodle.embed
de.flapdoodle.embed.mongo
test
3. Aufbau
Um die reaktive Unterstützung zu aktivieren, müssen wir@EnableReactiveMongoRepositories zusammen mit einigen Infrastruktur-Setups verwenden:
@EnableReactiveMongoRepositories
public class MongoReactiveApplication
extends AbstractReactiveMongoConfiguration {
@Bean
public MongoClient mongoClient() {
return MongoClients.create();
}
@Override
protected String getDatabaseName() {
return "reactive";
}
}
Beachten Sie, dass dies erforderlich wäre, wenn Sie die eigenständige MongoDB-Installation verwenden würden. Da wir in unserem Beispiel Spring Boot mit eingebetteter MongoDB verwenden, ist die obige Konfiguration nicht erforderlich.
4. Document erstellen
In den folgenden Beispielen erstellen wir eineAccount-Klasse und kommentieren sie mit@Document, um sie in den Datenbankoperationen zu verwenden:
@Document
public class Account {
@Id
private String id;
private String owner;
private Double value;
// getters and setters
}
5. Reaktive Repositorys verwenden
Wir sind bereits mit denrepositories programming model vertraut, mit den bereits definierten CRUD-Methoden sowie der Unterstützung einiger anderer allgemeiner Dinge.
Mit dem reaktiven Modell erhalten wir jetzt die gleichen Methoden und Spezifikationen, außer dass wir die Ergebnisse und Parameter reaktiv behandeln.
5.1. ReactiveCrudRepository
Wir können dieses Repository genauso verwenden wie die blockierendenCrudRepository:
@Repository
public interface AccountCrudRepository
extends ReactiveCrudRepository {
Flux findAllByValue(String value);
Mono findFirstByOwner(Mono owner);
}
Wir können verschiedene Arten von Argumenten wie einfache (String), umschlossene (Optional,Stream) oder reaktive (Mono,Flux) übergeben, wie wir können siehe in derfindFirstByOwner() Methode.
5.2. ReactiveMongoRepository
Es gibt auch dieReactiveMongoRepository-Schnittstelle, die vonReactiveCrudRepository erbt und einige neue Abfragemethoden hinzufügt:
@Repository
public interface AccountReactiveRepository
extends ReactiveMongoRepository { }
MitReactiveMongoRepository können wir anhand eines Beispiels abfragen:
Flux accountFlux = repository
.findAll(Example.of(new Account(null, "owner", null)));
Als Ergebnis erhalten wir alleAccount, die dem übergebenen Beispiel entsprechen.
Mit unseren erstellten Repositorys haben sie bereits Methoden definiert, um einige Datenbankoperationen auszuführen, die wir nicht implementieren müssen:
Mono accountMono
= repository.save(new Account(null, "owner", 12.3));
Mono accountMono2 = repository
.findById("123456");
5.3. RxJava2CrudRepository
MitRxJava2CrudRepository, haben wir das gleiche Verhalten wie mitReactiveCrudRepository,, aber mit den Ergebnissen und Parametertypen vonRxJava:
@Repository
public interface AccountRxJavaRepository
extends RxJava2CrudRepository {
Observable findAllByValue(Double value);
Single findFirstByOwner(Single owner);
}
5.4. Testen unserer Grundfunktionen
Um unsere Repository-Methoden zu testen, verwenden wir den Testabonnenten:
@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. ReactiveMongoTemplate
Neben dem Ansatz der Repositorien haben wir dieReactiveMongoTemplate.
Zunächst müssen wirReactiveMongoTemplate als Bean registrieren:
@Configuration
public class ReactiveMongoConfig {
@Autowired
MongoClient mongoClient;
@Bean
public ReactiveMongoTemplate reactiveMongoTemplate() {
return new ReactiveMongoTemplate(mongoClient, "test");
}
}
Anschließend können wir diese Bean in unseren Service einfügen, um die Datenbankoperationen auszuführen:
@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);
}
}
ReactiveMongoTemplate hat auch eine Reihe von Methoden, die sich nicht auf die Domain beziehen, die wir haben. Sie können sie indocumentation überprüfen.
7. Fazit
In diesem kurzen Tutorial haben wir die Verwendung von Repositorys und Vorlagen mithilfe der reaktiven Programmierung mit MongoDB mit dem Spring Data Reactive Repositories-Framework behandelt.
Der vollständige Quellcode für die Beispiele istover on GitHub verfügbar.