Spring Data 2020.0 - Spring Data R2DBC 1.2 中的新增功能

工程 | Mark Paluch | 2020 年 11 月 18 日 | ...

此版本是 Spring 对 R2DBC 支持的一个重要里程碑。 Spring 对 R2DBC 的支持始于两年前的一个实验性项目,旨在评估反应式 SQL 集成可能的样子。 在此版本中,Spring Data R2DBC 进行了重大重构,将多个组件移动到专用的 spring-r2dbc 模块中,并弃用由 Spring Framework 提供的组件。 除此之外,Spring Data R2DBC 还包含以下最显著的更改

  • 通过 EntityCallback API 添加生命周期回调
  • 反应式审计
  • 传递 enum 值和 Postgres Geo 类型

Spring R2DBC

Spring Data R2DBC 现在基于 spring-r2dbc,这是 Spring Framework 中的一个新模块,附带核心 R2DBC 支持,例如 DatabaseClientConnectionFactoryInitializerR2dbcTransactionManager。 这些组件已被弃用,取而代之的是 Spring R2DBC 组件,并在下一个主要的 Spring Data R2DBC 版本中标记为移除。 请参阅迁移指南,了解有关弃用以及要使用的替代 API 的信息。

生命周期 EntityCallback API

Spring Data Moore 引入了 EntityCallback API,用于在加载、保存和删除操作时预处理和后处理实体。 在持久化操作期间调用实体回调,允许对实体进行原地修改,并在实体类不可变时返回新的对象实例。

通过返回 Publisher<T> 使 EntityCallback 接口启用反应式,其中 T 表示实体类型。 返回发布者允许使用订阅者上下文(就像对反应式审计所做的那样)或与其他在保存实体之前或加载实体之后执行 I/O 的反应式组件集成。

您可以将 EntityCallback 用于各种回调钩子。 以下示例定义了一个 BeforeConvertCallback,用于在 H2 序列中为 Customer 类型生成主键值(如果其标识符为 null

@Bean  
BeforeConvertCallback<Customer> idGeneratingCallback(DatabaseClient databaseClient) {  
  
   return (customer, sqlIdentifier) -> {  
  
      if (customer.getId() == null) {  
  
         return databaseClient.sql("SELECT primary_key.nextval") //  
  .map(row -> row.get(0, Long.class)) //  
  .first() //  
  .map(customer::withId);  
      }  
  
      return Mono.just(customer);  
   };  
}

您可以在 R2DBC EntityCallbacks 中的 R2DBC 参考文档中阅读更多相关信息。

传递 enum 值和 Postgres Geo 类型

Postgres 支持各种数据类型,其中的枚举和几何类型可以直接从 Spring Data R2DBC 使用。 默认情况下,Spring Data 通过使用枚举的 name() 方法来表示枚举值,从而将 enum 值转换为 String。 R2DBC Postgres(自 0.8.4 版本起)支持特定的编解码器,该编解码器接受 Java enum 类型并将这些类型映射到相应的 Postgres 枚举类型。

考虑以下 Java enum

enum Color {
	Blue, Green, White
}

在使用枚举类型之前,需要在 Postgres 中创建枚举类型

CREATE TYPE color_enum as enum ('Blue', 'Green', `White`);

CREATE TABLE product (id SERIAL PRIMARY KEY, color color_enum);

枚举类型就位后,您需要配置驱动程序以将 Java 枚举与相应的 Postgres 枚举类型关联。 这可以通过使用 R2DBC Postgres EnumCodec 构建器来完成。 生成的 CodecRegistrar 必须在使用连接配置创建 ConnectionFactory 之前注册

CodecRegistrar codecRegistrar = EnumCodec.builder().withEnum("color_enum", Color.class).build();

PostgresqlConnectionConfiguration configuration = PostgresqlConnectionConfiguration.builder()
 
    .codecRegistrar(codecRegistrar)
 
    // additional configuration
    .build();

另请参阅 Postgres 枚举类型上的驱动程序文档,以供进一步参考。

配置 ConnectionFactory 后,您可以配置 Spring Data 中的特定 enum 类型,以将其真实值传递给驱动程序,而不是将枚举值转换为 StringR2dbcCustomConversions 是配置简单类型及其转换器的入口点

R2dbcCustomConversions conversions = R2dbcCustomConversions.of(PostgresDialect.INSTANCE, new ColorConverter());

现在您可以在您的域类中使用枚举类型

class Product {
  @Id Integer id;
  Color color;
  // getter, setter, constructors omitted for brevity
}

请参阅关于 使用显式转换器覆盖枚举映射的参考文档。

与枚举相比,使用 Postgres 几何类型不需要特殊设置,因为 Geo 类型具有固定的类型标识符并映射到单个 Geo 类型。 Spring Data R2DBC 支持在您的实体中使用以下特定于驱动程序的类型

  • io.r2dbc.postgresql.codec.Box
  • io.r2dbc.postgresql.codec.Circle
  • io.r2dbc.postgresql.codec.Line
  • io.r2dbc.postgresql.codec.Lseg
  • io.r2dbc.postgresql.codec.Point
  • io.r2dbc.postgresql.codec.Path
  • io.r2dbc.postgresql.codec.Polygon

或者,您可以在您的域模型中使用 Spring Data 的 Geo 类型

  • org.springframework.data.geo.Box
  • org.springframework.data.geo.Circle
  • org.springframework.data.geo.Point
  • org.springframework.data.geo.Polygon

要使用几何类型,请创建一个表和一个相应的实体类型

CREATE TABLE venue (id SERIAL PRIMARY KEY, name VARCHAR(255), location POINT);
class Venue {
  @Id Long id;
  String name;
  Point location;
  // getter, setter, constructors omitted for brevity
}

最后,您可以在您的应用程序中使用该实体

R2dbcEntityTemplate template = …;

template.insert(new Venue(null, "Seattle Space Needle", Point.of(47.6204,-122.3491));

获取 Spring 新闻通讯

通过 Spring 新闻通讯保持联系

订阅

抢先一步

VMware 提供培训和认证,以加速您的进步。

了解更多

获取支持

Tanzu Spring 在一个简单的订阅中提供对 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区中所有即将举行的活动。

查看全部