Каков опыт работы WebFlux с MySQL?

Spring Boot задняя часть Spring
Каков опыт работы WebFlux с MySQL?

Прежде чем мы это узнаем, наша серия WebFlux достигла 11-й статьи. Если вы не читали предыдущую статью, не забудьте сначала прочитать ее, она поможет вам понять эту статью.

  1. Выкопайте большую яму и запустите WebFlux!
  2. Необходимые знания WebFlux (1)
  3. Необходимые знания WebFlux (2)
  4. Необходимые знания WebFlux (3)
  5. Необходимые знания WebFlux (4)
  6. Я не понимаю асинхронные сервлеты, как насчет WebFlux?
  7. Первый опыт WebFlux
  8. Сервер активно пушит данные, что еще можно придумать, кроме WebSocket?
  9. Каков опыт написания CURD с помощью WebFlux?
  10. Как работает маршрутизация адресов запросов в WebFlux?

Хорошо, давайте начнем сегодняшний текст.

Мы уже писали CURD с WebFlux ранее, но база данных — MongoDB. Многие люди скептически относятся к WebFlux, в том числе, когда Сонг Гэ ранее опубликовал статью, некоторые люди сказали, что бессмысленно не подключаться к MySQL WebFlux! Это предложение верно, но мы также должны видеть, что WebFlux находится в периоде бурного развития, все невозможное станет возможным, все функции, которые не были доступны ранее, будут доступны в будущем, и скорость изменения WebFlux видна. невооруженным глазом.

Например, R2DBC, который мы собираемся представить сегодня, может в определенной степени развеять сомнения некоторых людей.Хотя этот инструмент не особенно совершенен, мы видели, что WebFlux усердно работает над решением этих существующих проблем.У нас также есть причины для этого. верим, что в будущем WebFlux будет становиться все больше и больше.

Ладно, давайте прекратим разговоры, давайте посмотрим на что-нибудь практическое.

1. Что такое R2DBC?

Прежде всего, вы должны знать, что наиболее часто используемый JDBC на самом деле является синхронным, а цель использования WebFlux — повысить эффективность ответа сервера асинхронным способом. Некоторые приложения неотделимы от базы данных, так что по сути эффективность не повысилась.

Так что делать? Есть ли асинхронный JDBC? имеют!

В настоящее время на рынке в основном существует два типа асинхронного JDBC:

  • ADAB: ADBA — это стандартный API-интерфейс Oracle для асинхронного доступа к базе данных в Java, который будет интегрирован в будущие стандартные версии Java. Однако в настоящее время разработка идет относительно медленно, и разработчикам предоставляется для изучения только функция песочницы OpenJDK.
  • R2DBC: R2DBC — это API взаимодействия с базой данных, который остро нуждается в асинхронном ответе после официального выпуска адаптивной веб-инфраструктуры Spring WebFlux в Spring 5. Однако из-за отсутствия стандартов и драйверов команда Pivotal начала изучать Reactive. Самостоятельное подключение к реляционным базам данных API-интерфейс спецификации R2DBC представлен для оценки осуществимости и обсуждения того, заинтересованы ли поставщики баз данных в поддержке реактивных асинхронных неблокирующих драйверов. Сначала было только три поставщика баз данных: PostgreSQL, H2 и MSSQL, но теперь к ним присоединилась и MySQL, что является большим преимуществом. Последняя версия R2DBC — 0.9.0.RELEASE.

Следует отметить, что эти два не являются дополнениями к оригинальному JDBC, а предназначены для изменения схемы доступа к базе данных!

Что ж, теперь у всех есть общее представление о R2DBC.Далее мы будем использовать простой пример, чтобы узнать, как работать с базой данных MySQL через R2DBC.

2. Практика Кодекса

2.1 Создать проект

Во-первых, давайте создадим проект Spring Boot и представим зависимости WebFlux и R2DBC, как показано ниже:

После успешного создания проекта зависимости, связанные с R2DBC, будут автоматически добавлены в файл pom.xml следующим образом:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
    <groupId>dev.miku</groupId>
    <artifactId>r2dbc-mysql</artifactId>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

Затем мы настраиваем информацию о подключении базы данных в application.properties, Обратите внимание, что эта конфигурация немного отличается от предыдущей:

spring.r2dbc.url=r2dbcs:mysql://localhost:3306/test01
spring.r2dbc.username=root
spring.r2dbc.password=123

Помимо различных ключевых атрибутов файла конфигурации, протокол подключения к базе данных также изменился с jdbc на r2dbc.

Итак, наши приготовления завершены.

2.2 Скрипт базы данных

Мы готовим простую таблицу данных следующим образом:

Этот сценарий очень прост, мне не нужно его предоставлять.

2.3 CURD

Сначала мы предоставляем класс сущности следующим образом:

public class User {
    @Id
    private Long id;
    private String username;
    private String address;
    //省略 getter/setter
}

Затем нам нужен интерфейс UserRepository, который напрямую наследуется от ReactiveCrudRepository, что похоже на то, как раньше играла MongoDB.

public interface UserRepository extends ReactiveCrudRepository<User,Long> {

}

Далее давайте определим процессор для таблицы User, аналогичный процессору в MongoDB, следующим образом:

import static java.lang.Long.parseLong;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.web.reactive.function.server.ServerResponse.notFound;
import static org.springframework.web.reactive.function.server.ServerResponse.ok;

@Component
public class UserHandler {

    @Autowired
    UserRepository userRepository;

    public Mono<ServerResponse> getAllUsers(ServerRequest serverRequest) {
        return ok().contentType(APPLICATION_JSON)
                .body(userRepository.findAll(), User.class);
    }

    public Mono<ServerResponse> addUser(ServerRequest serverRequest) {
        return ok().contentType(APPLICATION_JSON)
                .body(userRepository.saveAll(serverRequest.bodyToMono(User.class)), User.class);
    }

    public Mono<ServerResponse> deleteUser(ServerRequest serverRequest) {
        return userRepository.findById(parseLong(serverRequest.pathVariable("id")))
                .flatMap(user -> userRepository.delete(user).then(ok().build()))
                .switchIfEmpty(notFound().build());
    }
}

Наконец, давайте настроим маршрутизацию адресов запросов следующим образом:

@Configuration
public class RouterConfiguration {
    @Bean
    RouterFunction<ServerResponse> userRouterFunction(UserHandler userHandler) {
        return RouterFunctions.nest(RequestPredicates.path("/user"),
                RouterFunctions.route(RequestPredicates.GET("/"), userHandler::getAllUsers)
                        .andRoute(RequestPredicates.POST("/"), userHandler::addUser)
                        .andRoute(RequestPredicates.DELETE("/{id}"), userHandler::deleteUser));
    }
}

На самом деле об этом произведении сказать нечего, если вы запутались, то можете обратиться к объяснениям в наших предыдущих двух статьях.

3. Тест

Наконец, давайте проведем простой тест.

Спросите:

Добавить к:

обновить:

Если есть идентификатор, а идентификатор уже существует, по умолчанию выполняется обновление.

Удалить:

Удалить успешный ответ 200:

删除成功响应 200

Удалить ошибочный ответ 404:

删除失败响应 404

Что ж, это простой случай, когда WebFlux работает с реляционной базой данных.