Cassandra 专属查询方法
本章介绍 Cassandra 专属查询方法。本文档使用命令式类型。通过使用响应式返回类型,相同的语义同样适用于响应式仓库。
您通常在仓库上触发的大多数数据访问操作,最终都会在 Apache Cassandra 数据库上执行一条查询。定义这样的查询只需在仓库接口上声明一个方法即可。以下示例展示了若干此类方法声明:
- Imperative
- Reactive
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
}
The method shows a query for all people with the given
lastname. The query is derived from parsing the method name for constraints, which can be concatenated withAnd. Thus, the method name results in a query expression ofSELECT * FROM person WHERE lastname = 'lastname'.Applies pagination to a query. You can equip your method signature with a
Pageableparameter and let the method return aSliceinstance, and we automatically page the query accordingly.Applies scrolling to a query. Scrolling wraps Cassandra’s
PagingStateintoCassandraScrollPositionand allows dynamic limiting. You can also usefindTop…for a static limit.Passing a
QueryOptionsobject applies the query options to the resulting query before its execution.Applies dynamic sorting to a query. You can add a
Sortparameter to your method signature, and Spring Data automatically applies ordering to the query.Applies dynamic result limiting to a query. Query results can be limited using
SELECT … LIMIT.Shows that you can query based on properties that are not a primitive type by using
Converterinstances registered inCustomConversions. ThrowsIncorrectResultSizeDataAccessExceptionif more than one match is found.Uses the
Firstkeyword to restrict the query to only the first result. Unlike the preceding method, this method does not throw an exception if more than one match is found.Uses a Java 8
Streamto read and convert individual elements while iterating the stream.Shows a query method annotated with
@AllowFiltering, to allow server-side filtering.
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
}
A query for all people with the given
firstname. The query is derived by parsing the method name for constraints, which can be concatenated withAndandOr. Thus, the method name results in a query expression ofSELECT * FROM person WHERE firstname = :firstname.A query for all people with the given
firstnameonce thefirstnameis emitted from the givenPublisher.Find a single entity for the given criteria. Completes with
IncorrectResultSizeDataAccessExceptionon non-unique results.Unlike the preceding query, the first entity is always emitted even if the query yields more result rows.
A query method annotated with
@AllowFiltering, which allows server-side filtering.
查询非主键属性需要二级索引。
下表展示了可在查询方法中使用的关键词的简短示例:
表 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 | findByFirstnameContaining(String name) | firstname LIKE (name as like expression) |
集合上的 Containing | findByAddressesContaining(Address address) | addresses CONTAINING address |
| (无关键词) | 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)上配置以下参数,来控制提取大小、一致性级别和重试策略的默认值。如果未设置特定的查询选项,则应用默认值。