I want to discuss a bit further the usage of Criteria and ReactiveCrudRepository.
Spring data r2dbc supports query by example. Which in many cases is too limited. For example, all types other than String are exact-match only.
Navigating the issues of the project, I found an answer from @jiangtj and managed to elaborate the following piece of code:
public interface UserRepository extends ReactiveCrudRepository<User, Long>, ReactiveSearchRepository<User> {
}
interface ReactiveSearchRepository<T> {
Flux<T> findAll(Criteria criteria, Class<T> domainType);
public Mono<Page<T>> findAll(Criteria criteria, Pageable pageable, Class<T> domainType);
}
And then the implementation for ReactiveSearchRepositoryImpl
:
@AllArgsConstructor
class ReactiveSearchRepositoryImpl<T> implements ReactiveSearchRepository<T> {
private final R2dbcEntityTemplate r2dbcTemplate;
public Flux<T> findAll(Criteria criteria, Class<T> domainType) {
return r2dbcTemplate.select(domainType)
.matching(query(criteria))
.all();
}
public Mono<Page<T>> findAll(Criteria criteria, Pageable pageable, Class<T> domainType) {
Mono<List<T>> list = r2dbcTemplate.select(domainType)
.matching(query(criteria).with(pageable))
.all()
.collectList();
Mono<Long> count = r2dbcTemplate.select(domainType)
.matching(query(criteria))
.count();
return Mono.zip(list, count)
.map(tuple -> new PageImpl<>(tuple.getT1(), pageable, tuple.getT2()));
}
}
I'm aware of Oliver Drotbohm's view about Criteria
as a store-specific type. Although the Fluent API supports it out of the box.
In my personal view, adding Criteria
to the Reactive Repositories would empower the framework with a new dimension of querying the DB.
Does it make sense?