Cassandra Repositories
要访问存储在 Apache Cassandra 中的域实体,可以使用 Spring Data 复杂的存储库支持,这极大地简化了 DAO 的实现。要执行此操作,请为您的存储库创建一个接口,如下面的示例所示:
To access domain entities stored in Apache Cassandra, you can use Spring Data’s sophisticated repository support, which significantly eases implementing DAOs. To do so, create an interface for your repository, as the following example shows: .Sample Person entity
@Table
public class Person {
@Id
private String id;
private String firstname;
private String lastname;
// … getters and setters omitted
}
请注意,实体有一个名为 id
的 String 类型的属性。MappingCassandraConverter
中使用的默认转换机制(它支持存储库支持)将名为 id
的属性视为行 ID。
Note that the entity has a property named id
of type String
.
The default conversion mechanism used in MappingCassandraConverter
(which backs the repository support) regards properties named id
as being the row ID.
以下示例显示了一个存储 Person
实体的存储库定义:
The following example shows a repository definition to persist Person
entities:
Person
entities-
Imperative
-
Reactive
interface PersonRepository extends CrudRepository<Person, String> {
// additional custom finder methods go here
}
interface PersonRepository extends ReactiveCrudRepository<Person, String> {
// additional custom finder methods go here
}
现在,前一个示例中的接口仅用作键入目的,但我们稍后会向其中添加其他方法。
Right now, the interface in the preceding example serves only typing purposes, but we add additional methods to it later.
接下来,在 Spring 配置中,如果使用 Java 进行配置,则添加以下内容:
Next, in your Spring configuration, add the following (if you use Java for configuration):
如果您想使用 Java 配置,请使用 @EnableCassandraRepositories
对应的 @EnableReactiveCassandraRepositories
注释。此注释具有与命名空间元素相同的属性。如果未配置基本包,基础架构将扫描带注释的配置类包。以下示例显示了如何使用不同的配置方法:
If you want to use Java configuration, use the @EnableCassandraRepositories
respective @EnableReactiveCassandraRepositories
annotation.
The annotation carries the same attributes as the namespace element.
If no base package is configured, the infrastructure scans the package of the annotated configuration class.
The following example show how to the different configuration approaches:
-
Imperative Java Configuration
-
XML
-
Reactive Java Configuration
@Configuration
@EnableCassandraRepositories
class ApplicationConfig extends AbstractCassandraConfiguration {
@Override
protected String getKeyspaceName() {
return "keyspace";
}
public String[] getEntityBasePackages() {
return new String[] { "com.oreilly.springdata.cassandra" };
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cassandra="http://www.springframework.org/schema/data/cassandra"
xsi:schemaLocation="
http://www.springframework.org/schema/data/cassandra
https://www.springframework.org/schema/data/cassandra/spring-cassandra.xsd
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<cassandra:session port="9042" keyspace-name="keyspaceName"/>
<cassandra:mapping
entity-base-packages="com.acme.*.entities">
</cassandra:mapping>
<cassandra:converter/>
<cassandra:template/>
<cassandra:repositories base-package="com.acme.*.entities"/>
</beans>
@Configuration
@EnableReactiveCassandraRepositories
class ApplicationConfig extends AbstractReactiveCassandraConfiguration {
@Override
protected String getKeyspaceName() {
return "keyspace";
}
public String[] getEntityBasePackages() {
return new String[] { "com.oreilly.springdata.cassandra" };
}
}
cassandra:repositories
命名空间元素导致扫描基本包以查找扩展 CrudRepository
的接口,并为找到的每个接口创建 Spring bean。默认情况下,存储库会通过称为 cassandraTemplate
的 CassandraTemplate
Spring bean 进行连接,因此只有当偏离此约定时才需要明确配置 cassandra-template-ref
。
The cassandra:repositories
namespace element causes the base packages to be scanned for interfaces that extend CrudRepository
and create Spring beans for each one found.
By default, the repositories are wired with a CassandraTemplate
Spring bean called cassandraTemplate
, so you only need to configure
cassandra-template-ref
explicitly if you deviate from this convention.
因为我们的域存储库扩展了 CrudRepository
对应的 ReactiveCrudRepository
,所以它会为您提供基本的 CRUD 操作。处理存储库实例只是将存储库作为依赖项注入到客户端,如下面的示例通过自动连接 PersonRepository
所示:
Because our domain repository extends CrudRepository
respective ReactiveCrudRepository
, it provides you with basic CRUD operations.
Working with the repository instance is a matter of injecting the repository as a dependency into a client, as the following example does by autowiring PersonRepository
:
-
Imperative
-
Reactive
@ExtendWith(SpringExtension.class)
class PersonRepositoryTests {
@Autowired PersonRepository repository;
@Test
void readsPersonTableCorrectly() {
List<Person> persons = repository.findAll();
assertThat(persons.isEmpty()).isFalse();
}
}
public class PersonRepositoryTests {
@Autowired ReactivePersonRepository repository;
@Test
public void sortsElementsCorrectly() {
Flux<Person> people = repository.findAll(Sort.by(new Order(ASC, "lastname")));
}
}
Cassandra 存储库支持分页和排序,以便对实体进行分页和排序的访问。Cassandra 分页需要分页状态才能在页间进行仅转发导航。Slice
跟踪当前分页状态并允许创建 Pageable
来请求下一页。以下示例显示如何设置对 Person
实体的分页访问:
Cassandra repositories support paging and sorting for paginated and sorted access to the entities.
Cassandra paging requires a paging state to forward-only navigate through pages.
A Slice
keeps track of the current paging state and allows for creation of a Pageable
to request the next page.
The following example shows how to set up paging access to Person
entities:
Person
entities-
Imperative
-
Reactive
@ExtendWith(SpringExtension.class)
class PersonRepositoryTests {
@Autowired PersonRepository repository;
@Test
void readsPagesCorrectly() {
Slice<Person> firstBatch = repository.findAll(CassandraPageRequest.first(10));
assertThat(firstBatch).hasSize(10);
Slice<Person> nextBatch = repository.findAll(firstBatch.nextPageable());
// …
}
}
@ExtendWith(SpringExtension.class)
class PersonRepositoryTests {
@Autowired PersonRepository repository;
@Test
void readsPagesCorrectly() {
Mono<Slice<Person>> firstBatch = repository.findAll(CassandraPageRequest.first(10));
Mono<Slice<Person>> nextBatch = firstBatch.flatMap(it -> repository.findAll(it.nextPageable()));
// …
}
}}
Cassandra 存储库不扩展 |
Cassandra repositories do not extend |
前一个示例使用 Spring 的单元测试支持创建应用程序上下文,它将基于注释的依赖项注入到测试类中。在测试用例中(测试方法),我们使用存储库查询数据存储。我们调用存储库查询方法,请求所有 Person
实例。
The preceding example creates an application context with Spring’s unit test support, which performs annotation-based dependency injection into the test class.
Inside the test cases (the test methods), we use the repository to query the data store.
We invoke the repository query method that requests all Person
instances.
Reactive Repositories
Spring Data 的存储库抽象是一种动态 API,大部分由您和您的要求定义,因为您声明查询方法。通过扩展库特定存储库接口之一,可以使用 RxJava 或 Project Reactor 包装器类型实现 Reactive Cassandra 存储库:
Spring Data’s repository abstraction is a dynamic API that is mostly defined by you and your requirements as you declare query methods. Reactive Cassandra repositories can be implemented by using either RxJava or Project Reactor wrapper types by extending from one of the library-specific repository interfaces:
-
ReactiveCrudRepository
-
ReactiveSortingRepository
-
RxJava3CrudRepository
-
RxJava3SortingRepository
Spring Data 在幕后转换反应式包装器类型,以便您可以坚持使用自己喜欢的组合库。
Spring Data converts reactive wrapper types behind the scenes so that you can stick to your favorite composition library.