sql >> Database teknologi >  >> NoSQL >> MongoDB

Spring Data Reactive Repositories med MongoDB

1. Introduktion

I denne øvelse skal vi se, hvordan du konfigurerer og implementerer databaseoperationer ved hjælp af Reactive Programming gennem Spring Data Reactive Repositories med MongoDB.

Vi gennemgår de grundlæggende anvendelser af ReactiveCrud Repository, ReactiveMongoRepository , samt ReactiveMongoTemplate.

Selvom disse implementeringer bruger reaktiv programmering, er det ikke det primære fokus i denne øvelse.

2. Miljø

For at bruge Reactive MongoDB skal vi tilføje afhængigheden til vores pom.xml.

Vi tilføjer også en indlejret MongoDB til test:

<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

For at aktivere den reaktive support skal vi bruge @EnableReactiveMongoRepositories sammen med nogle infrastrukturopsætninger:

@EnableReactiveMongoRepositories
public class MongoReactiveApplication
  extends AbstractReactiveMongoConfiguration {

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

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

Bemærk, at ovenstående ville være nødvendigt, hvis vi brugte den selvstændige MongoDB-installation. Men da vi bruger Spring Boot med embedded MongoDB i vores eksempel, er ovenstående konfiguration ikke nødvendig.

4. Oprettelse af et dokument

For eksemplerne nedenunder, lad os oprette en konto klasse og annoter den med @Document for at bruge det i databasehandlingerne:

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

5. Brug af reaktive lagre

Vi er allerede bekendt med repositories-programmeringsmodellen, med CRUD-metoderne allerede defineret plus understøttelse af nogle andre almindelige ting også.

Nu med den reaktive model får vi det samme sæt metoder og specifikationer, bortset fra at vi vil håndtere resultaterne og parametrene på en reaktiv måde.

5.1. ReactiveCrudRepository

Vi kan bruge dette lager på samme måde som det blokerende CrudRepository :

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

Vi kan sende forskellige typer argumenter som almindelig (String ), pakket ind (Valgfrit , Stream ), eller reaktiv (Mono , Flux ), som vi kan se i findFirstByOwner() metode.

5.2. ReactiveMongoRepository

Der er også ReactiveMongoRepository grænseflade, som arver fra ReactiveCrudRepository og tilføjer nogle nye forespørgselsmetoder:

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

Brug af ReactiveMongoRepository , kan vi forespørge ved eksempel:

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

Som et resultat heraf får vi hver konto det er det samme som eksemplet.

Med vores arkiver oprettet, har de allerede defineret metoder til at udføre nogle databaseoperationer, som vi ikke behøver at implementere:

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

5.3. RxJava2CrudRepository

Med RxJava2CrudRepository, vi har samme adfærd som ReactiveCrudRepository, men med resultaterne og parametertyperne fra RxJava :

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

5.4. Test af vores grundlæggende operationer

For at teste vores lagermetoder bruger vi testabonnenten:

@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

Udover repositories-tilgangen har viReactiveMongoTemplate .

Først og fremmest skal vi registrere ReactiveMongoTemplate som en bønne:

@Configuration
public class ReactiveMongoConfig {
 
    @Autowired
    MongoClient mongoClient;

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

Og så kan vi injicere denne bønne i vores tjeneste for at udføre databasehandlingerne:

@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 har også en række metoder som ikke relaterer til det domæne vi har, du kan tjekke dem ud i dokumentationen.


  1. Sådan får du Laravel til at fungere med Redis cluster på AWS

  2. Mongodb, sharding og flere Windows-tjenester

  3. Node JS Redis Client Connection Prøv igen

  4. Understøtter Spring Data Redis (1.3.2.RELEASE) JedisSentinelPool of jedis?