MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Реактивни хранилища на Spring Data с MongoDB

1. Въведение

В този урок ще видим как да конфигурираме и прилагаме операции с база данни, използвайки реактивно програмиране чрез Spring Data Reactive Repositories с MongoDB.

Ще разгледаме основните употреби на ReactiveCrud Хранилище, ReactiveMongoRepository , както и ReactiveMongoTemplate.

Въпреки че тези реализации използват реактивно програмиране, това не е основният фокус на този урок.

2. Околна средата

За да използваме Reactive MongoDB, трябва да добавим зависимостта към нашия pom.xml.

Ще добавим и вграден 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. Конфигурацията

За да активираме реактивната поддръжка, трябва да използваме @EnableReactiveMongoRepositories заедно с някои настройки на инфраструктурата:

@EnableReactiveMongoRepositories
public class MongoReactiveApplication
  extends AbstractReactiveMongoConfiguration {

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

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

Имайте предвид, че горното би било необходимо, ако използвахме самостоятелната инсталация на MongoDB. Но тъй като използваме Spring Boot с вградена MongoDB в нашия пример, горната конфигурация не е необходима.

4. Създаване на Документ

За примерите по-долу, нека създадем Акаунт клас и го анотирайте с @Document за да го използвате в операциите с базата данни:

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

5. Използване на реактивни хранилища

Вече сме запознати с модела за програмиране на хранилища, с вече дефинираните CRUD методи плюс поддръжка за някои други често срещани неща.

Сега с реактивния модел получаваме същия набор от методи и спецификации, с изключение на това, че ще се справим с резултатите и параметрите по реактивен начин.

5.1. ReactiveCrudRepository

Можем да използваме това хранилище по същия начин като блокиращото CrudRepository :

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

Можем да предаваме различни типове аргументи като обикновен (String ), опакован (По избор , Поток ) или реактивен (Моно , Поток ), както можем да видим в findFirstByOwner() метод.

5.2. ReactiveMongoRepository

Има и ReactiveMongoRepository интерфейс, който наследява от ReactiveCrudRepository и добавя някои нови методи на заявка:

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

Използване на ReactiveMongoRepository , можем да правим заявка чрез пример:

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

В резултат на това ще получим всеки Профил това е същото като предания пример.

Със създадените ни хранилища те вече имат дефинирани методи за извършване на някои операции с база данни, които не е необходимо да прилагаме:

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

5.3. RxJava2CrudRepository

С RxJava2CrudRepository, имаме същото поведение като ReactiveCrudRepository, но с резултатите и типове параметри от RxJava :

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

5.4. Тестване на нашите основни операции

За да тестваме нашите методи за хранилище, ще използваме тестовия абонат:

@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

Освен подхода към хранилищата, имаме ReactiveMongoTemplate .

На първо място, трябва да регистрираме ReactiveMongoTemplate като боб:

@Configuration
public class ReactiveMongoConfig {
 
    @Autowired
    MongoClient mongoClient;

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

И след това можем да инжектираме този bean в нашата услуга, за да изпълняваме операциите с базата данни:

@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 също има редица методи, които не са свързани с домейна, който имаме, можете да ги проверите в документацията.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Как да използвате MongoRegex (драйвер MongoDB C#)

  2. Как да използвам агрегирането на MongoDB за пагинация?

  3. MongoDB използва клауза ИЛИ в mongoengine

  4. Как да задам стойност по подразбиране на цяло число в mongodb?

  5. Намаляване на размера на файла на базата данни MongoDB