dbc数据库官网_使用Spring和R2DBC进行React式关系数据库访问的简介

dbc数据库官网

by Daniel Newton

丹尼尔·牛顿

使用Spring和R2DBC进行React式关系数据库访问的简介 (An introduction to Reactive Relational Database Access with Spring and R2DBC)

Not too long ago, a reactive variant of the JDBC driver was released, known as R2DBC. It allows data to be streamed asynchronously to any endpoints that have subscribed to it. Using a reactive driver like R2DBC together with Spring, WebFlux allows you to write a full application that handles receiving and sending of data asynchronously.

不久前,发布了JDBC驱动程序的React型,称为R2DBC。 它允许将数据异步流传输到已预订的任何端点。 通过将R2DBC之类的React式驱动程序与Spring一起使用,WebFlux允许您编写一个完整的应用程序,该应用程序可以异步处理数据的接收和发送。

In this post, we will focus on the database, from connecting to the database and then finally saving and retrieving data. To do this, we will be using Spring Data. As with all Spring Data modules, it provides us with out of the box configuration. This decreases the amount of boilerplate code that we need to write to get our application setup. On top of that, it provides a layer upon the database driver that makes doing the simple tasks easier and the more difficult tasks a little less painful.

在本文中,我们将重点介绍数据库,从连接到数据库,然后最后保存和检索数据。 为此,我们将使用Spring Data。 与所有Spring Data模块一样,它为我们提供了现成的配置。 这减少了为获得应用程序设置而需要编写的样板代码量。 最重要的是,它在数据库驱动程序上提供了一层,使执行简单任务变得更加容易,而较困难的任务则减轻了一些痛苦。

For the content of this post, I am making use of a Postgres database. At the time of writing, only Postgres, H2 and Microsoft SQL Server have their own implementations of R2DBC drivers.

对于本文的内容,我正在使用Postgres数据库。 在撰写本文时,只有Postgres,H2和Microsoft SQL Server拥有自己的R2DBC驱动程序实现。

I have previously written two posts about reactive Spring Data libraries, one on Mongo and another about Cassandra. You might have noticed that neither of these databases are RDBMS databases. Now there are other reactive drivers available for a long time (I wrote the Mongo post nearly 2 years ago) but at the time of writing a reactive driver for a RDBMS database is still a pretty new thing. This post will follow a similar format to those.

之前,我曾写过两篇有关React式Spring Data库的文章,一篇关于Mongo ,另一篇关于Cassandra 。 您可能已经注意到,这些数据库都不是RDBMS数据库。 现在有很长一段时间都可以使用其他React式驱动程序(我将近两年前写了Mongo文章),但是在为RDBMS数据库编写React式驱动程序时,这仍然是一件很新的事情。 这篇文章将采用类似的格式。

Furthermore, I have also written a post about using Spring WebFlux which I mentioned in the introduction. Feel free to have a look at that if you are interested in producing a fully reactive web application.

此外,我还写了一篇关于使用Spring WebFlux的文章 ,我在引言中提到过。 如果您有兴趣生产完全React式的Web应用程序,请随时查看。

依存关系 (Dependencies)

There are a few things to point out here.

这里有几点要指出。

The more you use Spring Boot, the more you will get used to importing a single spring-boot-starter dependency for the cool thing that you want to do. For example, I hoped that there would have been a spring-boot-starter-r2dbc dependency, but unfortunately, there is not one. Yet.

使用Spring Boot的次数越多,就越会习惯于为您想做的很酷的事情导入单个spring-boot-starter依赖项。 例如,我希望会有spring-boot-starter-r2dbc依赖关系,但不幸的是,没有依赖关系。 然而。

Simply put, this library is on the newer side and at the time of writing, does not have its own Spring Boot module that contains any dependencies it needs along with faster setup via auto-configuration. I am sure these things will come at some point and make setting up a R2DBC driver even easier.

简而言之,该库是较新的方面,在编写本文时,它没有自己的Spring Boot模块,该模块包含所需的任何依赖项以及通过自动配置的更快设置。 我确信这些事情会在某个时候出现,并使设置R2DBC驱动程序更加容易。

For now, we will need to fill in a few extra dependencies manually.

现在,我们将需要手动填写一些额外的依赖项。

Furthermore, the R2DBC libraries only have Milestone releases (more proof of them being new) so we need to make sure we bring in the Spring Milestone repository. I will probably need to update this post in the future when it gets a release version.

此外,R2DBC库仅具有里程碑版本(更多证明它们是新发布的),因此我们需要确保引入Spring Milestone存储库。 当我获得发布版本时,将来可能会需要更新此帖子。

连接到数据库 (Connecting to the database)

Thanks to Spring Data doing a lot of the work for us, the only Bean that needs to be created manually is the ConnectionFactory that contains the database’s connection details:

由于Spring Data为我们做了很多工作,因此唯一需要手动创建的Bean是ConnectionFactory ,其中包含数据库的连接详细信息:

The first thing to notice here is the extension of AbstractR2dbcConfiguration. This class contains a load of Beans that we no longer need to manually create. Implementing connectionFactory is the only requirement of the class as it is required to create the DatabaseClient Bean. This sort of structure is typical of Spring Data modules, so it feels quite familiar when trying out a different one. Furthermore, I’d expect this manual configuration to be removed once auto-configuration is available and be solely driven via the application.properties.

这里首先要注意的是AbstractR2dbcConfiguration的扩展。 此类包含大量不再需要手动创建的Bean。 实现connectionFactory是该类的唯一要求,因为创建DatabaseClient Bean是必需的。 这种结构是Spring Data模块的典型结构,因此在尝试其他结构时会感到非常熟悉。 此外,我希望一旦有自动配置,就可以删除此手动配置,并且可以通过application.properties单独驱动。

I have included the port property here, but if you have not played around with your Postgres configuration then you can rely on the default value of 5432.

我在此处包括了port属性,但是如果您还没有使用Postgres配置,那么可以依靠默认值5432

The four properties: host, database, username and password defined by the PostgresqlConnectionFactory are the bare minimum to get it working. Any less and you will experience exceptions during startup.

PostgresqlConnectionFactory定义的四个属性: hostdatabaseusernamepassword是使它正常工作的最低要求。 少了一点,您将在启动过程中遇到异常。

Using this configuration, Spring is able to connect to a running Postgres instance.

使用此配置,Spring可以连接到正在运行的Postgres实例。

The final piece of noteworthy information from this example is the use of @EnableR2dbcRepositories. This annotation instructs Spring to find any repository interfaces that extend Spring’s Repository interface. This is used as the base interface for instrumenting Spring Data repositories. We will look at this a little closer in the next section. The main piece of information to take away from here is that you need to use the @EnableR2dbcRepositories annotation to fully leverage Spring Data’s capabilities.

该示例中最后一个值得注意的信息是@EnableR2dbcRepositories的使用。 该注释指示Spring查找扩展Spring的Repository接口的任何存储Repository接口。 这用作检测Spring Data存储库的基本接口。 我们将在下一部分中对此进行更仔细的研究。 从这里获得的主要信息是,您需要使用@EnableR2dbcRepositories批注以充分利用Spring Data的功能。

创建一个Spring数据仓库 (Creating a Spring Data Repository)

As touched on above, in this section we will look at adding a Spring Data Repository. These repositories are a nice feature of Spring Data, meaning that you don’t need to write out a load of extra code to simply write a query.

如上所述,在本节中,我们将介绍添加Spring Data Repository。 这些存储库是Spring Data的一个不错的功能,这意味着您无需写出额外的代码即可简单地编写查询。

Unfortunately, at least for now, Spring R2DBC cannot infer queries in the same way that other Spring Data modules currently do (I am sure this will be added at some point). This means that you will need to use the @Query annotation and write the SQL by hand. Let’s take a look:

不幸的是,至少就目前而言,Spring R2DBC无法以与其他Spring Data模块当前相同的方式来推断查询(我肯定会在某个时候添加它)。 这意味着您将需要使用@Query批注并手动编写SQL。 让我们来看看:

This interface extends R2dbcRepository. This in turn extends ReactiveCrudRepository and then down to Repository. ReactiveCrudRepository provides the standard CRUD functions and from what I understand, R2dbcRepository does not provide any extra functions and is instead an interface created for better situational naming.

该接口扩展了R2dbcRepository 。 这又扩展了ReactiveCrudRepository ,然后扩展到RepositoryReactiveCrudRepository提供了标准的CRUD功能,据我了解, R2dbcRepository不提供任何其他功能,而是为更好的情境命名而创建的接口。

R2dbcRepository takes in two generic parameters, one being the entity class that it takes as input and produces as output. The second being the type of the Primary Key. Therefore in this situation, the Person class is being managed by the PersonRepository (makes sense) and the Primary Key field inside Person is an Int.

R2dbcRepository接受两个通用参数,一个是它作为输入并作为输出产生的实体类。 第二个是主键的类型。 因此,在这种情况下, Person类由PersonRepository管理(有意义),并且Person内部的主键字段是Int

The return types of functions in this class and the ones provided by ReactiveCrudRepository are Flux and Mono (not seen here). These are Project Reactor types that Spring makes use of as the default Reactive Stream types. Flux represents a stream of multiple elements whereas a Mono is a single result.

此类中的函数以及ReactiveCrudRepository提供的函数的返回类型为FluxMono (此处未显示)。 这些是Spring用作默认React流类型的Project Reactor类型。 Flux代表多个元素的流,而Mono则是单个结果。

Finally, as I mentioned before the example, each function is annotated with @Query. The syntax is quite straight forward, with the SQL being a string inside the annotation. The $1 ($2, $3, etc… for more inputs) represents the value input into the function. Once you have done this, Spring will handle the rest and pass the input(s) into their respective input parameter, gather the results and map it to the repository’s designated entity class.

最后,正如我在示例之前提到的那样,每个函数都使用@Query注释。 语法非常简单,SQL是注释中的字符串。 $1 (用于更多输入的$2$3等)表示输入到函数中的值。 完成此操作后,Spring将处理其余部分,并将输入传递到各自的输入参数中,收集结果并将其映射到存储库的指定实体类。

快速浏览实体 (A very quick look at the entity)

Not going to say much here but simply show the Person class used by the PersonRepository.

在这里不多说,仅显示PersonRepository使用的Person类。

Actually, there is one point to make here. id has been made nullable and provided a default value of null to allow Postgres to generate the next suitable value itself. If this is not nullable and an id value is provided, Spring will actually try to run an update instead of an insert upon saving. There are other ways around this, but I think this is good enough.

实际上,这里有一点需要说明。 id已设置为可为空,并提供默认值null以允许Postgres自身生成下一个合适的值。 如果这不能为空并且提供了一个id值,那么Spring在保存时实际上将尝试运行更新而不是插入操作。 还有其他解决方法,但是我认为这已经足够了。

This entity will map to the people table defined below:

该实体将映射到下面定义的people表:

看到一切都在行动 (Seeing it all in action)

Now let’s have a look at it actually doing something. Below is some code that inserts a few records and retrieves them in a few different ways:

现在让我们看看它实际上在做什么。 下面是一些插入一些记录并以几种不同方式检索它们的代码:

One thing I will mention about this code. There is a very real possibility that it executes without actually inserting or reading some of the records. But, when you think about it, it makes sense. Reactive applications are meant to do things asynchronously and therefore this application has started processing the function calls in different threads. Without blocking the main thread, these asynchronous processes might never fully execute. For this reason, there are some Thread.sleep calls in this code, but I removed them from the example to keep everything tidy.

关于此代码,我将提到一件事。 它很可能在没有实际插入或读取某些记录的情况下执行。 但是,当您考虑它时,这是有道理的。 React性应用程序旨在异步执行操作,因此该应用程序已开始处理不同线程中的函数调用。 如果不阻塞主线程,这些异步进程可能永远不会完全执行。 因此,此代码中有一些Thread.sleep调用,但我从示例中删除了它们,以使所有内容保持整洁。

The output for running the code above would look something like the below:

运行上面的代码的输出如下所示:

[ main] onSubscribe(FluxConcatMap.ConcatMapImmediate)[ main] request(unbounded)[actor-tcp-nio-1] onNext(Person(id=35, name=Dan Newton, age=25))[actor-tcp-nio-1] onNext(Person(id=36, name=Laura So, age=23))[actor-tcp-nio-1] onComplete()[actor-tcp-nio-2] findAll - Person(id=35, name=Dan Newton, age=25)[actor-tcp-nio-2] findAll - Person(id=36, name=Laura So, age=23)[actor-tcp-nio-4] findAllByName - Person(id=36, name=Laura So, age=23)[actor-tcp-nio-5] findAllByAge - Person(id=35, name=Dan Newton, age=25)

A few things to take away here:

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

  • onSubscribe and request occur on the main thread where the Flux was called from. Only saveAll outputs this since it has included the log function. Adding this to the other calls would have lead to the same result of logging to the main thread.

    onSubscriberequest发生在调用Flux的主线程上。 仅saveAll输出此内容,因为它已包含log功能。 将其添加到其他调用中将导致记录到主线程的结果相同。

  • The execution contained within the subscribe function and the internal steps of the Flux are run on separate threads.

    subscription函数中包含的执行和Flux的内部步骤在单独的线程上运行。

This is not anywhere close to a real representation of how you would use Reactive Streams in an actual application but hopefully demonstrates how to use them and gives a bit of insight into how they execute.

这与在实际应用程序中如何使用React式流的真实表示不尽相同,但希望能演示如何使用它们,并对它们的执行方式提供一些见解。

结论 (Conclusion)

In conclusion, Reactive Streams have come to some RDBMS databases thanks to the R2DBC driver and Spring Data that builds a layer on top to make everything a bit tidier. By using Spring Data R2DBC we are able to create a connection to a database and start querying it without the need of too much code.

总之,由于R2DBC驱动程序和Spring Data在顶部建立了一层,使所有内容变得更加整洁,因此Reactive Streams进入了某些RDBMS数据库。 通过使用Spring Data R2DBC,我们可以创建到数据库的连接并开始查询它,而无需太多的代码。

Although Spring is already doing a lot for us, it could be doing more. Currently, it does not have Spring Boot auto-configuration support. Which is a bit annoying. But, I am sure that someone will get around to doing it soon and make everything even better than it already is.

尽管Spring已经为我们做了大量工作,但它可能会做更多的事情。 当前,它不具有Spring Boot自动配置支持。 这有点烦人。 但是,我相信有人很快就会做起来,并使所有事情变得比现在更好。

The code used in this post can be found on my GitHub.

这篇文章中使用的代码可以在我的GitHub上找到

If you found this post helpful, you can follow me on Twitter at @LankyDanDev to keep up with my new posts.

如果您发现此帖子有帮助,可以在Twitter上@LankyDanDev关注我,以跟上我的新帖子。

View all posts by Dan Newton

查看丹·牛顿的所有文章

Originally published at lankydanblog.com on February 16, 2019.

最初于2019年2月16日发布在lankydanblog.com上。

翻译自: https://www.freecodecamp.org/news/an-introduction-to-reactive-relational-database-access-with-spring-and-r2dbc-1a9447d4b122/

dbc数据库官网

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值