专栏首页码农小胖哥的码农生涯只会JDBC连接MySQL?来试试R2DBC吧

只会JDBC连接MySQL?来试试R2DBC吧

1. 简介

三月份已经介绍过R2DBC,它是一种异步的、非阻塞的关系式数据库连接规范。

尽管一些NoSQL数据库供应商为其数据库提供了反应式数据库客户端,但对于大多数项目而言,迁移到NoSQL并不是一个理想的选择。这促使了一个通用的响应式关系数据库连接规范的诞生。作为拥有庞大用户群的关系式数据库MySQL也有了反应式驱动,不过并不是官方的。但是Spring官方将其纳入了依赖池,说明该类库的质量并不低。所以今天就尝尝鲜,试一下使用R2DBC连接MySQL

2. 环境依赖

基于Spring Boot 2.3.1Spring 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并没有想象中的那么难,但是间接的需要了解FluxMono等抽象概念。同时目前来说如果不和Webflux框架配合也没有使用场景。就本文的MySQL而言,R2DBC驱动还是社区维护(不得不说PgSQL就做的很好)。

然而需要你看清的是反应式才是未来。如果你要抓住未来就需要现在就了解一些相关的知识。这让我想起五年前刚刚接触Spring Boot的感觉。

本文分享自微信公众号 - 码农小胖哥(Felordcn),作者:码农小胖哥

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-06-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Shiro权限管理框架入门到实战

    前言:前几天学习了SpringSecurity安全框架,这几天又接着学习shiro框架,这两者框架都是同一类产品,解决同一类问题,但是在官方推荐使用Shiro框...

    码农小胖哥
  • Java SPI 居然这么多知名框架在用

    Java SPI全称Java Service Provider Interface。是 Java 提供的一套用来被第三方实现或者扩展的 API,它可以用来启用框...

    码农小胖哥
  • SpringBoot使用Graylog日志收集

    Graylog是一个生产级别的日志收集系统,集成Mongo和Elasticsearch进行日志收集。其中Mongo用于存储Graylog的元数据信息和配置信息,...

    码农小胖哥
  • SpringBoot 实战 | 集成 Swagger2 构建强大的 RESTful API 文档

    Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。

    一个优秀的废人
  • SpringCloud-Zuul服务网关[容错Hystrix]

      zuul作为网关服务,用来分配调度其他服务的,那么难免就会出现调用的服务出现问题的请求,或者用户访问急剧增多的情况,那么此时我们的网关服务就应该具有容错能力...

    用户4919348
  • spring-boot - demo

    当我发现把最初的一个demo整的面目全非的时候,突然想要找一个简单的demo做测试,发现与其在原来的上面该,还不如新建一个demo。 官方入门:http://p...

    Ryan-Miao
  • SpringBoot拦截器

    在实际开发中,总存在着这样的场景,比如拦截请求的ip地址,或者在所有的请求都返回相同的数据,如果每一个方法都写出相同数据固然可以实现,但是随着项目的变大,重复的...

    dalaoyang
  • SpringBoot的国际化使用

    在项目中,很多时候需要国际化的支持,这篇文章要介绍一下springboot项目中国际化的使用。 在这个项目中前端页面使用的thymeleaf,另外加入了neko...

    dalaoyang
  • springboot (八) 文件上传下载

    IT故事会
  • springboot(13)国际化

    IT故事会

扫码关注云+社区

领取腾讯云代金券