Автор оригинала: Rodrigo Graciano.
1. введение
R2DBC (Реактивное подключение к реляционным базам данных) – это проект, представленный компанией Pivotal во время весенней платформы One 2018. Он намерен создать реактивный API для баз данных SQL.
Другими словами, это усилие создает соединение с базой данных с использованием полностью неблокирующих драйверов.
В этом уроке мы рассмотрим пример приложения, использующего Spring Data R2BDC. Для получения руководства по более низкоуровневому R2 DBCAPI ознакомьтесь с нашей предыдущей статьей .
2. Наш Первый Весенний проект R2DBC с данными
Начнем с того, что проект R2DBC появился совсем недавно. На данный момент только PostGres, MSSQL и H2 имеют драйверы R2 ODBC. Кроме того, мы не можем использовать с ним все функции Spring Boot . Поэтому есть несколько шагов, которые нам нужно будет добавить вручную. Но мы можем использовать такие проекты, как Spring Data , чтобы помочь нам.
Сначала мы создадим проект Maven. На данный момент существует несколько проблем с зависимостями с R2DBC, поэтому ваш pom.xml будет больше, чем обычно.
В рамках этой статьи мы будем использовать H2 в качестве нашей базы данных и создадим реактивные функции CRUD для нашего приложения.
Давайте откроем pom.xml сгенерированного проекта и добавьте соответствующие зависимости, а также некоторые весенние репозитории ранних версий:
org.springframework.data spring-data-r2dbc 1.0.0.RELEASE io.r2dbc r2dbc-h2 0.8.1.RELEASE com.h2database h2 1.4.199
Другие необходимые артефакты включают Ломбок, |/Spring Web Flux и несколько других, которые дополняют ваш проект зависимости .
3. Фабрика Соединений
При работе с базой данных нам нужна фабрика соединений. Так что, конечно, нам понадобится то же самое с R2DBC.
Итак, теперь мы добавим детали для подключения к нашему экземпляру:
@Configuration @EnableR2dbcRepositories class R2DBCConfiguration extends AbstractR2dbcConfiguration { @Bean public H2ConnectionFactory connectionFactory() { return new H2ConnectionFactory( H2ConnectionConfiguration.builder() .url("mem:testdb;DB_CLOSE_DELAY=-1;") .username("sa") .build() ); } }
Первое, что мы замечаем в приведенном выше коде, – это @EnableR2dbcRepositories . Нам нужна эта аннотация для использования функций Spring Data. Кроме того, мы расширяем Абстрактную конфигурацию R2 odbc , поскольку она предоставит множество компонентов, которые нам понадобятся позже.
4. Наше первое приложение R2DBC
Наш следующий шаг-создать репозиторий:
interface PlayerRepository extends ReactiveCrudRepository{}
То Реактивная грубая репозиция интерфейс очень полезен. Он обеспечивает, например, базовую функциональность CRUD.
Наконец, мы определим наш класс модели. Мы будем использовать Ломбок, чтобы избежать шаблонного кода:
@Data @NoArgsConstructor @AllArgsConstructor class Player { @Id Integer id; String name; Integer age; }
5. Тестирование
Пришло время протестировать наш код. Итак, давайте начнем с создания нескольких тестовых примеров:
@Test public void whenDeleteAll_then0IsExpected() { playerRepository.deleteAll() .as(StepVerifier::create) .expectNextCount(0) .verifyComplete(); } @Test public void whenInsert6_then6AreExpected() { insertPlayers(); playerRepository.findAll() .as(StepVerifier::create) .expectNextCount(6) .verifyComplete(); }
6. Пользовательские запросы
Мы также можем генерировать пользовательские запросы . Чтобы добавить его, нам нужно будет изменить ваш Репозиторий плееров :
@Query("select id, name, age from player where name = $1") FluxfindAllByName(String name); @Query("select * from player where age = $1") Flux findByAge(int age);
В дополнение к существующим тестам мы добавим тесты в наш недавно обновленный репозиторий:
@Test public void whenSearchForCR7_then1IsExpected() { insertPlayers(); playerRepository.findAllByName("CR7") .as(StepVerifier::create) .expectNextCount(1) .verifyComplete(); } @Test public void whenSearchFor32YearsOld_then2AreExpected() { insertPlayers(); playerRepository.findByAge(32) .as(StepVerifier::create) .expectNextCount(2) .verifyComplete(); } private void insertPlayers() { Listplayers = Arrays.asList( new Player(1, "Kaka", 37), new Player(2, "Messi", 32), new Player(3, "Mbappé", 20), new Player(4, "CR7", 34), new Player(5, "Lewandowski", 30), new Player(6, "Cavani", 32) ); playerRepository.saveAll(players).subscribe(); }
7. Партии
Еще одной особенностью R2DBC является создание пакетов. Пакет полезен при выполнении нескольких инструкций SQL, поскольку они будут работать лучше, чем отдельные операции.
Для создания Пакета нам нужен Объект подключения :
Batch batch = connection.createBatch();
После того, как наше приложение создаст экземпляр Batch , мы сможем добавить столько операторов SQL, сколько захотим. Чтобы выполнить его, мы вызовем метод execute () . Результатом пакета является Издатель , который возвращает объект результата для каждого оператора.
Итак, давайте перейдем к коду и посмотрим, как мы можем создать Пакет :
@Test public void whenBatchHas2Operations_then2AreExpected() { Mono.from(factory.create()) .flatMapMany(connection -> Flux.from(connection .createBatch() .add("select * from player") .add("select * from player") .execute())) .as(StepVerifier::create) .expectNextCount(2) .verifyComplete(); }
8. Заключение
Подводя итог, можно сказать, что R2DBC все еще находится на ранней стадии. Это попытка создать SPI, который будет определять реактивный API для баз данных SQL. При использовании с Spring Web Flux R2DBC позволяет нам написать приложение , которое асинхронно обрабатывает данные сверху и вплоть до базы данных.
Как всегда, код доступен на GitHub .