sql >> Databáze >  >> NoSQL >> MongoDB

Spring Data Reactive Repository s MongoDB

1. Úvod

V tomto tutoriálu se podíváme na to, jak nakonfigurovat a implementovat databázové operace pomocí reaktivního programování prostřednictvím Spring Data Reactive Repositories s MongoDB.

Projdeme si základní použití ReactiveCrud Úložiště, ReactiveMongoRepository , a také ReactiveMongoTemplate.

I když tyto implementace používají reaktivní programování, není to hlavním cílem tohoto tutoriálu.

2. Prostředí

Abychom mohli používat Reactive MongoDB, musíme přidat závislost do našeho pom.xml.

Přidáme také vložený MongoDB pro testování:

<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. Konfigurace

Abychom aktivovali reaktivní podporu, musíme použít @EnableReactiveMongoRepositories spolu s nastavením infrastruktury:

@EnableReactiveMongoRepositories
public class MongoReactiveApplication
  extends AbstractReactiveMongoConfiguration {

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

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

Všimněte si, že výše uvedené by bylo nutné, pokud bychom používali samostatnou instalaci MongoDB. Ale protože v našem příkladu používáme Spring Boot s vloženým MongoDB, výše uvedená konfigurace není nutná.

4. Vytvoření dokumentu

Pro příklady níže si vytvořte účet třídy a označte jej pomocí @Document pro použití v databázových operacích:

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

5. Používání reaktivních repozitářů

Již jsme obeznámeni s modelem programování repozitářů, s již definovanými metodami CRUD plus podporou některých dalších běžných věcí.

Nyní s modelem Reactive získáme stejnou sadu metod a specifikací, kromě toho, že s výsledky a parametry budeme pracovat reaktivním způsobem.

5.1. ReactiveCrudRepository

Toto úložiště můžeme použít stejným způsobem jako blokovací CrudRepository :

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

Můžeme předávat různé typy argumentů, jako je prostý (String ), zabalené (Volitelné , Stream ), nebo reaktivní (Mono , Flux ), jak můžeme vidět v findFirstByOwner() metoda.

5.2. ReactiveMongoRepository

K dispozici je také ReactiveMongoRepository rozhraní, které dědí z ReactiveCrudRepository a přidává některé nové metody dotazu:

@Repository
public interface AccountReactiveRepository 
  extends ReactiveMongoRepository<Account, String> { }

Pomocí ReactiveMongoRepository , můžeme se zeptat například:

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

V důsledku toho získáme každý účet to je stejné jako v předchozím příkladu.

S našimi vytvořenými repozitáři již mají definované metody pro provádění některých databázových operací, které nemusíme implementovat:

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

5.3. RxJava2CrudRepository

S RxJava2CrudRepository máme stejné chování jako ReactiveCrudRepository ale s výsledky a typy parametrů z RxJava :

@Repository
public interface AccountRxJavaRepository 
  extends RxJava2CrudRepository<Account, String> {
 
    Observable<Account> findAllByValue(Double value);
    Single<Account> findFirstByOwner(Single<String> owner);
}

5.4. Testování našich základních operací

Abychom otestovali naše metody úložiště, použijeme testovacího předplatitele:

@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

Kromě přístupu repozitářů mámeReactiveMongoTemplate .

Nejprve se musíme zaregistrovat ReactiveMongoTemplate jako fazole:

@Configuration
public class ReactiveMongoConfig {
 
    @Autowired
    MongoClient mongoClient;

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

A pak můžeme vložit tento bean do naší služby, abychom provedli databázové operace:

@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 má také řadu metod, které se nevztahují k naší doméně, můžete si je ověřit v dokumentaci.


  1. Umístění v mongoose, mongoDB

  2. Chyba při spouštění skriptu Lua z klienta redis

  3. Vložený dokument vs reference v designovém modelu mongoose?

  4. Geoprostorová podpora v MongoDB