使用Spring Boot反應式R2DBC實現PostgreSQL的CRUD操作原始碼 - Rajesh

banq發表於2020-06-19

在本文中,讓我們看一下用於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允許我們編寫一個應用程式,該應用程式從頂部一直到資料庫一直非同步處理資料。

完整的程式碼在這裡

 

相關文章