MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Repozytoria Spring Data Reactive z MongoDB

1. Wprowadzenie

W tym samouczku zobaczymy, jak skonfigurować i zaimplementować operacje na bazie danych za pomocą programowania reaktywnego za pomocą repozytoriów reaktywnych Spring Data z MongoDB.

Omówimy podstawowe zastosowania ReactiveCrud Repozytorium, Reaktywne MongoRepository , a także ReactiveMongoTemplate.

Mimo że te implementacje wykorzystują programowanie reaktywne, nie jest to główny cel tego samouczka.

2. Środowisko

Aby używać Reactive MongoDB, musimy dodać zależność do naszego pom.xml.

Dodamy również do testów osadzoną bazę danych MongoDB:

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

Aby aktywować wsparcie reaktywne, musimy użyć @EnableReactiveMongoRepositories wraz z konfiguracją infrastruktury:

@EnableReactiveMongoRepositories
public class MongoReactiveApplication
  extends AbstractReactiveMongoConfiguration {

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

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

Zauważ, że powyższe byłoby konieczne, gdybyśmy korzystali z samodzielnej instalacji MongoDB. Ale ponieważ w naszym przykładzie używamy Spring Boot z osadzoną bazą danych MongoDB, powyższa konfiguracja nie jest konieczna.

4. Tworzenie Dokumentu

W poniższych przykładach utwórzmy konto klasę i dodaj do niej adnotację @Document aby użyć go w operacjach na bazie danych:

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

5. Korzystanie z repozytoriów reaktywnych

Znamy już model programowania repozytoriów, ze zdefiniowanymi już metodami CRUD oraz obsługą kilku innych typowych rzeczy.

Teraz dzięki modelowi reaktywnemu otrzymujemy ten sam zestaw metod i specyfikacji, z wyjątkiem tego, że z wynikami i parametrami zajmiemy się w sposób reaktywny.

5.1. ReactiveCrudRepository

Możemy używać tego repozytorium w taki sam sposób, jak blokującego CrudRepository :

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

Możemy przekazywać różne typy argumentów, takie jak zwykły (Ciąg ), opakowane (Opcjonalne , Strumień ) lub reaktywny (Mono , strumień ), jak widzimy w findFirstByOwner() metoda.

5.2. Reaktywne MongoRepository

Jest też ReactiveMongoRepository interfejs, który dziedziczy z ReactiveCrudRepository i dodaje kilka nowych metod zapytań:

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

Korzystanie z ReactiveMongoRepository , możemy zapytać na przykład:

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

W rezultacie otrzymamy każde konto to jest to samo, co podany przykład.

Po utworzeniu naszych repozytoriów mają już zdefiniowane metody wykonywania niektórych operacji na bazach danych, których nie musimy wdrażać:

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

5.3. RxJava2CrudRepository

Dzięki RxJava2CrudRepository zachowujemy się tak samo jak ReactiveCrudRepository, ale z wynikami i typami parametrów z RxJava :

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

5.4. Testowanie naszych podstawowych operacji

Aby przetestować nasze metody repozytorium, użyjemy subskrybenta testowego:

@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. Reaktywny szablon Mongo

Oprócz podejścia opartego na repozytoriach, mamy ReactiveMongoTemplate .

Przede wszystkim musimy się zarejestrować ReactiveMongoTemplate jako fasola:

@Configuration
public class ReactiveMongoConfig {
 
    @Autowired
    MongoClient mongoClient;

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

A następnie możemy wstrzyknąć ten bean do naszej usługi, aby wykonać operacje na bazie danych:

@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);
    }
}

Reaktywny szablon Mongo ma również wiele metod, które nie są związane z domeną, którą posiadamy, możesz je sprawdzić w dokumentacji.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Jak wyszukiwać różne wartości w Mongoose?

  2. Właściwy sposób importowania pliku json do mongo

  3. Jak stworzyć użytkownika w mongodb za pomocą docker-compose

  4. Mongoose dodaje wiele obiektów do tablicy, jeśli nie istnieje na podstawie

  5. Jak zapobiegać wycofywaniu zmian w MongoDB?