Spring Data Reactive Repositories mit MongoDB

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.