【问题标题】:Spring Data Reactive R2DBC PaginationSpring Data Reactive R2DBC 分页
【发布时间】:2020-11-29 02:55:06
【问题描述】:

Spring Data Reactive 不支持 Page 作为返回类型。我正在尝试使用来自服务层的两个不同查询(一个用于获取结果列表,另一个用于获取总数)来实现这一点。

第一个查询给出的内容为Flux<Person>,第二个查询给出的计数为Mono<Integer>

我可以将这两者结合起来并返回一个Mono<Page<Person>>吗?怎么样?

请帮忙。

【问题讨论】:

    标签: spring-webflux project-reactor spring-data-r2dbc


    【解决方案1】:

    所以最后我编码如下。

    我对整个反应式范式很陌生。所以下面的代码可能不是最好的方法。最终,我希望 Spring Data R2DBC 增加对 Page 返回类型的支持。上述问题的答案在 CustomMentorRepositoryImpl 类中的 search 方法实现中。

    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import org.springframework.data.annotation.Id;
    import org.springframework.data.annotation.Version;
    import org.springframework.data.relational.core.mapping.Column;
    import org.springframework.data.relational.core.mapping.Table;
    
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Table("mentors")
    public class Mentor {
    
        @Id
        private Long id;
        boolean hasId() {
            return id != null;
        }
    
        @Version
        @Column("version")
        private Integer version;
    
        @Column("name")
        private String name;
    
        @Column("age")
        private Integer age;
    
    }
    

    存储库类

    import com.sample.app.domain.Mentor;
    import org.springframework.data.domain.Page;
    import org.springframework.data.domain.Pageable;
    import org.springframework.data.r2dbc.repository.Query;
    import org.springframework.data.repository.query.Param;
    import org.springframework.data.repository.reactive.ReactiveCrudRepository;
    import org.springframework.stereotype.Repository;
    import reactor.core.publisher.Flux;
    import reactor.core.publisher.Mono;
    
    @Repository
    public interface MentorRepository extends 
        ReactiveCrudRepository<Mentor, String>, CustomMentorRepository {    
    }
    

    // CustomRepository 类

    import com.sample.app.domain.Mentor;
    import org.springframework.data.domain.Page;
    import org.springframework.data.domain.Pageable;
    import org.springframework.data.repository.query.Param;
    import reactor.core.publisher.Flux;
    import reactor.core.publisher.Mono;
    
    public interface CustomMentorRepository {
        public Mono<Page<Mentor>> search(String name, Pageable page);
    }
    

    // CustomRepositoryImpl 类

    import lombok.AllArgsConstructor;
    import com.sample.app.domain.Mentor;
    import com.sample.app.repository.CustomMentorRepository;
    import org.springframework.data.domain.Page;
    import org.springframework.data.domain.PageImpl;
    import org.springframework.data.domain.Pageable;
    import org.springframework.data.r2dbc.core.DatabaseClient;
    import reactor.core.publisher.Flux;
    import reactor.core.publisher.Mono;
    
    @AllArgsConstructor
    public class CustomMentorRepositoryImpl implements CustomMentorRepository {
    
        DatabaseClient databaseClient;
    
        @Override
        public Mono<Page<Mentor>> search(String name, Pageable page) {
            // Get the contents
            Flux<Mentor> contents = databaseClient.execute("SELECT * FROM mentors where name like :name limit :limit offset :offset")
                    .bind("name", "%" + name + "%")
                    .bind("limit", page.getPageSize())
                    .bind("offset", page.getOffset())
                    .as(Mentor.class)
                    .fetch().all();
            // Get the count
            Mono<Long> count = databaseClient.execute("SELECT count(*) FROM mentors where name like :name")
                    .bind("name", "%" + name + "%")
                    .as(Long.class)
                    .fetch().first();
            return contents.collectList().zipWith(count).flatMap(objects ->
                    Mono.just(new PageImpl<Mentor>(objects.getT1(), page, objects.getT2()))
            );
        }
    }
    

    【讨论】:

    • 官方 r2dbc 文档有一个 PagingAndSortingRepository 的例子。不确定你是否可以使用它。你试过了吗?
    • PagingAndSortingRepository 不是反应式实现
    • 在响应式应用程序中使用Page 确实是个坏主意,响应式驱动系统中的数据应该是管道中的实时数据。返回 Flux 非常符合 ReactiveStreams 规范,可以在管道上应用任何操作。
    • 我在这个问题中回复了the R2dbc pagination
    猜你喜欢
    • 2020-07-04
    • 2019-08-22
    • 2020-03-11
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 2020-09-22
    • 1970-01-01
    • 2022-11-07
    相关资源
    最近更新 更多