20-06-19
banq
在本文中,让我们看一下用于Postgres的Spring-Data-R2DBC驱动程序,以进行响应式CRUD操作。
完整的代码在这里
使用Spring Boot版本2.3.1,JDK版本14和Gradle作为构建工具。如果您不熟悉Gradle,则可以自由选择Maven作为构建工具。
首先,R2DBC项目是最近的。目前,只有Postgres,MSSQL和H2具有R2DBC驱动程序。此外,我们不能将其与所有Spring Boot功能一起使用。因此,我们需要手动添加一些步骤。
在您的Postgres数据库中创建一个表。
CREATE TABLE product ( id integer, description character varying(255), price numeric, PRIMARY KEY (id) ); |
数据实体:
@Data @ToString public class Product implements Persistable<Integer> { @Id private Integer id; private String description; private Double price; @Transient private boolean newProduct; @Override @Transient public boolean isNew() { return this.newProduct || id == null; } public Product setAsNew() { this.newProduct = true; return this; } } |
记住这里我们正在实现Persistable接口。根据您提供的@Id,持久库确定该行是新行还是应该存在。如果您的实体实施Persistable,使用save(…)保存结果时,根据isNew()来确定是否实现数据库的INSERT或UPDATE。
使用数据库时,我们需要一个连接工厂。因此,当然,R2DBC也需要同样的东西。
因此,我们现在将添加详细信息以连接到我们的实例:
@Configuration public class R2DBCConfig { @Bean public ConnectionFactory connectionFactory() { return ConnectionFactories.get( ConnectionFactoryOptions.builder() .option(DRIVER, "postgresql") .option(HOST, "localhost") .option(PORT, 5432) .option(USER, "postgres") .option(PASSWORD, "******") .option(DATABASE, "postgres") .option(MAX_SIZE, 40) .build()); } } |
存储库负责持久化实体和值类型。他们为客户提供了一个简单的模型,用于获取持久性对象并管理其生命周期。它们使应用程序和领域设计与持久性技术和策略选择脱钩。他们还传达有关对象访问的设计决策。最后,它们允许用虚拟实现轻松替换实现,是测试的理想选择。Spring Data的存储库通过接口定义支持所有这些目标,这些定义的实现是在框架启动时由框架创建的。
创建一个Spring Data存储库:
@Repository public interface ProductRepository extends ReactiveCrudRepository<Product, Integer> { } |
Spring Framework 5改变了一切。Spring Framework 5假定使用Java 8基线,并具有lambda和无限的功能性可能性!
我们在反应式Web应用程序中所做的许多事情都使其具有函数性编程风格。Spring Framework 5首次推出了一种新的功能性反应式编程模型,该模型与Spring WebFlux中的控制器风格的编程模型相似。这个新的编程模型仅在Spring WebFlux中可用。
@Configuration public class ProductsEndpointConfig { private static final String PRODUCT = "/product"; @Bean RouterFunction<ServerResponse> routes(ProductHandler handler) { return route(GET(PRODUCT), handler::all) .andRoute(POST(PRODUCT), handler::create) .andRoute(DELETE(PRODUCT + "/{id}"), handler::deleteById); } } |
Spring WebFlux提供了一个DSL,用于描述如何匹配传入的请求。GET("/product")让RequestPredicate与通过GET方法到URI /product的HTTP 方法请求匹配。您可以组合RequestPredicate:.and(RequestPredicate),.not(RequestPredicate)或.or(RequestPredicate)。
匹配请求后,HandlerFunction<ServerResponse>被调用来产生响应。让我们看一下相应的处理程序对象。
@Component public class ProductHandler { final ProductService productService; public ProductHandler(ProductService productService) { this.productService = productService; } public Mono<ServerResponse> create(ServerRequest request) { Flux<Product> flux = request .bodyToFlux(Product.class) .flatMap(toWrite -> this.productService.updateProduct(toWrite)); return defaultWriteResponse(flux); } public Mono<ServerResponse> all(ServerRequest r) { return defaultReadResponse(this.productService.getAllProducts()); } public Mono<ServerResponse> deleteById(ServerRequest r) { return defaultReadResponse(this.productService.delete(id(r))); } private static Mono<ServerResponse> defaultReadResponse(Publisher<Product> products) { return ServerResponse .ok() .contentType(MediaType.APPLICATION_JSON) .body(products, Product.class); } private static Mono<ServerResponse> defaultWriteResponse(Publisher<Product> product) { return Mono .from(product) .flatMap(p -> ServerResponse .created(URI.create("/product")) .contentType(MediaType.APPLICATION_JSON) .build() ); } private static int id(ServerRequest r) { return Integer.parseInt(r.pathVariable("id")); } } |
主程序入口:
@SpringBootApplication @EnableR2dbcRepositories public class DemoReactiveRdbmsApplication { public static void main(String[] args) { SpringApplication.run(DemoReactiveRdbmsApplication.class, args); } } |
总而言之,R2DBC仍处于早期阶段。试图创建一个SPI,该SPI将为SQL数据库定义一个响应式API。当与Spring WebFlux一起使用时,R2DBC允许我们编写一个应用程序,该应用程序从顶部一直到数据库一直异步处理数据。
完整的代码在这里