关于java:WebFlux-操作-MySQL-是种什么体验

44次阅读

共计 3863 个字符,预计需要花费 10 分钟才能阅读完成。

人不知; 鬼不觉中,咱们的 WebFlux 系列曾经整到第 11 篇啦。如果小伙伴们还没看过后面的文章,记得先看一下哦,这有助于了解本文。

  1. 挖一个大坑,WebFlux 开搞!
  2. WebFlux 前置常识(一)
  3. WebFlux 前置常识(二)
  4. WebFlux 前置常识(三)
  5. WebFlux 前置常识(四)
  6. 异步 Servlet 都不懂,谈何 WebFlux?
  7. WebFlux 初体验
  8. 服务端被动推送数据,除了 WebSocket 你还能想到啥?
  9. 用 WebFlux 写个 CURD 是什么体验?
  10. WebFlux 中的申请地址路由怎么玩?

好啦,开始明天的注释。

后面咱们用 WebFlux 曾经写了一个 CURD 了,不过数据库用的是 MongoDB。很多人对 WebFlux 持狐疑态度,包含松哥之前发文章的时候,还有人在说不能连贯 MySQL 的 WebFlux 是没有任何意义的!这句话没错,然而咱们也要看到 WebFlux 正处于一个高速倒退的期间,所有不可能的事件都会变得可能,所有以前没有的性能当前都会有,WebFlux 的变动速度是肉眼可见的。

比方咱们明天要介绍的 R2DBC 就能在肯定水平上打消一些人的疑虑,尽管这个工具还不是特地完满,然而咱们看到了 WebFlux 在致力解决这些存在的问题,咱们也有理由置信 WebFlux 将来会越来越好。

好啦,不吹了,还是来看点理论的货色吧。

1. 什么是 R2DBC?

首先大家要晓得,咱们最常应用的 JDBC 其实是同步的,而咱们应用 WebFlux 的目标是为了通过异步的形式来进步服务端的响应效率,WebFlux 尽管实现了异步,然而因为 JDBC 还是同步的,而大部分利用都是离不开数据库的,所以其实效率实质上还是没有晋升。

那么怎么办呢?有没有异步的 JDBC 呢?有!

目前市面上异步 JDBC 次要是两种:

  • ADAB:ADBA 是 Oracle 主导的 Java 异步数据库拜访的规范 API,它将会集成于将来的 Java 规范发行版中。然而目前倒退比较慢,只提供 OpenJDK 的沙盒个性供开发者钻研之用。
  • R2DBC:R2DBC 是 Spring 官网在 Spring5 公布了响应式 Web 框架 Spring WebFlux 之后急需可能满足异步响应的数据库交互 API,不过因为不足规范和驱动,Pivotal 团队开始本人钻研响应式关系型数据库连贯 Reactive Relational Database Connectivity,并提出了 R2DBC 标准 API 用来评估可行性并探讨数据库厂商是否有趣味反对响应式的异步非阻塞驱动程序。最早只有 PostgreSQL、H2、MSSQL 三家数据库厂商,不过当初 MySQL 也退出进来了,这是一个极大的利好。目前 R2DBC 的最新版本是 0.9.0.RELEASE。

须要留神的是,这两个都不是对原来 JDBC 的补充,都是打算从新去设计数据库拜访计划!

好了,当初大家对 R2DBC 有一个根本的认知了,接下来咱们就通过一个简略的例子,咱们一起来体验一把如何通过 R2DBC 来操作 MySQL 数据库。

2. 代码实际

2.1 创立我的项目

首先咱们来创立一个 Spring Boot 我的项目,引入 WebFlux 和 R2DBC 依赖,如下图:

我的项目创立胜利后,pom.xml 文件中会主动退出 R2DBC 相干的依赖,如下:

<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

配置文件除了属性的 key 不同之外,数据库的连贯协定也从 jdbc 变为 r2dbc 了。

OK,如此,咱们的筹备工作就算实现了。

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

这一块其实都没啥好说的,如果大家感到困惑,能够参考咱们前两篇文章中的解说。

  • [用 WebFlux 写个 CURD 是什么体验?]()
  • [WebFlux 中的申请地址路由怎么玩?]()

3. 测试

最初咱们来简略测试下。

查问:

增加:

更新:

有 id 并且 id 曾经存在,默认就是更新。

删除:

删除胜利响应 200:

删除失败响应 404:

好啦,这就是一个简略的 WebFlux 操作关系型数据库的案例,对于 WebFlux 的更多其余用法,追随松哥一起来缓缓解剖吧~

正文完
 0