1. 简介
三月份已经介绍过 ,它是一种异步的、非阻塞的关系式数据库连接规范。尽管一些 NoSQL 数据库供应商为其数据库提供了反应式数据库客户端,但对于大多数项目而言,迁移到 NoSQL 并不是一个理想的选择。这促使了一个通用的响应式关系数据库连接规范的诞生。 作为拥有庞大用户群的关系式数据库 MySQL 也有了反应式驱动,不过并不是官方的。但是 Spring 官方将其纳入了依赖池,说明该类库的质量并不低。所以今天就尝尝鲜,试一下使用 R2DBC 连接 MySQL 。
2. 环境依赖
基于 Spring Boot 2.3.1 和 Spring Data R2DBC ,还有反应式Web框架 Webflux ,同时也要依赖 r2dbc-mysql 库,所有的 Maven 依赖为:
<!--r2dbc mysql 库--> < dependency > < groupId >dev.miku </ groupId > < artifactId >r2dbc-mysql </ artifactId > </ dependency > <!--Spring 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-data-jdbc </ artifactId > </ dependency > <!--反应式web框架--> < dependency > < groupId >org.springframework.boot </ groupId > < artifactId >spring-boot-starter-webflux </ artifactId > </ dependency >
MySQL 版本为5.7,没有测试其它版本。
3. R2DBC配置
所有的
R2DBC
自动配置都在
org.springframework.boot.autoconfigure.data.r2dbc
包下,如果要配置
MySQL
必须针对性的配置对应的连接工厂接口
ConnectionFactory
,当然也可以通过
application.yml
配置。个人比较喜欢
JavaConfig
。
@Bean ConnectionFactory connectionFactory() { return MySqlConnectionFactory. from( MySqlConnectionConfiguration. builder() . host( "127.0.0.1") . port( 3306) . username( "root") . password( "123456") . database( "database_name") // 额外的其它非必选参数省略 . build()); }
详细配置可参考 r2dbc-mysql 的官方说明: https://github.com/mirromutth/r2dbc-mysql
当
ConnectionFactory
配置好后,就会被注入
DatabaseClient
对象。该对象是非阻塞的,用于执行数据库反应性客户端调用与反应流背压请求。我们可以通过该接口反应式地操作数据库。
4. 编写反应式接口
我们先创建一张表并写入一些数据:
create table client_user ( user_id varchar( 64) not null comment '用户唯一标示' primary key, username varchar( 64) null comment '名称', phone_number varchar( 64) null comment '手机号', gender tinyint( 1) default 0 null comment '0 未知 1 男 2 女 ' )
对应的实体为:
package cn. felord. r2dbc. config; import lombok. Data; /** * @author felord.cn */ @Data public class ClientUser { private String userId; private String username; private String phoneNumber; private Integer gender; }
然后我们编写一个 Webflux 的反应式接口:
package cn. felord. r2dbc. config; import org. springframework. data. r2dbc. core. DatabaseClient; import org. springframework. web. bind. annotation. GetMapping; import org. springframework. web. bind. annotation. RequestMapping; import org. springframework. web. bind. annotation. RestController; import reactor. core. publisher. Flux; import reactor. core. publisher. Mono; import javax. annotation. Resource; /** * The type User controller. * * @author felord.cn * @since 17 :07 */ @RestController @RequestMapping( "/user") public class UserController { @Resource private DatabaseClient databaseClient; /** * 查询 * * @return 返回Flux序列 包含所有的ClientUser */ @GetMapping( "/get") public Flux < ClientUser > clientUserFlux() { return databaseClient. execute( "select * from client_user"). as( ClientUser. class) . fetch() . all(); } /** * 响应式写入. * * @return Mono对象包含更新成功的条数 */ @GetMapping( "/add") public Mono < Integer > insert() { ClientUser clientUser = new ClientUser(); clientUser. setUserId( "34345514644"); clientUser. setUsername( "felord.cn"); clientUser. setPhoneNumber( "3456121"); clientUser. setGender( 1); return databaseClient. insert(). into( ClientUser. class) . using( clientUser) . fetch(). rowsUpdated(); } }
调用接口就能获取到期望的数据结果。
5. 总结
乍一看
R2DBC
并没有想象中的那么难,但是间接的需要了解
Flux
、
Mono
等抽象概念。同时目前来说如果不和
Webflux
框架配合也没有使用场景。就本文的
MySQL
而言,
R2DBC
驱动还是社区维护(不得不说
PgSQL
就做的很好)。
然而需要你看清的是 反应式才是未来 Spring Boot 的感觉。另外这里有一份 Spring 官方关于 R2DBC 的PPT,也是让你更好了解 R2DBC 的权威资料。可以关注: 码农小胖哥 回复 r2dbc

