首页 > 解决方案 > 使用 Spring JPA 排序时如何将客户端与实体变量名称分离

问题描述

我正在使用 Spring JPA Pageable 来管理端点的分页和排序。问题是客户端应该使用与实体名称相同的变量名称进行排序,以便 JPA 能够接受排序请求。但是,我试图将请求中的排序与实体分离,因此如果实体变量被重命名,则对请求参数没有影响。

@Entity
class Example {

    @Id
    @GeneratedValue
    @Column(nullable = false)
    private Long id;

    @Column(nullable = false)
    private String firstName;

    @Column(nullable = false)
    private String lastName;


    // constructor, getters etc.
}


// controller
@GetMapping("/examples")
public ResponseEntity<ExampleResponseModel> getAllExamples(
      @RequestParam(required = false, defaultValue = "1") int pageNum,
      @RequestParam(required = false, defaultValue = "10") int pageSize,
      @RequestParam(required = false, defaultValue = "firstName, lastName") String[] sortFields,
      @RequestParam(required = false, defaultValue = "asc") String sortOrder {
    Page<Example> pages = repository.findAll(PageRequest
            .of(pageNum - 1, pageSize, Sort.by(Direction.fromString(sortOrder), sortFields)));
    return new ResponseEntity<>(pages, HttpStatus.OK);
}

一种方法是在中间实现映射,将请求模型排序字段名称转换为实体字段名称。但是这样会很冗长,并不能解决Entity类中对字段名的排序敏感问题。我的主要目标是在排序时将客户端与实体完全分离,并确保如果另一个开发人员将类的firstName变量重命名为排序不会中断(或者至少他得到一个编译时错误来通知他修理它)。Examplefirstname

标签: javaspringsortingspring-data-jpa

解决方案


如果您使用分页和排序,我猜您在前端有一个网格或类似的东西。如果是这样,您可以创建自己的注释,该注释将保留属性的元名称,无论发生什么都不会更改。之后,您应该GET在控制器中创建一个新方法,该方法将请求通过反射读取所有元数据及其真实名称。进入网格选项卡或其他任何内容,首先应该检查其存储以查找Example实体的元数据。如果成功,只需获取此数据并在请求中使用,否则,请求新端点获取具有映射真实名称的元数据并存储它,然后才发出排序和分页请求。如果前后独立,则在后端启动时添加元数据的实现。


推荐阅读