Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Spring JPA规范的多列搜索_Spring_Spring Boot_Spring Data Jpa_Jpql_Jpa Criteria - Fatal编程技术网

使用Spring JPA规范的多列搜索

使用Spring JPA规范的多列搜索,spring,spring-boot,spring-data-jpa,jpql,jpa-criteria,Spring,Spring Boot,Spring Data Jpa,Jpql,Jpa Criteria,我想在Spring Boot后端中创建一个多字段搜索。如何使用规范执行此操作 环境 Springboot Hibernate Gradle Intellij 前端的UI是一个Jquery数据表。每列允许应用单个字符串搜索词。跨多个列的搜索词由和连接 我已经将来自前端的过滤器填充到Java对象中 步骤1 扩展JPA规范执行器 public interface SomeRepository extends JpaRepository<Some, Long>, PagingAndSor

我想在Spring Boot后端中创建一个多字段搜索。如何使用
规范执行此操作

环境

Springboot
Hibernate
Gradle
Intellij
前端的UI是一个Jquery数据表。每列允许应用单个字符串搜索词。跨多个列的搜索词由
连接

我已经将来自前端的过滤器填充到Java对象中

步骤1 扩展JPA规范执行器

public interface SomeRepository extends JpaRepository<Some, Long>, PagingAndSortingRepository<Some, Long>, JpaSpecificationExecutor {
公共接口SomeRepository扩展了JPA存储库、分页和排序存储库、JPA指定执行器{
步骤2 创建一个新类SomeSpec

这就是我对代码的外观和工作方式感到困惑的地方

我需要为每一列指定一个方法吗? 什么是根,什么是标准生成器? 还需要什么

我是JPA的新手,所以虽然我不需要任何人为我编写代码,但详细的解释会很好

更新
看来QueDDSL是更容易和更好的方法来处理这个问题。我正在使用Gealle。我需要改变我的构建吗?GeDLE来自< < /P> > P>您可以考虑使用Spring Data支持QueryDSL,因为您将得到很多,而不必编写很多代码,也就是说,您实际上不必编写这些规范。

有关概述,请参见此处:

尽管这种方法非常方便(您甚至不必 编写一行实现代码以获取查询 它有两个缺点:第一,查询方法的数量 对于更大的应用程序可能会增长,这是第二个原因 点-查询定义了一组固定的标准来避免这些问题 两个缺点,如果你能想出一套 可以动态组合以构建 询问

因此,您的存储库本质上变成:

public interface SomeRepository extends JpaRepository<Some, Long>,
     PagingAndSortingRepository<Some, Long>, QueryDslPredicateExecutor<Some>{

}

因此,有了上述功能,您只需在项目中启用QueryDSL,UI现在应该能够根据各种条件组合对数据进行过滤、排序和分页。

如果您不想使用QueryDSL,您必须编写自己的规范。首先,您需要从
JpaSpecificationEx扩展存储库ecutor
与您一样。请确保添加泛型执行器(
JpaSpecificationExecutor

在此之后,您必须创建三个规范(每列一个),在这些规范中,它们将这些规范定义为类中的静态方法。基本上,创建规范意味着您必须将
规范
子类化,该子类只有一个方法要实现

如果您使用的是Java 8,则可以使用lambdas创建匿名内部类,例如:

 public class SomeSpecs {
     public static Specification<Some> withAddress(String address) {
          return (root, query, builder) -> {
               // ...
          };
     }
 }
或者,如果您想使用类似
的查询,您可以使用:

public class SomeSpecs {
     public static Specification<Some> withAddress(String address) {
          return (root, query, builder) -> builder.like(root.get("address"), "%" + address + "%");
     }
 }
您可以使用静态导入来导入
withAddress()
withName()
withDate()
以使其更易于阅读。
where()
方法也可以静态导入(来自)

但是请注意,可能必须调整上述方法,因为如果地址字段为
null
,则不希望对其进行筛选。可以通过返回
null
来完成此操作,例如:

public List<Some> getSome(String address, String name, Date date) {
    return repository.findAll(where(withAddress(address))
         .and(withName(name))
         .and(withDate(date));
}
public List<Some> getSome(String address, String name, Date date) {
    return repository.findAll(where(address == null ? null : withAddress(address))
         .and(name == null ? null : withName(name))
         .and(date == null ? null : withDate(date));
}
public List getSome(字符串地址、字符串名称、日期){
返回repository.findAll(其中(地址==null?null:withAddress(地址))
.和(name==null?null:withName(name))
.和(日期==null?null:withDate(日期));
}

我不确定是否需要问一个围绕QueryDSL的新问题,或者这里的答案是否可以调整?如果是围绕Gradle,那么我不知道Gradle,但您链接到的问题表明需要什么。这里还有一个问题:我应该使用哪个QueryDSL?com.mysema.QueryDSL还是com.QueryDSL?当然,但如果我确实想使用它?@g00glen00b-你能在这里引导我吗:?
public List<Some> getSome(String address, String name, Date date) {
    return repository.findAll(where(withAddress(address))
         .and(withName(name))
         .and(withDate(date));
}
public List<Some> getSome(String address, String name, Date date) {
    return repository.findAll(where(address == null ? null : withAddress(address))
         .and(name == null ? null : withName(name))
         .and(date == null ? null : withDate(date));
}