Spring Data R2DBC和分页

13

我正在使用新的Spring Data R2DBC模块,并且可以使用ReactiveCrudRepository提取数据。 现在我需要引入分页,但我无法做到。 我尝试了以下方法

public interface TestRepository extends ReactiveCrudRepository<MyEntity, Long> {
    Flux<MyEntity> findByEntityId(Long entityId, Pageable page);
}

但是当我尝试执行这个操作时,我得到了这个错误

org.springframework.data.repository.query.ParameterOutOfBoundsException: Invalid parameter index! You seem to have declared too little query method parameters!
    at org.springframework.data.repository.query.Parameters.getParameter(Parameters.java:237)
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 

这个模块有没有实现分页的功能呢?

4个回答

13

新的R2dbcEntityTemplate Spring Data R2dbc 1.2 包含像这样的分页操作。

 private final R2dbcEntityTemplate template;

    public Flux<Post> findByTitleContains(String name) {
        return this.template.select(Post.class)
                .matching(Query.query(where("title").like("%" + name + "%")).limit(10).offset(0))
                .all();
    }

Spring Data R2dbc 1.2 (尚未发布) 将会接受 Repository 中的一个 Pageable 参数。

 public Flux<PostSummary> findByTitleLike(String title, Pageable pageable);

完整的代码示例请查看此处测试代码


1
在 ReactiveCrudRepository 中使用 Pageable 应该也适用于 1.1.4 版本。 - Chris

5

目前还没有使用隐式分页的方法。您应该指定整个查询以使用它。

以下是一个例子:

@Query("SELECT * FROM my_entity WHERE entity_id = :entityId OFFSET :offset LIMIT :limit")
Flux<MyEntity> findByEntityId(Long entityId, int offset, int limit);

3
较新的Spring Data R2dbc版本接受@Hantsy提到的Pageable,但有一个陷阱。 如果您在没有任何WHERE子句的情况下获取所有记录,则以下内容将不起作用:
public interface MyEntityRepository extends ReactiveCrudRepository<MyEntity, Long> {
    Flux<MyEntity> findAll(Pageable pageable);
}

findAll()更改为findBy()是有效的。

public interface MyEntityRepository extends ReactiveCrudRepository<MyEntity, Long> {
    Flux<MyEntity> findBy(Pageable pageable);
}

0

我使用spring-boot-starter-data-r2dbc.2.4.3实现了这个功能。

正如@Hantsy所说,ReactiveCrudRepository将Pageable作为查询参数接受,但这并不能解决分页问题。在Hibernate中,您期望返回一个对象的页面,但对于Reactive来说,它将是一个Flux。

然而,我通过使用PageImpl类和从ReactiveCrudRepository接口中使用count方法来实现了这一点。

例如

public interface TestRepository extends ReactiveCrudRepository<MyEntity, Long> {
    Flux<MyEntity> findByEntityId(Long entityId, Pageable page);
}

public Mono<<Page<MyEntity>> getMyEntities(Long entityId, PageRequest request) {
    return testRepository.findByEntityId(entityId, request)
            .collectList()
            .zipWith(testRepository.count())
            .flatMap(entityTuples -> 
                new PageImpl<>(entityTuples.getT1(), request, entityTuples.getT2()));
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接