【问题标题】:Spring data JPA query with varying params具有不同参数的 Spring 数据 JPA 查询
【发布时间】:2016-08-19 22:18:03
【问题描述】:

我试图通过几个参数来找到表格的必要元素,比如

List <Person> findByLastname(String lastname);

但是,如果将来要添加/删除其中一些参数怎么办?如何使用 Spring Data JPA 使某些参数成为可选参数,类似这样

List <Person> findByOptionalLastnameAndOptionalFirstNameAnd...(String lastname, String firstname,...);

【问题讨论】:

    标签: spring spring-data spring-data-jpa


    【解决方案1】:

    您不能使用 Spring Data 的可选参数和命名方法解析器,您应该为每种可能性创建 on 方法,这为什么更容易我建议您使用规范,您可以在其中根据列表构建查询条件。

    如果你不确定你的参数是否会被修复,那么我会使用这个方法:

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

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

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

    【讨论】:

    • 我编辑了这个问题,所以目标更容易理解。因为我有些怀疑如何在我的案例中使用这个规范。
    • @BohdanZ 我在回复中回复了你,但我担心你想要的东西在 spring data 命名的方法解析器中是不允许的,你应该用所有可能的组合创建 N 方法,你会同意是太复杂了,那我建议你用 Specifications 会更干净,更容易理解 scale,...
    【解决方案2】:

    我认为这篇文章是您正在寻找的:

    JPA Criteria API Queries

    您可以根据输入通过向查询添加多个谓词来获得动态条件。

    这个参考可能也有用Spring Data JPA Specifications

    【讨论】:

    • 也许你可以举个例子(sn-p代码)来回答更好:)
    【解决方案3】:

    是的,这是可能的,但是您需要进行不同的查询 根据给定的参数。

    这将是这样的:

    @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 提供更好的解决方案...我对“Querydsl”一无所知,我会照顾它。
    • 查看Spring data JPA reference documentation 获取有价值的示例(查找所有出现的“querydsl”)。
    【解决方案4】:

    使用querydsl framework 解决了我的任务。如果使用 gradle,则需要在 build.gradle 中添加this

    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,很好的例子是here,很好的教程是here

    @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();
    

    【讨论】:

      【解决方案5】:

      通过示例使用查询

      Person person = new Person();                         
      person.setLastname("Smith");                          
      Example<Person> example = Example.of(person);
      List<Person> results = personRepository.findAll(example);
      

      文档http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#query-by-example

      这是 Adam Erstelle 对Spring Data JPA: Query by Example?的回答

      【讨论】:

        猜你喜欢
        • 2012-06-03
        • 1970-01-01
        • 2021-09-15
        • 1970-01-01
        • 1970-01-01
        • 2012-05-04
        • 2021-02-17
        • 2018-08-16
        相关资源
        最近更新 更多