Spring Boot JPA调用存储过程结果集实现分页方案
Spring Boot + Thymeleaf 工单系统存储过程查询分页实现方案
问题背景
基于Spring Boot与Thymeleaf搭建支持工单系统,当前正在开发已有工单的搜索功能。根据业务决策,部分业务逻辑下沉至数据库端实现,因此采用SQL存储过程查询的方式填充模型数据,而非直接连接数据表执行查询。目前搜索功能已调试通过,接下来需要实现搜索结果的分页功能。
现有代码结构
- Controller层:通过
@Autowired注入SearchResultTestService实例,在映射路径为/searchresultstest的@GetMapping请求方法中,指定单页数据量为5,调用服务的findPaginated方法获取第1页、按requestnumber字段升序排序的Page<SearchResult>分页对象,取出分页内的数据列表存入Model后,返回searchresultstest视图。 SearchResultTestService接口:标注@Service注解,定义findPaginated方法,入参为页码、页大小、排序字段、排序方向,返回Page<SearchResult>类型分页对象。SearchResultTestServiceImpl实现类:实现SearchResultTestService接口,通过@Autowired注入SearchResultTestRepository实例;在重写的findPaginated方法中,根据传入的排序方向生成Sort排序对象,构造PageRequest分页参数,原有逻辑直接调用Repository的findAll(pageable)方法返回分页结果。SearchResultTestRepository层:标注@Repository注解,原有定义为直接继承JpaRepository<SearchResult, Long>,无自定义查询方法。SearchResult模型类:标注@Entity注解,通过@SqlResultSetMapping配置存储过程返回列到构造函数的映射(使用@ConstructorResult指定映射目标类,@ColumnResult指定各返回列的名称与类型,覆盖requestnumber、status、assignedto、opendate、customer、description字段),类内定义对应私有属性、匹配映射顺序的构造函数与各属性的getter方法,其中requestnumber字段标注@Id作为主键。- 已编写的存储过程查询逻辑:通过
@PersistenceContext注入EntityManager实例,定义getSearchResults方法返回List<SearchResult>类型结果;方法内创建ArrayList实例存储返回结果,调用entityManager.createStoredProcedureQuery方法构造名为sc_app_test的存储过程查询、绑定"SearchResult"结果集映射;在try块中执行查询获取结果列表,finally块中通过unwrap获取ProcedureOutputs实例执行资源释放,捕获异常打印堆栈信息,最终返回查询结果列表。
待解决问题
- 上述调用存储过程获取结果的代码块应当放在Service层还是Repository层
SearchResult模型未直接绑定数据库表,无法直接使用JpaRepository自带的findAll()分页方法,如何适配实现分页
落地实现方案
- 分层职责调整:将调用存储过程获取搜索结果的逻辑迁移至Repository层实现,符合Repository层统一承载数据访问逻辑的分层规范。
- 分页逻辑适配:在Service层获取存储过程返回的全量结果列表后,使用Spring内置的
PagedListHolder将普通List转换为分页持有对象,通过MutableSortDefinition配置排序规则、设置页大小与当前页码,完成内存层面的分页与排序。 - 视图层对接:Controller层调用服务方法获取
PagedListHolder对象,取出当前页的数据列表存入Model传递给Thymeleaf视图渲染。
调整后的代码经测试可正常运行,分页、排序功能均符合预期。
内容的提问来源于stack exchange,提问作者rphello101
相关产品推荐
相关产品推荐

