R2DBC

R2DBC整合mysql

前言: 目前关于响应式编程这块的教程的还不多,我也踩了一些雷,最终完成一个demo,在此分享出来。在操作之前需要WebFlux的前置知识。

分享一份WebFlux的博客:https://cloud.tencent.com/developer/article/1847825

官方文档:https://docs.spring.io/spring-data/r2dbc/docs/1.1.0.RELEASE/reference/html/#r2dbc.datbaseclient.fluent-api

1.简介(摘自官网)

R2DBC是 Reactive Relational Database Connectivity 的首字母缩写词。R2DBC 是一个 API 规范倡议,它声明了一个响应式 API,由驱动程序供应商实现以访问他们的关系数据库。

关于为什么创建 R2DBC 的部分答案是需要一个非阻塞应用程序堆栈来处理具有少量线程的并发并使用较少的硬件资源进行扩展。重用标准化的关系数据库访问 API(即 JDBC)无法满足这种需求,因为 JDBC 是一个完全阻塞的 API。尝试使用 a 来补偿阻塞行为ThreadPool的用途有限。

答案的另一部分是大多数应用程序使用关系数据库来存储它们的数据。虽然一些 NoSQL 数据库供应商为他们的数据库提供了反应式数据库客户端,但迁移到 NoSQL 并不是大多数项目的选择。这是将新的通用 API 用作任何非阻塞数据库驱动程序的基础的动机。虽然开源生态系统承载着各种非阻塞关系数据库驱动程序实现,但每个客户端都带有特定于供应商的 API,因此在这些库之上的通用层是不可能的。

反应式术语

术语“反应性”是指围绕对变化、可用性和可处理性做出反应而构建的编程模型——网络组件对 I/O 事件做出反应,UI 控制器对鼠标事件做出反应,资源可用等等。从这个意义上说,非阻塞是反应性的,因为我们现在处于对通知作出反应的模式,而不是被阻塞,因为操作完成或数据可用。

反应式API

Reactive Streams 在互操作性方面发挥着重要作用。它对库和基础设施组件很感兴趣,但作为应用程序 API 不太有用,因为它太低级了。应用程序需要一个更高级、更丰富、功能更强大的 API 来组合异步逻辑——类似于 Java 8 Stream API,但不仅限于表。这就是反应式库所扮演的角色。

Project Reactor是 Spring Data R2DBC 的首选反应库。它提供了MonoFluxAPI 类型,通过一组与 ReactiveX 运算符词汇表对齐的丰富运算符来处理0..1( Mono) 和0..N( Flux) 的数据序列。Reactor 是一个 Reactive Streams 库,因此它的所有操作符都支持非阻塞背压。Reactor 非常关注服务器端 Java。它是与 Spring 密切合作开发的。

Spring Data R2DBC 需要 Project Reactor 作为核心依赖项,但它可以通过 Reactive Streams 规范与其他反应式库互操作。作为一般规则,Spring Data R2DBC 存储库接受普通Publisher作为输入,在内部将其调整为 Reactor 类型,使用它,并返回 aMono或 aFlux作为输出。因此,您可以将任何Publisher作为输入并在输出上应用操作,但您需要调整输出以与另一个反应库一起使用。只要可行,Spring Data 就会透明地适应 RxJava 或其他反应式库的使用。

个人理解:通过响应式WebFlux 配合 配合反应式数据源,可以通过非阻塞的方式,提升线程的可用性,提升系统的吞吐量,但是响应时长并没多太多的感知。

2.R2DBC整合Mysql demo

环境:

jdk: adopt-openjdk-11

maven: 3.8.1

SpringBoot : 2.3.2.RELEASE

Pom文件

 		<!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!-- r2dbc spring data-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-r2dbc</artifactId>
        </dependency>
        <!-- r2dbc mysql 库-->
        <dependency>
            <groupId>dev.miku</groupId>
            <artifactId>r2dbc-mysql</artifactId>
            <version>0.8.2.RELEASE</version>
        </dependency>
        <!-- r2dbc-pool -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-r2dbc</artifactId>
            <version>2.3.0.RELEASE</version>
        </dependency>
        <!-- webFlux -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>

application配置文件

### r2dbc
spring:
  r2dbc:
    url: r2dbc:mysql://localhost/r2dbc?useUnicode=true&characterEncoding=UTF-8
    username: root
    password: root
    pool:
      enabled: true
      max-size: 10
      initial-size: 10
      validation-query: select 1

表结构

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `age` int(11) NULL DEFAULT NULL,
  `email` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `phone_number` int(11) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, 'admin', 12, '123@163.com', 145448546);
INSERT INTO `user` VALUES (2, 'tom', 18, 'tom@163.com', 12346789);
INSERT INTO `user` VALUES (5, 'jerry', 25, 'jerry@163.com', 154646126);

SET FOREIGN_KEY_CHECKS = 1;

实体类

/**
 * @author ZhaoJiu
 * @since: 2021/7/22
 * @desc: 用户实体类
 */
@Table("user")
@Data
public  class User {
   @Id
   private String id;
   private String name;
   private Integer age;
   private String email;
   private Integer phoneNumber;

}

JPA中的Repository

/**
 * @author ZhaoJiu
 * @since: 2021/7/22
 * @desc:
 */
public interface PersonRepository extends R2dbcRepository<User,String> {

}

最终代码

/**
 * @author ZhaoJiu
 * @since: 2021/7/22
 * @desc: r2dbc 操作mysql CRUD
 */
@RestController
@RequestMapping("user")
public class UserController {

    @Resource
    PersonRepository repository;

    /**
     * 修改用户
     *
     * @param user
     * @return
     */
    @PutMapping("/update")
    public Mono<ResponseEntity<String>> update(@RequestBody User user) {
        return repository.findById(user.getId())
                .flatMap(u -> repository.save(user)
                        .then(
                                Mono.just(new ResponseEntity<>("修改成功", HttpStatus.OK))
                        ))
                .defaultIfEmpty(new ResponseEntity<>("用户未找到", HttpStatus.NOT_FOUND));
    }

    /**
     * 根据id查询
     *
     * @param id 用户id
     * @return Mono
     */
    @GetMapping("{id}")
    public Mono<User> findById(@PathVariable String id) {
        return repository.findById(id);
    }

    /**
     * 添加用户
     *
     * @param user
     * @return
     */
    @PostMapping("save")
    public Mono<User> save(@RequestBody User user) {
        return repository.save(user);
    }

    /**
     * 查询所有
     *
     * @return
     */
    @GetMapping("/list")
    public Flux<User> findAll() {
        return repository.findAll();
    }

  /**
     * 删除
     *
     * @param id
     * @return
     */
    @DeleteMapping("{id}")
    public Mono<ResponseEntity<String>> delete(@PathVariable String id) {

        return repository.findById(id)
                .flatMap(
                   u -> repository.deleteById(id)
                       .then(
                             Mono.just(new ResponseEntity<>("删除成功", HttpStatus.OK))
                                ))
                .defaultIfEmpty(new ResponseEntity<>("没有该用户",HttpStatus.NOT_FOUND));

    }
}

测试效果(部分)
在这里插入图片描述

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在Spring WebFlux中使用R2DBC连接MySQL并集成Flyway,可以按照以下步骤进行操作: 1. 在pom.xml中添加所需的依赖项: ```xml <!-- Spring WebFlux --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> <!-- R2DBC MySQL 驱动 --> <dependency> <groupId>dev.miku</groupId> <artifactId>r2dbc-mysql</artifactId> <version>0.8.2.RELEASE</version> </dependency> <!-- Flyway --> <dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> </dependency> ``` 2. 在application.properties中配置R2DBC连接和Flyway: ```properties # R2DBC MySQL 连接配置 spring.r2dbc.url=r2dbc:mysql://localhost:3306/test spring.r2dbc.username=root spring.r2dbc.password=root # Flyway 配置 flyway.locations=classpath:db/migration flyway.clean-disabled=false flyway.baseline-on-migrate=true ``` 3. 创建数据库迁移脚本文件,存放在`src/main/resources/db/migration`目录下。例如,创建一个名为`V1__init.sql`的脚本文件,用于初始化数据库: ```sql CREATE TABLE `user` ( `id` INT PRIMARY KEY, `name` VARCHAR(50) NOT NULL, `age` INT NOT NULL ); ``` 4. 在Spring Boot应用程序中创建一个数据访问对象(DAO)来处理与数据库的交互。可以使用R2DBC提供的`DatabaseClient`或Spring Data R2DBC来简化数据库访问。 5. 启动应用程序,Flyway将自动执行数据库迁移脚本,初始化数据库。 注意:R2DBC是非阻塞的数据库访问方式,与传统的JDBC和Spring Data JPA不同,需要使用异步的方式进行操作。确保代码中的异步操作正确处理。 希望对你有所帮助!如有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值