日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

r2dbc_使用Spring Data R2DBC进行异步RDBMS访问

發(fā)布時間:2023/12/3 javascript 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 r2dbc_使用Spring Data R2DBC进行异步RDBMS访问 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

r2dbc

不久之前,發(fā)布了JDBC驅(qū)動程序的React性變體。 稱為R2DBC。 它允許將數(shù)據(jù)異步流傳輸?shù)揭杨A(yù)訂的任何端點(diǎn)。 通過將R2DBC之類的React性驅(qū)動程序與Spring WebFlux結(jié)合使用,可以編寫一個完整的應(yīng)用程序,以異步方式處理數(shù)據(jù)的接收和發(fā)送。 在本文中,我們將重點(diǎn)介紹數(shù)據(jù)庫。 從連接到數(shù)據(jù)庫,然后最終保存和檢索數(shù)據(jù)。 為此,我們將使用Spring Data。 與所有Spring Data模塊一樣,它為我們提供了現(xiàn)成的配置。 減少為實(shí)現(xiàn)應(yīng)用程序設(shè)置而需要編寫的樣板代碼數(shù)量。 最重要的是,它在數(shù)據(jù)庫驅(qū)動程序上提供了一層,使執(zhí)行簡單任務(wù)變得更加容易,而較困難的任務(wù)則減輕了一些痛苦。

對于本文的內(nèi)容,我正在使用Postgres數(shù)據(jù)庫。 在撰寫本文時,僅Postgres,H2和Microsoft SQL Server具有自己的R2DBC驅(qū)動程序?qū)崿F(xiàn)。

之前,我曾寫過兩篇有關(guān)React式Spring Data庫的文章,一篇關(guān)于Mongo ,另一篇關(guān)于Cassandra 。 您可能已經(jīng)注意到,這些數(shù)據(jù)庫都不是RDBMS數(shù)據(jù)庫。 現(xiàn)在有很長一段時間都可以使用其他React式驅(qū)動程序(我將近兩年前寫了Mongo文章),但是在為RDBMS數(shù)據(jù)庫編寫React式驅(qū)動程序時,這仍然是一件很新的事情。 這篇文章將遵循類似的格式。

此外,我還寫了一篇關(guān)于使用Spring WebFlux的文章 ,我在引言中提到過。 如果您有興趣生產(chǎn)完全React式的Web應(yīng)用程序,請隨時查看。

依存關(guān)系

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-r2dbc</artifactId><version>1.0.0.M1</version></dependency><dependency><groupId>io.r2dbc</groupId><artifactId>r2dbc-postgresql</artifactId><version>1.0.0.M6</version></dependency><dependency><groupId>io.projectreactor</groupId><artifactId>reactor-core</artifactId></dependency> </dependencies><repositories><repository><id>repository.spring.milestone</id><name>Spring Milestone Repository</name><url>http://repo.spring.io/milestone</url></repository> </repositories>

這里有幾點(diǎn)要指出。

使用Spring Boot的次數(shù)越多,就越會習(xí)慣于為您想做的很酷的事情導(dǎo)入單個spring-boot-starter依賴項(xiàng)。 例如,我希望會有spring-boot-starter-r2dbc依賴關(guān)系,但不幸的是,沒有依賴關(guān)系。 然而。 簡而言之,該庫位于較新的一側(cè),在編寫本文時,它沒有自己的Spring Boot模塊,該模塊包含所需的任何依賴項(xiàng)以及通過自動配置的更快設(shè)置。 我確信這些事情會在某個時候出現(xiàn),并使設(shè)置R2DBC驅(qū)動程序變得更加容易。

現(xiàn)在,我們將需要手動填寫一些額外的依賴項(xiàng)。

此外,R2DBC庫僅具有Milestone版本(更多證明它們是新版本),因此我們需要確保引入Spring Milestone存儲庫。 當(dāng)我獲得發(fā)布版本時,將來可能會需要更新此帖子。

連接到數(shù)據(jù)庫

由于Spring Data為我們做了很多工作,因此唯一需要手動創(chuàng)建的Bean是ConnectionFactory ,其中包含數(shù)據(jù)庫的連接詳細(xì)信息:

@Configuration @EnableR2dbcRepositories class DatabaseConfiguration(@Value("\${spring.data.postgres.host}") private val host: String,@Value("\${spring.data.postgres.port}") private val port: Int,@Value("\${spring.data.postgres.database}") private val database: String,@Value("\${spring.data.postgres.username}") private val username: String,@Value("\${spring.data.postgres.password}") private val password: String ) : AbstractR2dbcConfiguration() {override fun connectionFactory(): ConnectionFactory {return PostgresqlConnectionFactory(PostgresqlConnectionConfiguration.builder().host(host).port(port).database(database).username(username).password(password).build())} }

這里首先要注意的是AbstractR2dbcConfiguration的擴(kuò)展。 此類包含大量我們不再需要手動創(chuàng)建的Bean。 實(shí)現(xiàn)connectionFactory是該類的唯一要求,因?yàn)閯?chuàng)建DatabaseClient Bean是必需的。 這種結(jié)構(gòu)是Spring Data模塊的典型結(jié)構(gòu),因此在嘗試其他結(jié)構(gòu)時會感到非常熟悉。 此外,我希望一旦可以使用自動配置,就可以刪除此手動配置,并且可以通過application.properties單獨(dú)驅(qū)動。

我在此處包括了port屬性,但是如果您還沒有使用Postgres配置,那么可以依靠默認(rèn)值5432 。

PostgresqlConnectionFactory定義的四個屬性: host , database , username和password是使它正常工作的最低要求。 少了一點(diǎn),您將在啟動過程中遇到異常。

使用此配置,Spring可以連接到正在運(yùn)行的Postgres實(shí)例。

該示例中最后一個值得注意的信息是@EnableR2dbcRepositories的使用。 該注釋指示Spring查找擴(kuò)展Spring的Repository接口的任何存儲Repository接口。 這用作檢測Spring Data存儲庫的基本接口。 我們將在下一部分中對此進(jìn)行更仔細(xì)的研究。 從這里獲得的主要信息是,您需要使用@EnableR2dbcRepositories批注以充分利用Spring Data的功能。

創(chuàng)建一個Spring數(shù)據(jù)倉庫

如上所述,在本節(jié)中,我們將介紹添加Spring Data Repository。 這些存儲庫是Spring Data的一個不錯的功能,這意味著您無需寫很多額外的代碼即可簡單地編寫查詢。 不幸的是,至少到目前為止,Spring R2DBC不能像其他Spring Data模塊那樣以同樣的方式推斷查詢(我肯定會在某個時候添加它)。 這意味著您將需要使用@Query批注并手動編寫SQL。 讓我們來看看:

@Repository interface PersonRepository : R2dbcRepository<Person, Int> {@Query("SELECT * FROM people WHERE name = $1")fun findAllByName(name: String): Flux<Person>@Query("SELECT * FROM people WHERE age = $1")fun findAllByAge(age: Int): Flux<Person> }

該接口擴(kuò)展了R2dbcRepository 。 這依次擴(kuò)展了ReactiveCrudRepository ,然后向下擴(kuò)展到Repository 。 ReactiveCrudRepository提供了標(biāo)準(zhǔn)的CRUD功能,據(jù)我了解, R2dbcRepository不提供任何額外的功能,而是為更好的情境命名而創(chuàng)建的接口。

R2dbcRepository接受兩個通用參數(shù),一個是它作為輸入并作為輸出產(chǎn)生的實(shí)體類。 第二個是主鍵的類型。 因此,在這種情況下, Person類由PersonRepository管理(有意義),并且Person內(nèi)部的主鍵字段是Int 。

此類中的函數(shù)以及ReactiveCrudRepository提供的函數(shù)的返回類型為Flux和Mono (此處未顯示)。 這些是Spring用作默認(rèn)React流類型的Project Reactor類型。 Flux代表多個元素的流,而Mono則是單個結(jié)果。

最后,正如我在示例之前提到的那樣,每個函數(shù)都使用@Query注釋。 語法非常簡單,SQL是注釋中的字符串。 $1 (用于更多輸入的$2 , $3等)表示輸入到函數(shù)中的值。 完成此操作后,Spring將處理其余部分,并將輸入傳遞到各自的輸入?yún)?shù)中,收集結(jié)果并將其映射到存儲庫的指定實(shí)體類。

快速瀏覽實(shí)體

在這里不多說,僅顯示PersonRepository使用的Person類。

@Table("people") data class Person(@Id val id: Int? = null,val name: String,val age: Int )

實(shí)際上,這里有一點(diǎn)需要說明。 id已設(shè)置為可為空,并提供默認(rèn)值null以允許Postgres自身生成下一個合適的值。 如果這不能為空并且提供了一個id值,那么Spring在保存時實(shí)際上將嘗試運(yùn)行更新而不是插入操作。 還有其他解決方法,但是我認(rèn)為這已經(jīng)足夠了。

該實(shí)體將映射到下面定義的people表:

CREATE TABLE people (id SERIAL PRIMARY KEY, name VARCHAR NOT NULL, age INTEGER NOT NULL );

看到一切都在行動

現(xiàn)在讓我們看看它實(shí)際上在做什么。 下面是一些插入一些記錄并以幾種不同方式檢索它們的代碼:

@SpringBootApplication class Application : CommandLineRunner {@Autowiredprivate lateinit var personRepository: PersonRepositoryoverride fun run(vararg args: String?) {personRepository.saveAll(listOf(Person(name = "Dan Newton", age = 25),Person(name = "Laura So", age = 23))).log().subscribe()personRepository.findAll().subscribe { log.info("findAll - $it") }personRepository.findAllById(Mono.just(1)).subscribe { log.info("findAllById - $it") }personRepository.findAllByName("Laura So").subscribe { log.info("findAllByName - $it") }personRepository.findAllByAge(25).subscribe { log.info("findAllByAge - $it") }} }

關(guān)于此代碼,我將提到一件事。 它很可能在沒有實(shí)際插入或讀取某些記錄的情況下執(zhí)行。 但是,當(dāng)您考慮它時。 這說得通。 React性應(yīng)用程序旨在異步執(zhí)行操作,因此該應(yīng)用程序已開始處理不同線程中的函數(shù)調(diào)用。 如果不阻塞主線程,這些異步進(jìn)程可能永遠(yuǎn)不會完全執(zhí)行。 因此,此代碼中有一些Thread.sleep調(diào)用,但我從示例中刪除了它們,以使所有內(nèi)容保持整潔。

運(yùn)行上面的代碼的輸出如下所示:

2019-02-11 09:04:52.294 INFO 13226 --- [ main] reactor.Flux.ConcatMap.1 : onSubscribe(FluxConcatMap.ConcatMapImmediate) 2019-02-11 09:04:52.295 INFO 13226 --- [ main] reactor.Flux.ConcatMap.1 : request(unbounded) 2019-02-11 09:04:52.572 INFO 13226 --- [actor-tcp-nio-1] reactor.Flux.ConcatMap.1 : onNext(Person(id=35, name=Dan Newton, age=25)) 2019-02-11 09:04:52.591 INFO 13226 --- [actor-tcp-nio-1] reactor.Flux.ConcatMap.1 : onNext(Person(id=36, name=Laura So, age=23)) 2019-02-11 09:04:52.591 INFO 13226 --- [actor-tcp-nio-1] reactor.Flux.ConcatMap.1 : onComplete() 2019-02-11 09:04:54.472 INFO 13226 --- [actor-tcp-nio-2] com.lankydanblog.tutorial.Application : findAll - Person(id=35, name=Dan Newton, age=25) 2019-02-11 09:04:54.473 INFO 13226 --- [actor-tcp-nio-2] com.lankydanblog.tutorial.Application : findAll - Person(id=36, name=Laura So, age=23) 2019-02-11 09:04:54.512 INFO 13226 --- [actor-tcp-nio-4] com.lankydanblog.tutorial.Application : findAllByName - Person(id=36, name=Laura So, age=23) 2019-02-11 09:04:54.524 INFO 13226 --- [actor-tcp-nio-5] com.lankydanblog.tutorial.Application : findAllByAge - Person(id=35, name=Dan Newton, age=25)

這里有一些要注意的地方:

  • onSubscribe和request發(fā)生在調(diào)用Flux的主線程上。 僅saveAll輸出此內(nèi)容,因?yàn)樗寻琹og功能。 將其添加到其他調(diào)用中將導(dǎo)致記錄到主線程的結(jié)果相同。
  • subscription函數(shù)中包含的執(zhí)行和Flux的內(nèi)部步驟在單獨(dú)的線程上運(yùn)行。

這與在實(shí)際應(yīng)用程序中如何使用React式流的真實(shí)表示不盡相同,但是希望可以演示如何使用它們,并對它們的執(zhí)行方式提供一些見解。

結(jié)論

總之,由于R2DBC驅(qū)動程序和Spring Data在頂部建立了一層,使所有內(nèi)容變得更加整潔,因此Reactive Streams進(jìn)入了某些RDBMS數(shù)據(jù)庫。 通過使用Spring Data R2DBC,我們可以創(chuàng)建與數(shù)據(jù)庫的連接并開始查詢它,而無需太多代碼。 盡管Spring已經(jīng)為我們做了大量工作,但它可能會做更多的事情。 當(dāng)前,它不具有Spring Boot自動配置支持。 這有點(diǎn)煩人。 但是,我相信有人很快就會做起來并使所有事情變得比現(xiàn)在更好。

這篇文章中使用的代碼可以在我的GitHub上找到 。

翻譯自: https://www.javacodegeeks.com/2019/02/asynchronous-rdbms-access-spring-r2dbc.html

r2dbc

總結(jié)

以上是生活随笔為你收集整理的r2dbc_使用Spring Data R2DBC进行异步RDBMS访问的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。