Spring Data 为什么需要 Specifications

在 Spring Boot 中执行查询的最常见方法之一是使用如下查询方法:

interface ProductRepository extends JpaRepository<Product, String>, 
                  JpaSpecificationExecutor<Product> {
  
  List<Product> findAllByNameLike(String name);
  
  List<Product> findAllByNameLikeAndPriceLessThanEqual(
                  String name, 
                  Double price
                  );
  
  List<Product> findAllByCategoryInAndPriceLessThanEqual(
                  List<Category> categories, 
                  Double price
                  );
  
  List<Product> findAllByCategoryInAndPriceBetween(
                  List<Category> categories,
                  Double bottom, 
                  Double top
                  );
  
  List<Product> findAllByNameLikeAndCategoryIn(
                  String name, 
                  List<Category> categories
                  );
  
  List<Product> findAllByNameLikeAndCategoryInAndPriceBetween(
                  String name, 
                  List<Category> categories,
                  Double bottom, 
                  Double top
                  );
}

查询方法(query methods)的问题是我们只能指定固定数量的标准。此外,查询方法的数量随着用例的增加而迅速增加。

在某些时候,查询方法中有许多重叠的条件,如果其中任何一种发生变化,我们将不得不对多种查询方法进行更改。

此外,当我们的查询中有很长的字段名称和多个条件时,查询方法的长度可能会显着增加。因此,可能需要一段时间才能理解如此冗长的查询及其目的:

List<Product> findAllByNameLikeAndCategoryInAndPriceBetweenAndManufacturingPlace_State(String name,
                                             List<Category> categories,
                                             Double bottom, Double top,
                                             STATE state);

使用Specifications,我们可以通过创建原子谓词来解决这些问题。通过给这些谓词一个有意义的名字,我们可以清楚地说明它们的意图。我们将在使用规范编写查询部分中了解如何将上述内容转换为更有意义的查询 。

Specifications允许我们以编程方式编写查询。因此,我们可以根据用户输入动态构建查询。