Spring Boot WebFlux Kotlin R2DBC 实现suspend分页返回Page对象咨询
Spring WebFlux R2DBC Repository 返回Page分页对象解决方案
报错原因
Spring Data R2DBC 原生不支持在Repository查询方法上直接声明返回Page<T>类型,框架校验时会认为返回类型不符合响应式规范,触发启动报错。
解决方案
1. 调整Repository定义
拆分查询逻辑为两个独立方法,分别查询当前页数据和符合条件的总条数:
interface MemberContactableStatusRepository : ReactiveCrudRepository<MemberContactableStatusEntity, Long> { suspend fun findByUserId(userId: Long): MemberContactableStatusEntity? // 查询当前页数据 suspend fun findAllByUserId(userId: Long, pageable: Pageable): List<MemberContactableStatusEntity> // 查询符合条件的总记录数 suspend fun countByUserId(userId: Long): Long }
2. Service层手动组装Page对象
通过协程并发执行两个查询降低耗时,再用Spring官方提供的PageImpl实现类组装分页对象:
import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope import org.springframework.data.domain.Page import org.springframework.data.domain.PageImpl import org.springframework.data.domain.Pageable import org.springframework.stereotype.Service @Service class MemberContactableStatusService( private val repository: MemberContactableStatusRepository ) { suspend fun getPageByUserId(userId: Long, pageable: Pageable): Page<MemberContactableStatusEntity> = coroutineScope { // 并发查询提升性能 val totalCount = async { repository.countByUserId(userId) } val records = async { repository.findAllByUserId(userId, pageable) } // 组装分页对象 PageImpl(records.await(), pageable, totalCount.await()) } }
可选优化
如果业务不需要返回总记录数、总页数,可改用Slice实现:仅在查询当前页数据时多查1条,根据返回结果数量判断是否存在下一页,可避免count查询带来的性能损耗。
内容的提问来源于stack exchange,提问作者Sehyeon Youn
相关产品推荐
相关产品推荐

