Spring Boot接口投影分页:修改返回键名与排序方案咨询
解决方案
1. 修改_embedded节点下的键名
接口投影默认会被Spring HATEOAS序列化为tupleBackedMaps,要改成somethingElse,有两种实用方法:
方式一:给投影接口加@Relation注解
直接在你的CustomResult投影接口上标注@Relation,指定collectionRelation为目标名称:
import org.springframework.data.rest.core.annotation.Relation; @Relation(collectionRelation = "somethingElse") public interface CustomResult { // 你的投影方法示例: String getName(); Integer getAge(); }
这样返回的分页结果里,_embedded下的键就会变成somethingElse。
方式二:手动构建PagedModel(更灵活)
如果不想依赖Spring Data REST的注解,可以手动将Page转换为自定义PagedModel,指定元素的关系名称:
import org.springframework.hateoas.PagedModel; import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class YourController { private final YourRepository repository; public YourController(YourRepository repository) { this.repository = repository; } @GetMapping("/your-endpoint") public PagedModel<CustomResult> getPagedResults(@RequestParam int page, @RequestParam int size) { Page<CustomResult> resultPage = repository.findCustomResults(PageRequest.of(page, size)); // 构建分页模型,指定collectionRelation为somethingElse PagedModel.PageMetadata metadata = new PagedModel.PageMetadata(size, resultPage.getNumber(), resultPage.getTotalElements()); PagedModel<CustomResult> pagedModel = PagedModel.of(resultPage.getContent(), metadata); // 可选:添加自链接 pagedModel.add(WebMvcLinkBuilder.linkTo(WebMvcLinkBuilder.methodOn(YourController.class).getPagedResults(page, size)).withSelfRel()); return pagedModel; } }
这种方式能完全掌控分页模型的结构,适合需要自定义更多细节的场景。
2. 对结果元素排序
排序有两种实现方式,按需选择:
方式一:在@Query中固定排序规则
直接在Repository的@Query注解里添加ORDER BY子句,写死排序逻辑:
import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.PagingAndSortingRepository; public interface YourRepository extends PagingAndSortingRepository<YourEntity, Long> { @Query("SELECT c.name as name, c.age as age FROM YourEntity c ORDER BY c.name ASC") Page<CustomResult> findCustomResults(Pageable pageable); }
方式二:通过Pageable参数动态控制排序
如果需要前端传递排序参数,直接利用Pageable的Sort属性即可:
// Repository层 @Query("SELECT c.name as name, c.age as age FROM YourEntity c") Page<CustomResult> findCustomResults(Pageable pageable); // Controller层 @GetMapping("/your-endpoint") public PagedModel<CustomResult> getPagedResults(Pageable pageable) { Page<CustomResult> resultPage = repository.findCustomResults(pageable); // 后续处理同手动构建PagedModel的逻辑 }
前端可以通过sort=name,asc或sort=age,desc这类参数,动态指定排序字段和方向。
替代方案:转回DTO类投影(兼容你熟悉的方法)
如果接口投影限制太多,直接换回类投影就行,用你已知的RepresentationModel、@Relation和@JsonPropertyOrder实现:
import org.springframework.hateoas.RepresentationModel; import org.springframework.data.rest.core.annotation.Relation; import com.fasterxml.jackson.annotation.JsonPropertyOrder; @Relation(collectionRelation = "somethingElse") @JsonPropertyOrder({"name", "age"}) // 控制字段输出顺序 public class CustomResultDTO extends RepresentationModel<CustomResultDTO> { private String name; private Integer age; // 构造器、getter方法 public CustomResultDTO(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public Integer getAge() { return age; } }
然后Repository返回Page<CustomResultDTO>,既能通过@Relation修改_embedded的键名,又能靠@JsonPropertyOrder控制元素字段排序,完全兼容你熟悉的方案。
内容的提问来源于stack exchange,提问作者Lokesh Pandey
相关产品推荐
相关产品推荐

