Spring Data R2DBC中带过滤条件的分页查询问题求助
Spring Data R2DBC中带过滤条件的分页查询问题求助
看起来你遇到的问题大概率是由细节错误和R2DBC的特性适配问题导致的,咱们一步步来排查解决:
1. 先修正SQL里的拼写错误
你的@Query语句里有两处明显的拼写错误,这很可能是返回null元素的直接原因:
f.project_id:根据你描述的表结构,file表关联的是system表的id,字段应该是f.system_id而不是project_idp.syetem_title:应该是p.system_title(多打了一个y)
修正后的SQL语句:
select f from file f inner join system p on f.system_id = p.id where f.is_deleted = false AND (f.file_name LIKE CONCAT('%', :searchParam, '%') OR p.system_title LIKE CONCAT('%', :searchParam, '%'))
2. 适配R2DBC的参数绑定与PostgreSQL语法
PostgreSQL中使用CONCAT结合参数可能存在绑定兼容性问题,建议换成PostgreSQL原生的字符串拼接语法||,这样参数绑定会更可靠:
select f from file f inner join system p on f.system_id = p.id where f.is_deleted = false AND (f.file_name LIKE '%' || :searchParam || '%' OR p.system_title LIKE '%' || :searchParam || '%')
另外可以先确认searchParam没有被意外转义(比如包含%或_这类通配符),普通搜索场景下暂时不用额外处理。
3. 修复分页与count查询不匹配的问题
你现在service层用的repository.count()是查询全表总记录数,而非符合过滤条件的记录数,这会导致分页的总条数、总页数完全错误。需要在repository中新增带过滤条件的count方法:
@Query("select count(*) from file f inner join system p on f.system_id = p.id where f.is_deleted=false AND (f.file_name LIKE '%' || :searchParam || '%' OR p.system_title LIKE '%' || :searchParam || '%')") Mono<Long> countFilteredFileList(@Param("searchParam") String searchParam);
然后在service层替换原来的count逻辑:
repository.getFilteredFileList(searchParam, pageRequest.withSort(Sort.by("uploadDateTime").descending())) .collectList() .zipWith(repository.countFilteredFileList(searchParam)) .flatMap(e -> Mono.just(new PageImpl<>(e.getT1(), pageRequest, e.getT2())));
4. 检查实体映射是否正确
如果上述修正后还是返回null,要确认File实体类是否正确映射了数据库字段:
- 关联查询时,实体字段要和查询返回的列名匹配(PostgreSQL默认小写,实体驼峰字段需要配置映射规则)
- 可以尝试在SQL中明确指定查询字段,比如
select f.id, f.file_name, f.uploaded_date_time, f.system_id from ...,避免多余字段导致映射失败
5. 调试参数传递是否正常
可以开启R2DBC的DEBUG日志,查看实际执行的SQL和参数值,确认searchParam是否正确替换。在application.yml中添加配置:
logging: level: io.r2dbc.postgresql: DEBUG org.springframework.data.r2dbc: DEBUG
这样就能看到发送到Postgres的真实SQL和参数,快速定位参数绑定问题。
先试试这些步骤,应该能解决你遇到的问题。
备注:内容来源于stack exchange,提问作者Rahul
相关产品推荐
相关产品推荐

