Java 在Spring中使用许多可选查询参数处理RESTAPI请求

Java 在Spring中使用许多可选查询参数处理RESTAPI请求,java,spring,spring-boot,spring-data,Java,Spring,Spring Boot,Spring Data,为了简单起见,让我们假设我有一个文档对象,它有七个字段(但想象一下,它可以有更多字段)。此对象的外观如下所示: @Getter @Setter public class Document { private String fileName; private String fileType; private String createdBy; private Date createdAt; private Date lastModifiedAt; p

为了简单起见,让我们假设我有一个
文档
对象,它有七个字段(但想象一下,它可以有更多字段)。此对象的外观如下所示:

@Getter
@Setter
public class Document {
    private String fileName;
    private String fileType;
    private String createdBy;
    private Date createdAt;
    private Date lastModifiedAt;
    private List<String> modifiers;
    private Long timesModified;
}
这方面的问题是,因为我们使用
optionalFilters
作为
Map
,这需要我们在代码中执行大量的强制转换,总体而言,这使得我们的代码非常乏味和麻烦,因为我们必须迭代整个Map,并根据传递的字段创建自定义查询。为了尝试改进这一点,我创建了一个
OptionalFilters
对象:

@Getter
@Setter
@NoArgsConstructor
public class OptionalFilters {
    private String fileName;
    private String fileType;
    private String createdBy;
    private Date createdAt;
    private Date lastModifiedAt;
    private List<String> modifiers;
    private Long timesModified;
}
@Getter
@塞特
@诺尔格构装师
公共类可选过滤器{
私有字符串文件名;
私有字符串文件类型;
创建的私有字符串;
私人日期创建日期;
最后修改的私人日期;
私有列表修饰符;
修改私人长时间通信;
}
并将端点修改为:

@GetMapping(value = {RestApi.LIST})
public ResponseEntity<List<Document>> getDocuments (@Valid OptionalFilters optionalFilters) {
    List<Document> documents = documentService.getListOfDocuments(optionalFilters);
    if (documents != null) {
        return new ResponseEntity<>(documents, HttpStatus.OK);
    }
    return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
@GetMapping(值={RestApi.LIST})
公共响应属性getDocuments(@Valid OptionalFilters OptionalFilters){
列表文档=documentService.getListOfDocuments(可选过滤器);
if(文档!=null){
返回新的响应(文档,HttpStatus.OK);
}
返回新的ResponseEntity(未找到HttpStatus.NOT_);
}
然而,尽管这简化了我们接收参数并从中提取值的方式,但我们仍然需要遍历所有参数并创建自定义查询。是否有某种方法可以提升和利用
Spring数据
(或任何其他解决方案),从而不必根据传递的每个查询参数创建自定义查询?如果可能有帮助的话,我将使用
Solr
作为存储库。

使用是最简单的选择之一,但它有其局限性。摘自上述链接:

  • 限制
    与所有事情一样,示例查询API也有一些限制。例如:
    • 不支持嵌套和分组语句,例如: (firstName=?0,lastName=?1)或seatNumber=?2
    • 字符串匹配仅包括精确、不区分大小写、开始、结束、包含和正则表达式 除字符串以外的所有类型都是完全匹配的
    如果您的筛选从未过于复杂,那么通过示例查询是合适的选择。但是当像上面这样的restriction影响到CPU冷却器的风扇时,可以选择使用它来构造查询

    还有一个很大的区别是,使用示例查询时,您需要通过示例的getter和setter显式地填充示例。有了规范,您就可以用一种通用的方式(使用Java泛型),只需使用字段名

    在您的例子中,您可以将映射传递给泛型方法,并通过循环和添加
    来创建过滤(请注意,链接的示例大部分都是静态的,但不一定是静态的,您只需要字段名/标准-对以泛型方式循环它)

    使用规范,您可以通过示例查询完成任何操作,也可以完成几乎所有其他操作。熟悉规范的开销可能更大,但使用规范的优势将是有益的

    简言之:

    Spring
    接口规范
    基于JPA
    标准查询
    ,对于每一种,您只需要实现一种方法:

    Predicate toPredicate (Root<User> root, CriteriaQuery<?> query, CriteriaBuilder builder);
    

    一开始可能看起来很复杂或困难,但事实并非如此。
    规范的最大优点是,您几乎可以通过编程来执行任何操作,而不是操纵JPQL查询等。

    如果您使用Solr,您也可以创建动态查询。试试这个:@Gurkanİlleez感谢您的回复,这就是我今天正在做的。问题是,我需要根据发送的参数创建一个自定义查询,这是我想要避免的。我想创建一个查询,无论发送的参数是什么,我都可以重用它。@RoieBeck谢谢,我将签出它并用结果更新它
    Predicate toPredicate (Root<User> root, CriteriaQuery<?> query, CriteriaBuilder builder);
    
    repository.findAll(Specification.where(spec1).and(spec2));