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,用于在加载、保存和删除操作时预处理和后处理实体。实体回调在持久化操作期间被调用,允许对实体进行就地修改,如果实体类是不可变的,则返回新的对象实例。

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

您可以将EntityCallback用于各种回调钩子。以下示例定义了一个BeforeConvertCallback,用于为Customer类型生成来自 H2 序列的主键值(如果其标识符为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 构建器完成的。在创建ConnectionFactory之前,必须将生成的CodecRegistrar注册到连接配置中。

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 社区中所有即将举行的活动。

查看全部