Spring Data 2020.0 - Spring Data for Apache Cassandra 3.1 的新增功能和值得关注内容

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

Spring Data 2020.0.0 与 Spring Data for Apache Cassandra 3.1 一起发布。此版本包含许多增强功能,这些增强功能改进了现有功能并引入了对选定 Cassandra 4 功能的支持

  • 响应式审计
  • @Query 查询方法中支持响应式 SpEL。
  • 通过 CqlTemplateQueryOptions 为每个 Statement 配置键空间。
  • 修订后的 CqlOperations,其中包含新的 queryForStream(…) 方法,该方法返回一个 Stream 并提供透明分页。
  • DataClassRowMapper 用于通过构造函数创建/bean 属性将 Cassandra 结果映射到数据类

响应式审计

通过在配置类上使用 @EnableReactiveCassandraAuditing 注解启用响应式审计。注册实现 ReactiveAuditorAware 的 Bean 作为获取当前审计者的接口。以下示例显示了所需的配置

@Configuration
@EnableReactiveCassandraAuditing  
class ApplicationConfiguration {  
  
  @Bean  
  ReactiveAuditorAware<String> reactiveAuditorAware() {  
      return …;
   }  
}

启用响应式审计后,您可以在域类中使用 Spring Data 的审计注解。如果您之前使用过 Spring Data 审计,那么您可能会注意到,与 Spring Data 的命令式用法相比,设置域模型没有任何区别。

public class Order implements Persistable<String> {  
    
   @Id String orderId;  
  
   @CreatedBy String createdBy;  
  
   @CreatedDate Instant createdDate;  
  
   @LastModifiedBy String lastModifiedBy;  
  
   @LastModifiedDate Instant lastModifiedDate;   
}

上面显示的域类通过使用带有 @CreatedBy@LastModifiedBy 注解的属性来引用审计者。保存创建或修改时间的属性分别使用 @CreatedDate@LastModifiedDate 进行注解。

您可能已经注意到,域类实现了 Persistable。为了正确地将实体标记为已审计,Spring Data 需要知道实体是新的还是应该被认为存在于数据库中。通常,这是通过检查 @Id 属性来查看它是否为 null 来实现的。Cassandra 没有生成主键值的方法。新对象必须使用提供的标识符持久化。因此,您的域模型必须表示它是否应该被认为是新的或现有的(参见 Persistable.isNew())。或者,Spring Data 在使用乐观锁时可以检查 @Version 属性,以判断实体是否应该被认为是新的。

您可以通过响应式 Cassandra 存储库和 ReactiveCassandraTemplate 使用响应式审计。

关于迁移的最后一点说明:随着响应式审计的引入,只有当您的配置用 @EnableReactiveCassandraAuditing 标记时,才会注册整个响应式审计基础设施。以前的版本 (3.0.x) 在配置 @EnableCassandraAuditing 时注册了一个名为 EntityCallback 的轻量级审计。现在不再是这样了,因此,如果您之前使用过审计功能,请确保重新检查您基于注解的配置。

您可以在 Apache Cassandra 审计 中阅读更多关于 Spring Data Cassandra 参考文档 的信息。

每个 Statement 的键空间配置

Cassandra 4 允许在每个语句级别指定目标键空间。而不是在已记录的键空间中运行语句,各个语句可以定位到不同的键空间。为了支持此功能,Spring Data for Apache Cassandra 允许通过以下方式配置键空间

  • CqlTemplate(包括 AsyncCqlTemplateReactiveCqlTemplate
  • QueryOptions(包括子类)

在 Template API 上配置键空间允许通过特定模板在与已记录的键空间不同的键空间中运行所有语句。一个典型的用例可能是每个租户模型的键空间

CqlSession cqlSession = …;  
CqlTemplate tenant1Template = new CqlTemplate(cqlSession);  
tenant1Template.setKeyspace(CqlIdentifier.fromCql("my-other-keyspace"));  
tenant1Template.queryForList("SELECT …");

CqlTemplate 及其异步和反应式变体由 CassandraTemplate 和存储库基础设施使用,这允许将整个堆栈连接到不同的键空间。

要自定义 CassandraTemplate 上各个操作的键空间,您可以使用 QueryOptions 及其特定于操作的子类来控制键空间

CassandraTemplate template = …;  
  
template.insert(person, InsertOptions.builder().keyspace("my-other-keyspace").build());

请注意,此功能需要 Cassandra 4,并且它不会影响早期 Cassandra 版本。

修订后的 CqlTemplate 及其异步/反应式变体

在此版本中,我们借此机会改进了我们的 CQL 模板 API。有一段时间了,我们希望 CqlTemplate 支持 Java 8 Stream,包括 CqlTemplate 上的透明分页。它的反应式对应物 ReactiveCqlTemplate 使用 queryForFlux 支持此功能(自版本 2.0 起)。在此版本中,您可以在 CqlTemplate 上使用 queryForStream,从而允许对 java.util.stream.Stream 进行延迟迭代

CqlTemplate template = …;

Stream<String> stream = cqlTemplate.queryForStream("SELECT * from USERS", (row, index) -> row.getString(0));

此外,queryForStreamCassandraTemplate.stream(…) 提供服务,以运行返回实体流的查询。

轻量级数据类和记录(从 Java 15 及更高版本开始)的使用成为越来越流行的用于临时结果映射的选择。此版本不再使用面向实体的 CassandraTemplate,而是启用了一种更轻量级的模式,以将查询结果作为纯 Java Bean、Kotlin 数据类和 Java 记录来使用。DataClassRowMapper 是一个专用的 RowMapper,它通过检查其构造函数属性来实例化遵循数据类/Java 记录模式的类。以下示例说明了 Java 记录的使用

record User(String id, String name, int age){}

CqlTemplate template = …;

Stream<User> stream = cqlTemplate.queryForStream("SELECT * from USERS", new DataClassRowMapper(User.class));

以下是 Kotlin 数据类变体

data class User(id: String, name: String, age: Int)

val stream : Stream<Person> = cqlTemplate.queryForStream("SELECT * from USERS", DataClassRowMapper<User>())

您可以将 DataClassRowMapper 与所有 CqlTemplate 变体一起使用,因为所有这些都接受 RowMapper

获取 Spring 时事通讯

与 Spring 时事通讯保持联系

订阅

领先一步

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

了解更多

获取支持

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

了解更多

即将举行的活动

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

查看全部