最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

springboot3+r2dbc響應(yīng)式編程實踐

 更新時間:2022年02月11日 11:54:05   作者:麒思妙想  
本文主要介紹了springboot3+r2dbc響應(yīng)式編程實踐,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下

Spring boot3已經(jīng)M1了,最近群佬們也開始蠢蠢欲動的開始整活Reactive+Spring Boot3,跟著大家的步伐,我也來整一篇工程入門,我們將用java17+Spring Boot3+r2dbc+Reactive棧來講述,歡迎大家來討論。(關(guān)于響應(yīng)式,請大家異步到之前的文章里,有詳細(xì)介紹。)

r2dbc

Reactor還有基于其之上的Spring WebFlux框架。包括vert.x,rxjava等等reactive技術(shù)。我們實際上在應(yīng)用層已經(jīng)有很多優(yōu)秀的響應(yīng)式處理框架。

但是有一個問題就是所有的框架都需要獲取底層的數(shù)據(jù),而基本上關(guān)系型數(shù)據(jù)庫的底層讀寫都還是同步的。

為了解決這個問題,出現(xiàn)了兩個標(biāo)準(zhǔn),一個是oracle提出的 ADBC (Asynchronous Database Access API),另一個就是Pivotal提出的R2DBC (Reactive Relational Database Connectivity)。

R2DBC是基于Reactive Streams標(biāo)準(zhǔn)來設(shè)計的。通過使用R2DBC,你可以使用reactive API來操作數(shù)據(jù)。

同時R2DBC只是一個開放的標(biāo)準(zhǔn),而各個具體的數(shù)據(jù)庫連接實現(xiàn),需要實現(xiàn)這個標(biāo)準(zhǔn)。

今天我們以r2dbc-h2為例,講解一下r2dbc在Spring webFlux中的使用。

工程依賴

以下是 pom.xml清單

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
?? ?xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
?? ?<modelVersion>4.0.0</modelVersion>
?? ?<parent>
?? ??? ?<groupId>org.springframework.boot</groupId>
?? ??? ?<artifactId>spring-boot-starter-parent</artifactId>
?? ??? ?<version>3.0.0-M1</version>
?? ??? ?<relativePath/> <!-- lookup parent from repository -->
?? ?</parent>
?? ?<groupId>wang.datahub</groupId>
?? ?<artifactId>springboot3demo</artifactId>
?? ?<version>0.0.1-SNAPSHOT</version>
?? ?<name>springboot3demo</name>
?? ?<description>Demo project for Spring Boot</description>
?? ?<properties>
?? ??? ?<java.version>17</java.version>
?? ?</properties>
?? ?<dependencies>
?? ??? ?<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-redis-reactive</artifactId>
?? ??? ?</dependency>
?? ??? ?<dependency>
?? ??? ??? ?<groupId>org.springframework.boot</groupId>
?? ??? ??? ?<artifactId>spring-boot-starter-data-rest</artifactId>
?? ??? ?</dependency>
?? ??? ?<dependency>
?? ??? ??? ?<groupId>org.springframework.boot</groupId>
?? ??? ??? ?<artifactId>spring-boot-starter-groovy-templates</artifactId>
?? ??? ?</dependency>
?? ??? ?<dependency>
?? ??? ??? ?<groupId>org.springframework.boot</groupId>
?? ??? ??? ?<artifactId>spring-boot-starter-hateoas</artifactId>
?? ??? ?</dependency>
?? ??? ?<dependency>
?? ??? ??? ?<groupId>org.springframework.boot</groupId>
?? ??? ??? ?<artifactId>spring-boot-starter-web</artifactId>
?? ??? ?</dependency>
?? ??? ?<dependency>
?? ??? ??? ?<groupId>org.springframework.boot</groupId>
?? ??? ??? ?<artifactId>spring-boot-starter-webflux</artifactId>
?? ??? ?</dependency>

?? ??? ?<dependency>
?? ??? ??? ?<groupId>org.springframework.boot</groupId>
?? ??? ??? ?<artifactId>spring-boot-configuration-processor</artifactId>
?? ??? ??? ?<optional>true</optional>
?? ??? ?</dependency>
?? ??? ?<dependency>
?? ??? ??? ?<groupId>org.springframework.boot</groupId>
?? ??? ??? ?<artifactId>spring-boot-devtools</artifactId>
?? ??? ?</dependency>

?? ??? ?<dependency>
?? ??? ??? ?<groupId>io.r2dbc</groupId>
?? ??? ??? ?<artifactId>r2dbc-h2</artifactId>
?? ??? ?</dependency>
?? ??? ?<dependency>
?? ??? ??? ?<groupId>com.h2database</groupId>
?? ??? ??? ?<artifactId>h2</artifactId>
?? ??? ?</dependency>

?? ??? ?<dependency>
?? ??? ??? ?<groupId>mysql</groupId>
?? ??? ??? ?<artifactId>mysql-connector-java</artifactId>
?? ??? ??? ?<scope>runtime</scope>
?? ??? ?</dependency>
?? ??? ?<dependency>
?? ??? ??? ?<groupId>org.springframework.boot</groupId>
?? ??? ??? ?<artifactId>spring-boot-starter-test</artifactId>
?? ??? ??? ?<scope>test</scope>
?? ??? ?</dependency>
?? ??? ?<dependency>
?? ??? ??? ?<groupId>io.projectreactor</groupId>
?? ??? ??? ?<artifactId>reactor-test</artifactId>
?? ??? ??? ?<scope>test</scope>
?? ??? ?</dependency>
?? ??? ?<dependency>
?? ??? ??? ?<groupId>io.projectreactor</groupId>
?? ??? ??? ?<artifactId>reactor-test</artifactId>
<!--?? ??? ??? ?<version>3.4.14</version>-->
<!--?? ??? ??? ?<scope>compile</scope>-->
?? ??? ?</dependency>

?? ?</dependencies>

?? ?<build>
?? ??? ?<plugins>
?? ??? ??? ?<plugin>
?? ??? ??? ??? ?<groupId>org.springframework.boot</groupId>
?? ??? ??? ??? ?<artifactId>spring-boot-maven-plugin</artifactId>
?? ??? ??? ?</plugin>
?? ??? ?</plugins>
?? ?</build>
?? ?<repositories>
?? ??? ?<repository>
?? ??? ??? ?<id>spring-milestones</id>
?? ??? ??? ?<name>Spring Milestones</name>
?? ??? ??? ?<url>https://repo.spring.io/milestone</url>
?? ??? ??? ?<snapshots>
?? ??? ??? ??? ?<enabled>false</enabled>
?? ??? ??? ?</snapshots>
?? ??? ?</repository>
?? ??? ?<repository>
?? ??? ??? ?<id>spring-snapshots</id>
?? ??? ??? ?<name>Spring Snapshots</name>
?? ??? ??? ?<url>https://repo.spring.io/snapshot</url>
?? ??? ??? ?<releases>
?? ??? ??? ??? ?<enabled>false</enabled>
?? ??? ??? ?</releases>
?? ??? ?</repository>
?? ?</repositories>
?? ?<pluginRepositories>
?? ??? ?<pluginRepository>
?? ??? ??? ?<id>spring-milestones</id>
?? ??? ??? ?<name>Spring Milestones</name>
?? ??? ??? ?<url>https://repo.spring.io/milestone</url>
?? ??? ??? ?<snapshots>
?? ??? ??? ??? ?<enabled>false</enabled>
?? ??? ??? ?</snapshots>
?? ??? ?</pluginRepository>
?? ??? ?<pluginRepository>
?? ??? ??? ?<id>spring-snapshots</id>
?? ??? ??? ?<name>Spring Snapshots</name>
?? ??? ??? ?<url>https://repo.spring.io/snapshot</url>
?? ??? ??? ?<releases>
?? ??? ??? ??? ?<enabled>false</enabled>
?? ??? ??? ?</releases>
?? ??? ?</pluginRepository>
?? ?</pluginRepositories>

</project>

配置文件

這里我們只配置了r2dbc鏈接信息

配置類

用于配置默認(rèn)鏈接,創(chuàng)建初始化數(shù)據(jù)

package wang.datahub.springboot3demo.config;

import io.netty.util.internal.StringUtil;
import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactory;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Flux;
import static io.r2dbc.spi.ConnectionFactoryOptions.*;

@Configuration
@ConfigurationProperties(prefix = "r2dbc")
public class DBConfig {

    private String url;
    private String user;
    private String password;

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Bean
    public ConnectionFactory connectionFactory() {
        System.out.println("url ==> "+url);
        ConnectionFactoryOptions baseOptions = ConnectionFactoryOptions.parse(url);
        ConnectionFactoryOptions.Builder ob = ConnectionFactoryOptions.builder().from(baseOptions);
        if (!StringUtil.isNullOrEmpty(user)) {
            ob = ob.option(USER, user);
        }
        if (!StringUtil.isNullOrEmpty(password)) {
            ob = ob.option(PASSWORD, password);
        }
        return ConnectionFactories.get(ob.build());
    }

    @Bean
    public CommandLineRunner initDatabase(ConnectionFactory cf) {

        return (args) ->
                Flux.from(cf.create())
                        .flatMap(c ->
                                Flux.from(c.createBatch()
                                                .add("drop table if exists Users")
                                                .add("create table Users(" +
                                                        "id IDENTITY(1,1)," +
                                                        "firstname varchar(80) not null," +
                                                        "lastname varchar(80) not null)")
                                                .add("insert into Users(firstname,lastname)" +
                                                        "values('Jacky','Li')")
                                                .add("insert into Users(firstname,lastname)" +
                                                        "values('Doudou','Li')")
                                                .add("insert into Users(firstname,lastname)" +
                                                        "values('Maimai','Li')")
                                                .execute())
                                        .doFinally((st) -> c.close())
                        )
                        .log()
                        .blockLast();
    }

}

bean

創(chuàng)建用戶bean

package wang.datahub.springboot3demo.bean;

import org.springframework.data.annotation.Id;

public class Users {
    @Id
    private Long id;
    private String firstname;
    private String lastname;

    public Users(){

    }

    public Users(Long id, String firstname, String lastname) {
        this.id = id;
        this.firstname = firstname;
        this.lastname = lastname;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }


    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", firstname='" + firstname + '\'' +
                ", lastname='" + lastname + '\'' +
                '}';
    }
}

DAO

dao代碼清單如下,包含查詢列表、按id查詢,以及創(chuàng)建用戶等操作

package wang.datahub.springboot3demo.dao;

import io.r2dbc.spi.Connection;
import io.r2dbc.spi.ConnectionFactory;
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
import org.springframework.data.relational.core.query.Query;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import wang.datahub.springboot3demo.bean.Users;

import static org.springframework.data.r2dbc.query.Criteria.where;
import static org.springframework.data.relational.core.query.Query.query;

@Component
public class UsersDao {
? ? private ConnectionFactory connectionFactory;
? ? private R2dbcEntityTemplate template;

? ? public UsersDao(ConnectionFactory connectionFactory) {
? ? ? ? this.connectionFactory = connectionFactory;
? ? ? ? this.template = new R2dbcEntityTemplate(connectionFactory);
? ? }

? ? public Mono<Users> findById(long id) {

? ? ? ? return this.template.selectOne(query(where("id").is(id)),Users.class);

// ? ? ? ?return Mono.from(connectionFactory.create())
// ? ? ? ? ? ? ? ?.flatMap(c -> Mono.from(c.createStatement("select id,firstname,lastname from Users where id = $1")
// ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?.bind("$1", id)
// ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?.execute())
// ? ? ? ? ? ? ? ? ? ? ? ?.doFinally((st) -> close(c)))
// ? ? ? ? ? ? ? ?.map(result -> result.map((row, meta) ->
// ? ? ? ? ? ? ? ? ? ? ? ?new Users(row.get("id", Long.class),
// ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?row.get("firstname", String.class),
// ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?row.get("lastname", String.class))))
// ? ? ? ? ? ? ? ?.flatMap( p -> Mono.from(p));
? ? }

? ? public Flux<Users> findAll() {
? ? ? ? return this.template.select(Users.class).all();
// ? ? ? ?return Mono.from(connectionFactory.create())
// ? ? ? ? ? ? ? ?.flatMap((c) -> Mono.from(c.createStatement("select id,firstname,lastname from users")
// ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?.execute())
// ? ? ? ? ? ? ? ? ? ? ? ?.doFinally((st) -> close(c)))
// ? ? ? ? ? ? ? ?.flatMapMany(result -> Flux.from(result.map((row, meta) -> {
// ? ? ? ? ? ? ? ? ? ?Users acc = new Users();
// ? ? ? ? ? ? ? ? ? ?acc.setId(row.get("id", Long.class));
// ? ? ? ? ? ? ? ? ? ?acc.setFirstname(row.get("firstname", String.class));
// ? ? ? ? ? ? ? ? ? ?acc.setLastname(row.get("lastname", String.class));
// ? ? ? ? ? ? ? ? ? ?return acc;
// ? ? ? ? ? ? ? ?})));
? ? }

? ? public Mono<Users> createAccount(Users account) {

? ? ? ? return Mono.from(connectionFactory.create())
? ? ? ? ? ? ? ? .flatMap(c -> Mono.from(c.beginTransaction())
? ? ? ? ? ? ? ? ? ? ? ? .then(Mono.from(c.createStatement("insert into Users(firstname,lastname) values($1,$2)")
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? .bind("$1", account.getFirstname())
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? .bind("$2", account.getLastname())
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? .returnGeneratedValues("id")
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? .execute()))
? ? ? ? ? ? ? ? ? ? ? ? .map(result -> result.map((row, meta) ->
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? new Users(row.get("id", Long.class),
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? account.getFirstname(),
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? account.getLastname())))
? ? ? ? ? ? ? ? ? ? ? ? .flatMap(pub -> Mono.from(pub))
? ? ? ? ? ? ? ? ? ? ? ? .delayUntil(r -> c.commitTransaction())
? ? ? ? ? ? ? ? ? ? ? ? .doFinally((st) -> c.close()));

? ? }

? ? private <T> Mono<T> close(Connection connection) {
? ? ? ? return Mono.from(connection.close())
? ? ? ? ? ? ? ? .then(Mono.empty());
? ? }
}

controller

controller代碼清單如下,包含了查詢列表、按id查詢,以及創(chuàng)建用戶等操作

package wang.datahub.springboot3demo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import wang.datahub.springboot3demo.bean.Users;
import wang.datahub.springboot3demo.dao.UsersDao;

@RestController
public class UsersController {
    @Autowired
    private final UsersDao usersDao;

    public UsersController(UsersDao usersDao) {
        this.usersDao = usersDao;
    }

    @GetMapping("/users/{id}")
    public Mono<ResponseEntity<Users>> getUsers(@PathVariable("id") Long id) {

        return usersDao.findById(id)
                .map(acc -> new ResponseEntity<>(acc, HttpStatus.OK))
                .switchIfEmpty(Mono.just(new ResponseEntity<>(null, HttpStatus.NOT_FOUND)));
    }

    @GetMapping("/users")
    public Flux<Users> getAllAccounts() {
        return usersDao.findAll();
    }

    @PostMapping("/createUser")
    public Mono<ResponseEntity<Users>> createUser(@RequestBody Users user) {
        return usersDao.createAccount(user)
                .map(acc -> new ResponseEntity<>(acc, HttpStatus.CREATED))
                .log();
    }
}

啟動類清單:

package wang.datahub.springboot3demo;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import wang.datahub.springboot3demo.config.DBConfig;


@SpringBootApplication
@EnableConfigurationProperties(DBConfig.class)
public class WebFluxR2dbcApp {
? ? public static void main(String[] args) {
? ? ? ? SpringApplication.run(WebFluxR2dbcApp.class, args);
? ? }
}

好了,致此我們整個 Demo 就實現(xiàn)完成了

參考鏈接:

https://zhuanlan.zhihu.com/p/299069835

到此這篇關(guān)于springboot3+r2dbc響應(yīng)式編程實踐的文章就介紹到這了,更多相關(guān)springboot3 r2dbc響應(yīng)式編程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java中List<對象>如何根據(jù)對象的一個屬性進(jìn)行去重

    java中List<對象>如何根據(jù)對象的一個屬性進(jìn)行去重

    這篇文章主要給大家介紹了關(guān)于java中List<對象>如何根據(jù)對象的一個屬性進(jìn)行去重的相關(guān)資料,在開發(fā)中可能會遇到很多需要去重的情況,比如Person對象有name跟age兩個屬性,需要根據(jù)age進(jìn)行去重,需要的朋友可以參考下
    2023-08-08
  • 淺談java Iterator.remove()方法的用法(詳解)

    淺談java Iterator.remove()方法的用法(詳解)

    下面小編就為大家?guī)硪黄獪\談java Iterator.remove()方法的用法(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01
  • springboot接口多實現(xiàn)類選擇性注入解決方案

    springboot接口多實現(xiàn)類選擇性注入解決方案

    這篇文章主要為大家介紹了springboot接口多實現(xiàn)類選擇性注入解決方案的四種方式,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-03-03
  • Java是自學(xué)好還是參加培訓(xùn)班好?

    Java是自學(xué)好還是參加培訓(xùn)班好?

    這篇文章主要介紹了Java是自學(xué)好還是參加培訓(xùn)班好這一問題,給大家介紹了哪些人適合自學(xué)java,哪些人適合java培訓(xùn)班學(xué)習(xí),大家可以看看內(nèi)容詳情
    2018-04-04
  • Servlet機(jī)制Pushlet原理及用法詳解

    Servlet機(jī)制Pushlet原理及用法詳解

    這篇文章主要介紹了Servlet機(jī)制Pushlet原理及用法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-10-10
  • Java經(jīng)典用法總結(jié)

    Java經(jīng)典用法總結(jié)

    這篇文章主要介紹了Java經(jīng)典用法總結(jié),在本文中,盡量收集一些java最常用的習(xí)慣用法,特別是很難猜到的用法,感興趣的小伙伴們可以參考一下
    2016-02-02
  • Java中的snowflake算法詳解

    Java中的snowflake算法詳解

    這篇文章主要介紹了Java中的snowflake算法詳解,Snowflake算法產(chǎn)生是為了滿足Twitter每秒上萬條消息的請求,每條消息都必須分配一條唯一的id,這些id還需要一些大致的順序,并且在分布式系統(tǒng)中不同機(jī)器產(chǎn)生的id必須不同,需要的朋友可以參考下
    2023-08-08
  • Object類toString()和equals()方法使用解析

    Object類toString()和equals()方法使用解析

    這篇文章主要介紹了Object類toString()和equals()方法使用解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-02-02
  • Java數(shù)據(jù)結(jié)構(gòu)之基于比較的排序算法基本原理及具體實現(xiàn)

    Java數(shù)據(jù)結(jié)構(gòu)之基于比較的排序算法基本原理及具體實現(xiàn)

    最近剛學(xué)習(xí)完七種比較常見的基于比較的排序算法,感覺比較重要,所以寫個博客記錄一下,通讀本篇對大家的學(xué)習(xí)或工作具有一定的價值,需要的朋友可以參考下
    2021-09-09
  • 使用import導(dǎo)入靜態(tài)成員的方法

    使用import導(dǎo)入靜態(tài)成員的方法

    這篇文章主要介紹了淺談使用import導(dǎo)入靜態(tài)成員,需要的朋友可以參考下。
    2017-09-09

最新評論

嘉祥县| 突泉县| 察雅县| 鄄城县| 岳西县| 冷水江市| 元谋县| 云霄县| 东山县| 汤阴县| 潜山县| 翁牛特旗| 屯留县| 和静县| 化州市| 鹤峰县| 新泰市| 安平县| 瓮安县| 巢湖市| 徐汇区| 和田市| 江孜县| 开封市| 东丽区| 湖南省| 巴林左旗| 浪卡子县| 上饶市| 阿尔山市| 玉林市| 北川| 铜鼓县| 岳西县| 桃源县| 博乐市| 方山县| 东兰县| 平塘县| 阳曲县| 福建省|