gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 12:09:45 24 4
gpt4 key购买 nike

我想创建一个搜索,其中用户定义 where 子句条件。如果用户在搜索表单中输入参数,则该参数将包含在 WHERE 子句中。如果该参数留空,则 where 子句中将省略该参数。如果整个表单为空,则查询应返回 SELECT ALL 和整个表。这样,用户输入的参数越多,查询逐渐变得更加精确。

我正在尝试下面的代码,但这似乎需要输入参数,并且仅当实际数据与指定的所有谓词匹配时才返回结果。看起来谓词被包含在数组中,即使它们是 NULL 和空?要么就是我在写这篇文章时遗漏了一些非常明显的东西。

我的问题是:

1) 如果搜索表单留空,谓词是否会从数组中排除?

2) 如果是,查询不是默认为 SELECT ALL 吗? [query.from(Contacts.class)]?

我看到了一个类似的问题,但并没有真正告诉我如何实现上述目标,因为看起来我的代码逻辑是正确的。

JPA where clause any

预先感谢您的指导!

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;
}

最佳答案

我解决了这个问题。上面的代码似乎在所有情况下都创建了谓词,并且没有明确的条件从数组列表中排除谓词或在不存在谓词的情况下执行 SELECT ALL。我使用 TypedQuery 对象明确地重写了代码中的每个参数。现在这导致了所需的行为。没有谓词会导致 SELECT ALL。每个谓词仅在不为 null 且不为空时才包含为 WHERE 子句条件。希望这可以帮助。

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;

}
}

关于java - 通过用户定义的动态 where 子句条件在 JPA 中创建高级搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30900276/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com