sql >> Database >  >> NoSQL >> MongoDB

Spring Data Reactive Repositories met MongoDB

1. Inleiding

In deze zelfstudie gaan we zien hoe databasebewerkingen kunnen worden geconfigureerd en geïmplementeerd met behulp van Reactive Programming via Spring Data Reactive Repositories met MongoDB.

We bespreken het basisgebruik van ReactiveCrud Repository, ReactiveMongoRepository , evenals ReactiveMongoTemplate.

Hoewel deze implementaties reactieve programmering gebruiken, is dat niet de primaire focus van deze tutorial.

2. Omgeving

Om Reactive MongoDB te gebruiken, moeten we de afhankelijkheid toevoegen aan onze pom.xml.

We voegen ook een ingesloten MongoDB toe om te testen:

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

Om de reactieve ondersteuning te activeren, moeten we de @EnableReactiveMongoRepositories gebruiken samen met wat infrastructuurconfiguratie:

@EnableReactiveMongoRepositories
public class MongoReactiveApplication
  extends AbstractReactiveMongoConfiguration {

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

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

Merk op dat het bovenstaande nodig zou zijn als we de zelfstandige MongoDB-installatie zouden gebruiken. Maar aangezien we Spring Boot gebruiken met geïntegreerde MongoDB in ons voorbeeld, is de bovenstaande configuratie niet nodig.

4. Een Document maken

Laten we voor de onderstaande voorbeelden een Account maken class en annoteer het met @Document om het te gebruiken in de databasebewerkingen:

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

5. Reactieve opslagplaatsen gebruiken

We zijn al bekend met het repositories-programmeermodel, met de CRUD-methoden die al zijn gedefinieerd, plus ondersteuning voor een aantal andere veelvoorkomende dingen.

Met het Reactive-model krijgen we nu dezelfde set methoden en specificaties, behalve dat we de resultaten en parameters op een reactieve manier behandelen.

5.1. ReactiveCrudRepository

We kunnen deze repository op dezelfde manier gebruiken als de blokkerende CrudRepository :

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

We kunnen verschillende soorten argumenten doorgeven, zoals gewoon (String ), verpakt (Optioneel , Streamen ), of reactief (Mono , Flux ) zoals we kunnen zien in de findFirstByOwner() methode.

5.2. ReactiveMongoRepository

Er is ook de ReactiveMongoRepository interface, die erft van ReactiveCrudRepository en voegt enkele nieuwe zoekmethoden toe:

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

De ReactiveMongoRepository gebruiken , we kunnen bijvoorbeeld vragen:

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

Als resultaat krijgen we elk account dat is hetzelfde als het doorgegeven voorbeeld.

Nu onze repositories zijn gemaakt, hebben ze al gedefinieerde methoden om sommige databasebewerkingen uit te voeren die we niet hoeven te implementeren:

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

5.3. RxJava2CrudRepository

Met RxJava2CrudRepository, we hebben hetzelfde gedrag als de ReactiveCrudRepository, maar met de resultaten en parametertypes van RxJava :

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

5.4. Onze basisbewerkingen testen

Om onze repository-methoden te testen, gebruiken we de testabonnee:

@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

Naast de repositories-aanpak hebben we deReactiveMongoTemplate .

Allereerst moeten we ReactiveMongoTemplate . registreren als boon:

@Configuration
public class ReactiveMongoConfig {
 
    @Autowired
    MongoClient mongoClient;

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

En dan kunnen we deze boon in onze service injecteren om de databasebewerkingen uit te voeren:

@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 heeft ook een aantal methoden die niet gerelateerd zijn aan het domein dat we hebben, je kunt ze bekijken in de documentatie.


  1. Hoe installeer ik Predis op XAMPP-vensters?

  2. MongoDB sorteert documenten op array-elementen

  3. Grote gegevensworkflows met panda's

  4. find() en findOne() methoden in MongoDB met verschillende resultaten