Автор оригинала: 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")
Flux findAllByName(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() {
List players = 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 .