8.2.2 使用 Spring Data R2DBC 响应式持久化数据
在第 5 章中,你了解到 Spring Boot 应用程序与数据库之间的交互涉及数据库驱动程序、实体和仓库。你在 Spring Data JDBC 上下文中学习的相同概念也适用于 Spring Data R2DBC。Spring Data 提供了通用的抽象和模式,使导航不同模块变得简单直接。
与 Catalog Service 相比,Order Service 的主要区别在于数据库驱动程序的类型。JDBC 是 Java 应用程序与关系数据库通信最常用的驱动程序,但它不支持响应式编程。已经有一些尝试提供对关系数据库的响应式访问。一个脱颖而出且广泛支持的项目是 Reactive Relational Database Connectivity(R2DBC),由 Pivotal(现在是 VMware Tanzu)发起。R2DBC 驱动程序可用于所有主要数据库(如 PostgreSQL、MariaDB、MySQL、SQL Server 和 Oracle DB),并且有多个项目的客户端,包括使用 Spring Data R2DBC 的 Spring Boot 和 Testcontainers。
本节将指导你使用 Spring Data R2DBC 和 PostgreSQL 为 Order Service 定义域实体和持久化层。让我们开始吧。
为 Order Service 运行 PostgreSQL 数据库
首先,我们需要一个数据库。我们将采用每个服务一个数据库的方法来保持应用程序的松散耦合。决定 Catalog Service 和 Order Service 各有一个数据库后,我们有两个实际存储的选择。我们可以为两个数据库使用同一个数据库服务器,或者使用两个不同的服务器。为方便起见,我们将使用第 5 章中设置的同一个 PostgreSQL 服务器来托管 Catalog Service 使用的 polardb_catalog 数据库和 Order Service 使用的新 polardb_order 数据库。
转到你的 polar-deployment 仓库,创建一个新的 docker/postgresql 文件夹。然后在文件夹中添加一个新的 init.sql 文件。将以下代码添加到 init.sql 文件中;这是 PostgreSQL 在启动阶段应运行的初始化脚本。
代码清单 8.2 使用两个数据库初始化 PostgreSQL 服务器
CREATE DATABASE polardb_catalog;
CREATE DATABASE polardb_order;
接下来,打开 docker-compose.yml 文件并更新 PostgreSQL 容器定义以加载初始化脚本。记住删除 POSTGRES_DB 环境变量的值,因为我们现在将数据库创建委托给脚本。在本书的源代码中,参考 Chapter08/08-end/polar-deployment/docker 查看最终结果。
代码清单 8.3 从 SQL 脚本初始化 PostgreSQL 服务器
version: "3.8"
services:
# ... 其他服务
polar-postgres:
image: "postgres:14.4"
container_name: "polar-postgres"
ports:
- 5432:5432
environment:
# POSTGRES_DB 不再定义值
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
volumes:
# 将初始化 SQL 脚本挂载到容器作为卷
- ./postgresql/init.sql:/docker-entrypoint-initdb.d/init.sql
最后,基于新配置启动新的 PostgreSQL 容器。打开终端窗口,导航到定义 docker-compose.yml 文件的文件夹,运行以下命令:
$ docker-compose up -d polar-postgres
在本章的其余部分,我将假设你已经启动并运行了数据库。
使用 R2DBC 连接到数据库
Spring Boot 允许你通过 spring.r2dbc 属性配置响应式应用程序与关系数据库的集成。打开 Order Service 项目的 application.yml 文件,配置与 PostgreSQL 的连接。默认情况下启用连接池,你可以通过定义连接超时和大小来进一步配置它,就像你在第 5 章中为 JDBC 所做的那样。由于它是响应式应用程序,连接池可能比使用 JDBC 时小。你可以在正常条件下监控应用程序后调整值。
代码清单 8.4 通过 R2DBC 配置数据库集成
spring:
r2dbc:
username: user # 有权访问给定数据库的用户
password: password # 给定用户的密码
url: r2dbc:postgresql://localhost:5432/polardb_order
pool:
max-create-connection-time: 2s
initial-size: 5 # 连接池的初始大小
max-size: 10 # 连接池的最大大小
现在我们需要定义 Order 实体。