使用反應式關係資料庫連線規範R2DBC操作MySQL資料庫
阿新 • • 發佈:2020-06-24
![](https://img2020.cnblogs.com/other/1739473/202006/1739473-20200624085745321-1194140335.png)
## 1. 簡介
三月份已經介紹過[R2DBC](https://mp.weixin.qq.com/s/yGzCrJgyqt_8eZEFNVStzg),它是一種非同步的、非阻塞的關係式資料庫連線規範。儘管一些**NoSQL**資料庫供應商為其資料庫提供了反應式資料庫客戶端,但對於大多數專案而言,遷移到**NoSQL**並不是一個理想的選擇。這促使了一個通用的響應式關係資料庫連線規範的誕生。 作為擁有龐大使用者群的關係式資料庫**MySQL**也有了反應式驅動,不過並不是官方的。但是**Spring**官方將其納入了依賴池,說明該類庫的質量並不低。所以今天就嚐嚐鮮,試一下使用**R2DBC**連線**MySQL**。
## 2. 環境依賴
基於**Spring Boot 2.3.1**和**Spring Data R2DBC**,還有反應式Web框架**Webflux**,同時也要依賴**r2dbc-mysql**庫,所有的**Maven**依賴為:
```xml
```
> **MySQL**版本為5.7,沒有測試其它版本。
## 3. R2DBC配置
所有的**R2DBC**自動配置都在`org.springframework.boot.autoconfigure.data.r2dbc`包下,如果要配置**MySQL**必須針對性的配置對應的連線工廠介面`ConnectionFactory`,當然也可以通過`application.yml`配置。個人比較喜歡`JavaConfig`。
```java
@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. 編寫反應式介面
我們先建立一張表並寫入一些資料:
```sql
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 女 '
)
```
對應的實體為:
```java
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**的反應式介面:
```java
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