Spring数据JPA查询与不同参数

5

我正在尝试通过几个参数找到表格的必要元素,例如

List <Person> findByLastname(String lastname);

但是如果未来添加/删除了某些参数怎么办?如何使用Spring Data JPA使一些参数变得可选,类似于以下内容:

List <Person> findByOptionalLastnameAndOptionalFirstNameAnd...(String lastname, String firstname,...);
5个回答

3

我使用querydsl框架解决了我的任务。如果您使用gradle,您需要在build.gradle中添加这个

dependencies {
  compile "com.mysema.querydsl:querydsl-jpa:3.6.3"

  compile "com.mysema.querydsl:querydsl-apt:3.6.3:jpa" // Magic happens here

  compile "org.hibernate:hibernate-entitymanager:4.3.5.Final"

  compile 'com.h2database:h2:1.4.187'
}

还可以使用JPA Criteria API,一个很好的示例在这里,而一个很好的教程则在这里

@Entity
public class A {
    @Id private Long id;    
    String someAttribute;
    String someOtherAttribute;
    ...
}

查询本身:

//some parameters to your method
    String param1 = "1";
    String paramNull = null;

    CriteriaBuilder qb = em.getCriteriaBuilder();
    CriteriaQuery cq = qb.createQuery();
    Root<A> customer = cq.from(A.class);

    //Constructing list of parameters
    List<Predicate> predicates = new ArrayList<Predicate>();

    //Adding predicates in case of parameter not being null
    if (param1 != null) {
        predicates.add(
                qb.equal(customer.get("someAttribute"), param1));
    }
    if (paramNull != null) {
        predicates.add(
                qb.equal(customer.get("someOtherAttribute"), paramNull));
    }
    //query itself
    cq.select(customer)
            .where(predicates.toArray(new Predicate[]{}));
    //execute query and do something with result
    em.createQuery(cq).getResultList();

2

1
也许您可以提供示例(代码片段),这样回答会更好 :) - masadi zainul

2

1
您不能同时使用Spring Data的可选参数和命名方法解析器,您应该为每种可能性创建一个方法,这就是为什么我建议您使用Specification来根据条件列表构建查询,以使其更容易。

如果您不确定自己的参数是否固定,那么我会使用以下方法:

  1. 使用Spring规范,您可以根据某些条件构建查询。 https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/

  2. 创建一些JUnit测试,确保您的查询是稳定的,并且如果有人添加/删除某些参数,则应修改JUnit以使其保持更新。

如果您对如何使用有疑问,请告诉我,我可以与您分享其他示例。


我编辑了这个问题,以便更清楚地了解目标。因为我对如何在我的情况下使用这个规范有一些疑问。 - BohdanZ
@BohdanZ 我在我的回复中已经回答了你的问题,但我担心你想要的不符合Spring Data命名方法解析器的规定。你应该创建N个方法来包含所有可能的组合,而你会同意这太过复杂。因此,我建议你使用Specifications,这样代码将更加简洁易懂且易于扩展... - cralfaro

-1
是的,这是可能的,但是您需要根据给定参数进行不同的查询。
@RequestMapping("find")
public List<Person> findByOptional...(@RequestParam(value = "fName", required = false) String fname,@RequestParam(value = "lName", required = false) String lname) {
    //here you need to check you data for not null and create methods accordingly 
}

但这并不是一个好的建议,如果你传递了更多的可选参数,那么就需要放置更多的if else条件语句。


这将是最糟糕的方式。使用 Querydsl 来获得干净的解决方案。 - Marc Tarin
谢谢@Marc提供更好的解决方案...我不了解"Querydsl",我会去了解一下。 - Riddhi Gohil
请查看Spring data JPA参考文档,以获取有价值的(querydsl)示例。 - Marc Tarin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接