简体   繁体   English

通过用户定义的动态where子句条件在JPA中创建高级搜索

[英]Create advanced search in JPA through user defined dynamic where clause conditions

I'd like to create a search where the user defines the where clause conditions. 我想创建一个用户定义where子句条件的搜索。 If the user enters a parameter in the search form, then that parameter is included in the WHERE clause. 如果用户在搜索表单中输入参数,则该参数将包含在WHERE子句中。 If the parameter is left blank, it is omitted from the where clause. 如果该参数保留为空白,那么它将在where子句中省略。 If the entire form is blank,the query should returns a SELECT ALL and the entire table. 如果整个表单为空,则查询应返回SELECT ALL和整个表。 In this way the query becomes successively more precise the more parameters entered by the user. 这样,用户输入的参数越多,查询就变得越来越精确。

I am trying the below code but this seems to require the parameters to be input and returns results only if the actual data matches with ALL of the Predicates specified. 我正在尝试下面的代码,但这似乎要求输入参数,并且仅当实际数据与指定的所有谓词匹配时才返回结果。 It looks like the Predicates are being included in the array even if they are NULL and empty? 看起来谓词是否包含在数组中,即使它们为NULL并且为空? Either that or I'm missing something very obvious in how I've written this. 要么是我在写这篇文章时就遗漏了很明显的东西。

My questions are: 我的问题是:

1) If the search form is left blank, would the Predicates be excluded from the array? 1)如果将搜索表单留空,是否将谓词从数组中排除?

2) If yes, wouldn't the query default to a SELECT ALL? 2)如果是,查询是否默认为全选? [query.from(Contacts.class)]? [query.from(Contacts.class)]?

I saw a similar question but didn't really tell me how to achieve the above since it appears that the logic of my code is correct. 我看到了类似的问题,但是并没有真正告诉我如何实现上述目标,因为看来我的代码逻辑是正确的。

JPA where clause any JPA where子句any

Thanks in advance for any guidance! 预先感谢您的指导!

public ListDataModel<Contacts> qSearchContacts(String firstName, String surName, Integer countryid, Integer companyId) {

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Contacts> query = cb.createQuery(Contacts.class);
    Root<Contacts> cont = query.from(Contacts.class);
    query.select(cont);

    List<Predicate> predicateList = new ArrayList<Predicate>();
    Predicate firstnamePredicate, surnamePredicate, countryPredicate, companyPredicate;

    if ((firstName != null) && (!(firstName.isEmpty()))) {
        firstnamePredicate = cb.like(cb.upper(cont.<String>get("firstName")), "%" + firstName.toUpperCase() + "%");
        predicateList.add(firstnamePredicate);
    }


    if ((surName != null) && (!(surName.isEmpty()))) {
        surnamePredicate = cb.like(cb.upper(cont.<String>get("surName")), "%" + surName.toUpperCase() + "%");
        predicateList.add(surnamePredicate);

     }

    if (countryid != null) {
        Join<Contacts, Country> country = cont.join("country");
        countryPredicate = cb.equal(country.<Integer>get("countryid"), countryid);
        predicateList.add(countryPredicate);
    } 
    }

    if (companyId != null) {
        Join<Contacts, Company> company = cont.join("company");
        companyPredicate = cb.equal(company.<Integer>get("companyId"), companyId);
        predicateList.add(companyPredicate);
    }

    Predicate[] predicateArray = new Predicate[predicateList.size()];
    predicateList.toArray(predicateArray);
    query.where(predicateArray);
    ListDataModel<Contacts> contactResultList = new ListDataModel<Contacts>(em.createQuery(query).getResultList());

    return contactResultList;
}

I solved this. 我解决了 The above code seems to create the predicates in all cases and there are no explicit conditions for excluding the predicates from the array list or executing a SELECT ALL in the event that no predicates exist. 上面的代码似乎在所有情况下都创建了谓词,并且没有明确的条件可将谓词从数组列表中排除或在不存在谓词的情况下执行SELECT ALL。 I rewrote the code explicitly each parameter using a TypedQuery object. 我使用TypedQuery对象显式重写了每个参数的代码。 This is now resulting in the desired behavior. 现在,这导致了所需的行为。 No predicates result in a SELECT ALL. 没有谓词会导致全选。 Each predicate is only included as a WHERE clause condition if it is not null and empty. 如果每个谓词不为null和空,则仅将其作为WHERE子句条件包括在内。 Hope this helps. 希望这可以帮助。

public ListDataModel<Contacts> qSearchContacts(String firstName, String surName, Integer countryid, Integer companyId) {

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Contacts> query = cb.createQuery(Contacts.class);
    Root<Contacts> cont = query.from(Contacts.class);
    query.select(cont);

    // Join<Contacts, Country> country = cont.join("country", JoinType.LEFT);
    List<Predicate> predicateList = new ArrayList<Predicate>();

    if ((firstName != null) && (!(firstName.isEmpty()))) {
        ParameterExpression<String> p
                = cb.parameter(String.class, "firstName");
        predicateList.add(cb.like(cb.upper(cont.<String>get("firstName")), "%" + firstName.toUpperCase() + "%"));

    }

    if ((surName != null) && (!(surName.isEmpty()))) {
        ParameterExpression<String> p
                = cb.parameter(String.class, "surName");
        predicateList.add(cb.like(cb.upper(cont.<String>get("surName")), "%" + surName.toUpperCase() + "%"));

    }

    if ((countryid != null) && (countryid != 0)) {
        Join<Contacts, Country> country = cont.join("country");
        ParameterExpression<Integer> ci
                = cb.parameter(Integer.class, "countryid");
        predicateList.add(cb.equal(country.get("countryid"), ci));
    }

    if ((companyId != null) && (companyId != 0)) {
        Join<Contacts, Company> company = cont.join("company");
        ParameterExpression<Integer> co
                = cb.parameter(Integer.class, "companyId");
        predicateList.add(cb.equal(company.get("companyId"), co));
    }

    if (predicateList.size() == 0) {
        query.select(cont);
    } else {
        if (predicateList.size() == 1) {
            query.where(predicateList.get(0));
        } else {
            query.where(cb.and(predicateList.toArray(new Predicate[0])));
        }
    }

    TypedQuery<Contacts> tq = em.createQuery(query);
    if (firstName != null) {
        tq.setParameter("firstName", firstName);
    }
    if (surName != null) {
        tq.setParameter("surName", surName);
    }

    if ((countryid != null) && (countryid != 0)) {
        tq.setParameter("countryid", countryid);
    }

    if((companyId != null) && (companyId != 0)) {
        tq.setParameter("companyId", companyId);
    }

    ListDataModel<Contacts> contactsResultList = new ListDataModel<Contacts>(tq.getResultList());
    return contactsResultList;

}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM