使用Spring JPA规范的多列搜索
我想在Spring Boot后端中创建一个多字段搜索。如何使用使用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
规范执行此操作
环境
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));
}