r2dbc在Spring webFlux中怎么使用
r2dbc在Spring webFlux中怎么使用
这篇文章主要介绍“r2dbc在Spring webFlux中怎么使用”,在日常操作中,相信很多人在r2dbc在Spring webFlux中怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”r2dbc在Spring webFlux中怎么使用”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
r2dbc
Reactor还有基于其之上的Spring WebFlux框架。包括vert.x,rxjava等等reactive技术。我们实际上在应用层已经有很多优秀的响应式处理框架。
但是有一个问题就是所有的框架都需要获取底层的数据,而基本上关系型数据库的底层读写都还是同步的。
为了解决这个问题,出现了两个标准,一个是oracle提出的 ADBC (Asynchronous Database Access API),另一个就是Pivotal提出的R2DBC (Reactive Relational Database Connectivity)。
R2DBC是基于Reactive Streams标准来设计的。通过使用R2DBC,你可以使用reactive API来操作数据。
同时R2DBC只是一个开放的标准,而各个具体的数据库连接实现,需要实现这个标准。
工程依赖
以下是 pom.xml清单
<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="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.0https://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/><!--lookupparentfromrepository--></parent><groupId>wang.datahub</groupId><artifactId>springboot3demo</artifactId><version>0.0.1-SNAPSHOT</version><name>springboot3demo</name><description>DemoprojectforSpringBoot</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-h3</artifactId></dependency><dependency><groupId>com.h3database</groupId><artifactId>h3</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>SpringMilestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository><repository><id>spring-snapshots</id><name>SpringSnapshots</name><url>https://repo.spring.io/snapshot</url><releases><enabled>false</enabled></releases></repository></repositories><pluginRepositories><pluginRepository><id>spring-milestones</id><name>SpringMilestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></pluginRepository><pluginRepository><id>spring-snapshots</id><name>SpringSnapshots</name><url>https://repo.spring.io/snapshot</url><releases><enabled>false</enabled></releases></pluginRepository></pluginRepositories></project>
配置文件
这里我们只配置了r2dbc链接信息
配置类
用于配置默认链接,创建初始化数据
packagewang.datahub.springboot3demo.config;importio.netty.util.internal.StringUtil;importio.r2dbc.spi.ConnectionFactories;importio.r2dbc.spi.ConnectionFactory;importio.r2dbc.spi.ConnectionFactoryOptions;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.boot.CommandLineRunner;importorg.springframework.boot.context.properties.ConfigurationProperties;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importreactor.core.publisher.Flux;importstaticio.r2dbc.spi.ConnectionFactoryOptions.*;@Configuration@ConfigurationProperties(prefix="r2dbc")publicclassDBConfig{privateStringurl;privateStringuser;privateStringpassword;publicStringgetUrl(){returnurl;}publicvoidsetUrl(Stringurl){this.url=url;}publicStringgetUser(){returnuser;}publicvoidsetUser(Stringuser){this.user=user;}publicStringgetPassword(){returnpassword;}publicvoidsetPassword(Stringpassword){this.password=password;}@BeanpublicConnectionFactoryconnectionFactory(){System.out.println("url==>"+url);ConnectionFactoryOptionsbaseOptions=ConnectionFactoryOptions.parse(url);ConnectionFactoryOptions.Builderob=ConnectionFactoryOptions.builder().from(baseOptions);if(!StringUtil.isNullOrEmpty(user)){ob=ob.option(USER,user);}if(!StringUtil.isNullOrEmpty(password)){ob=ob.option(PASSWORD,password);}returnConnectionFactories.get(ob.build());}@BeanpublicCommandLineRunnerinitDatabase(ConnectionFactorycf){return(args)->Flux.from(cf.create()).flatMap(c->Flux.from(c.createBatch().add("droptableifexistsUsers").add("createtableUsers("+"idIDENTITY(1,1),"+"firstnamevarchar(80)notnull,"+"lastnamevarchar(80)notnull)").add("insertintoUsers(firstname,lastname)"+"values('Jacky','Li')").add("insertintoUsers(firstname,lastname)"+"values('Doudou','Li')").add("insertintoUsers(firstname,lastname)"+"values('Maimai','Li')").execute()).doFinally((st)->c.close())).log().blockLast();}}
bean
创建用户bean
packagewang.datahub.springboot3demo.bean;importorg.springframework.data.annotation.Id;publicclassUsers{@IdprivateLongid;privateStringfirstname;privateStringlastname;publicUsers(){}publicUsers(Longid,Stringfirstname,Stringlastname){this.id=id;this.firstname=firstname;this.lastname=lastname;}publicLonggetId(){returnid;}publicvoidsetId(Longid){this.id=id;}publicStringgetFirstname(){returnfirstname;}publicvoidsetFirstname(Stringfirstname){this.firstname=firstname;}publicStringgetLastname(){returnlastname;}publicvoidsetLastname(Stringlastname){this.lastname=lastname;}@OverridepublicStringtoString(){return"User{"+"id="+id+",firstname='"+firstname+'\''+",lastname='"+lastname+'\''+'}';}}
DAO
dao代码清单如下,包含查询列表、按id查询,以及创建用户等操作
packagewang.datahub.springboot3demo.dao;importio.r2dbc.spi.Connection;importio.r2dbc.spi.ConnectionFactory;importorg.springframework.data.r2dbc.core.R2dbcEntityTemplate;importorg.springframework.data.relational.core.query.Query;importorg.springframework.stereotype.Component;importreactor.core.publisher.Flux;importreactor.core.publisher.Mono;importwang.datahub.springboot3demo.bean.Users;importstaticorg.springframework.data.r2dbc.query.Criteria.where;importstaticorg.springframework.data.relational.core.query.Query.query;@ComponentpublicclassUsersDao{privateConnectionFactoryconnectionFactory;privateR2dbcEntityTemplatetemplate;publicUsersDao(ConnectionFactoryconnectionFactory){this.connectionFactory=connectionFactory;this.template=newR2dbcEntityTemplate(connectionFactory);}publicMono<Users>findById(longid){returnthis.template.selectOne(query(where("id").is(id)),Users.class);//returnMono.from(connectionFactory.create())//.flatMap(c->Mono.from(c.createStatement("selectid,firstname,lastnamefromUserswhereid=$1")//.bind("$1",id)//.execute())//.doFinally((st)->close(c)))//.map(result->result.map((row,meta)->//newUsers(row.get("id",Long.class),//row.get("firstname",String.class),//row.get("lastname",String.class))))//.flatMap(p->Mono.from(p));}publicFlux<Users>findAll(){returnthis.template.select(Users.class).all();//returnMono.from(connectionFactory.create())//.flatMap((c)->Mono.from(c.createStatement("selectid,firstname,lastnamefromusers")//.execute())//.doFinally((st)->close(c)))//.flatMapMany(result->Flux.from(result.map((row,meta)->{//Usersacc=newUsers();//acc.setId(row.get("id",Long.class));//acc.setFirstname(row.get("firstname",String.class));//acc.setLastname(row.get("lastname",String.class));//returnacc;//})));}publicMono<Users>createAccount(Usersaccount){returnMono.from(connectionFactory.create()).flatMap(c->Mono.from(c.beginTransaction()).then(Mono.from(c.createStatement("insertintoUsers(firstname,lastname)values($1,$2)").bind("$1",account.getFirstname()).bind("$2",account.getLastname()).returnGeneratedValues("id").execute())).map(result->result.map((row,meta)->newUsers(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(Connectionconnection){returnMono.from(connection.close()).then(Mono.empty());}}
controller
controller代码清单如下,包含了查询列表、按id查询,以及创建用户等操作
packagewang.datahub.springboot3demo.controller;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.http.HttpStatus;importorg.springframework.http.ResponseEntity;importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.*;importreactor.core.publisher.Flux;importreactor.core.publisher.Mono;importwang.datahub.springboot3demo.bean.Users;importwang.datahub.springboot3demo.dao.UsersDao;@RestControllerpublicclassUsersController{@AutowiredprivatefinalUsersDaousersDao;publicUsersController(UsersDaousersDao){this.usersDao=usersDao;}@GetMapping("/users/{id}")publicMono<ResponseEntity<Users>>getUsers(@PathVariable("id")Longid){returnusersDao.findById(id).map(acc->newResponseEntity<>(acc,HttpStatus.OK)).switchIfEmpty(Mono.just(newResponseEntity<>(null,HttpStatus.NOT_FOUND)));}@GetMapping("/users")publicFlux<Users>getAllAccounts(){returnusersDao.findAll();}@PostMapping("/createUser")publicMono<ResponseEntity<Users>>createUser(@RequestBodyUsersuser){returnusersDao.createAccount(user).map(acc->newResponseEntity<>(acc,HttpStatus.CREATED)).log();}}
启动类清单:
packagewang.datahub.springboot3demo;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.boot.context.properties.EnableConfigurationProperties;importwang.datahub.springboot3demo.config.DBConfig;@SpringBootApplication@EnableConfigurationProperties(DBConfig.class)publicclassWebFluxR2dbcApp{publicstaticvoidmain(String[]args){SpringApplication.run(WebFluxR2dbcApp.class,args);}}
到此,关于“r2dbc在Spring webFlux中怎么使用”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注恰卡编程网网站,小编会继续努力为大家带来更多实用的文章!
推荐阅读
-
spring(boot 自定义jar包 linux怎么部署springboot)
linux怎么部署springboot?Linux以两种部署springboot项目。部署jar包(官方推荐)在linux服务器上...
-
springboot静态资源路径虚拟映射(spring boot 中可以存放静态滋源文件的位置有)
springboot中可以存放静态滋源文件的位置有?springboot是实际不自动配置来实现的,其中静态资源配置共有是::/...
-
Spring Security 实战干货:手把手教你实现JWT Token
-
「web安全」Spring Boot eureka xstream 反序列化
-
spring中的特殊注解@RequiredArgsConstructor怎么用
spring中的特殊注解@RequiredArgsConstructor怎么用...
-
SpringBoot+Spring Security无法实现跨域怎么解决
-
Spring Security基于注解的接口角色访问控制怎么实现
-
Spring代理对象导致的获取不到原生对象注解怎么解决
Spring代理对象导致的获取不到原生对象注解怎么解决本文小编为大...
-
解析Spring漏洞及修复的方法
-
Spring和IDEA为什么都不推荐使用@Autowired注解