Cassandra-specific 查询方法
本章解释了 Cassandra 特定的查询方法。本文档使用了命令式类型。通过使用响应式返回类型,相同的语义也适用于响应式存储库。
大多数情况下,您在存储库上触发的数据访问操作会导致对 Apache Cassandra 数据库执行查询。定义这样的查询只需在存储库接口上声明一个方法。以下示例展示了一些这样的 方法声明:
- 命令式
- 响应式
interface PersonRepository extends CrudRepository<Person, String> {
List<Person> findByLastname(String lastname); 1
Slice<Person> findByFirstname(String firstname, Pageable pageRequest); 2
Window<Person> findByFirstname(String firstname, CassandraScrollPosition pos, Limit limit); 3
List<Person> findByFirstname(String firstname, QueryOptions opts); 4
List<Person> findByFirstname(String firstname, Sort sort); 5
List<Person> findByFirstname(String firstname, Limit limit); 6
Person findByShippingAddress(Address address); 7
Person findFirstByShippingAddress(Address address); 8
Stream<Person> findAllBy(); 9
@AllowFiltering
List<Person> findAllByAge(int age); 10
}
该方法展示了一个查询所有具有给定
lastname
的人的查询。该查询通过解析方法名中的约束得出,可以使用And
连接。因此,方法名会生成一个查询表达式SELECT * FROM person WHERE lastname = 'lastname'
。对查询应用分页。可以在方法签名中添加
Pageable
参数,并让方法返回一个Slice
实例,Spring Data 会自动分页查询。对查询应用滚动。滚动将 Cassandra 的
PagingState
封装成CassandraScrollPosition
,并允许动态限制。也可以使用findTop…
来应用静态限制。传递一个
QueryOptions
对象,应用查询选项到执行查询之前。对查询应用动态排序。可以在方法签名中添加一个
Sort
参数,Spring Data 会自动将排序应用到查询中。对查询应用动态结果限制。查询结果可以通过
SELECT … LIMIT
来限制。显示你可以基于非原始类型的属性进行查询,通过使用在
CustomConversions
中注册的Converter
实例。如果找到多个匹配项,将抛出IncorrectResultSizeDataAccessException
异常。使用
First
关键字来限制查询只返回第一个结果。与前一个方法不同,如果找到多个匹配项,该方法不会抛出异常。使用 Java 8
Stream
来读取并转换单个元素,同时遍历流。显示一个用
@AllowFiltering
注解的方法,允许服务器端过滤。
interface ReactivePersonRepository extends ReactiveSortingRepository<Person, Long> {
Flux<Person> findByFirstname(String firstname); 1
Flux<Person> findByFirstname(Publisher<String> firstname); 2
Mono<Person> findByFirstnameAndLastname(String firstname, String lastname); 3
Mono<Person> findFirstByFirstname(String firstname); 4
@AllowFiltering
Flux<Person> findByAge(int age); 5
}
查询所有具有给定
firstname
的人。查询是通过解析方法名中的约束得出的,可以使用And
和Or
进行连接。因此,方法名会生成一个查询表达式SELECT * FROM person WHERE firstname = :firstname
。查询所有具有给定
firstname
的人,查询条件来自于给定的Publisher
发出的firstname
。根据给定的条件查找单个实体。如果结果不唯一,会抛出
IncorrectResultSizeDataAccessException
异常。与前一个查询不同,始终返回第一个实体,即使查询返回多个结果行。
使用
@AllowFiltering
注解的查询方法,允许服务器端过滤。
查询非主键属性需要二级索引。
以下表格展示了您可以在查询方法中使用的关键字的简短示例:
表 1. 查询方法支持的关键字
关键字 | 示例 | 逻辑结果 |
---|---|---|
After | findByBirthdateAfter(Date date) | birthdate > date |
GreaterThan | findByAgeGreaterThan(int age) | age > age |
GreaterThanEqual | findByAgeGreaterThanEqual(int age) | age >= age |
Before | findByBirthdateBefore(Date date) | birthdate < date |
LessThan | findByAgeLessThan(int age) | age < age |
LessThanEqual | findByAgeLessThanEqual(int age) | age ⇐ age |
Between | findByAgeBetween(int from, int to) 和 findByAgeBetween(Range<Integer> range) | age > from AND age < to 和下限 / 上限 (> / >= & < / ⇐ ) 根据 Range |
In | findByAgeIn(Collection ages) | age IN (ages…) |
Like , StartingWith , EndingWith | findByFirstnameLike(String name) | firstname LIKE (name as like expression) |
Containing on String | findByFirstnameContaining(String name) | firstname LIKE (name as like expression) |
Containing on Collection | findByAddressesContaining(Address address) | addresses CONTAINING address |
(No keyword) | findByFirstname(String name) | firstname = name |
IsTrue , True | findByActiveIsTrue() | active = true |
IsFalse , False | findByActiveIsFalse() | active = false |
删除查询
前表中的关键字可以与 delete…By
一起使用,以创建删除匹配文档的查询。
- Imperative
- Reactive
interface PersonRepository extends Repository<Person, String> {
void deleteWithoutResultByLastname(String lastname);
boolean deleteByLastname(String lastname);
}
interface PersonRepository extends Repository<Person, String> {
Mono<Void> deleteWithoutResultByLastname(String lastname);
Mono<Boolean> deleteByLastname(String lastname);
}
删除查询返回是否应用了查询,或者使用 void
终止而不返回任何值。
查询选项
您可以通过传递一个 QueryOptions
对象来为查询方法指定查询选项。这些选项在实际查询执行之前应用。QueryOptions
被视为一个非查询参数,并不被视为查询参数值。查询选项适用于派生的和字符串 @Query
仓库方法。
要静态设置一致性级别,请在查询方法上使用 @Consistency
注解。声明的一致性级别在每次执行查询时应用。以下示例将一致性级别设置为 ConsistencyLevel.LOCAL_ONE
:
- Imperative
- Reactive
interface PersonRepository extends CrudRepository<Person, String> {
@Consistency(ConsistencyLevel.LOCAL_ONE)
List<Person> findByLastname(String lastname);
List<Person> findByFirstname(String firstname, QueryOptions options);
}
interface PersonRepository extends ReactiveCrudRepository<Person, String> {
@Consistency(ConsistencyLevel.LOCAL_ONE)
Flux<Person> findByLastname(String lastname);
Flux<Person> findByFirstname(String firstname, QueryOptions options);
}
DataStax Cassandra 文档中包含了 关于可用一致性级别的详细讨论。
您可以通过在 CQL API 实例上配置以下参数来控制获取大小、一致性级别和重试策略默认值:CqlTemplate
、AsyncCqlTemplate
和 ReactiveCqlTemplate
。如果未设置特定查询选项,则应用默认值。