如何在CriteriaBuilder中编写此JPA选择语句

时间:2015-12-09 07:18:56

标签: jpa jboss jpa-2.0

例如,这是根据电子邮件从数据库中检索成员:

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Member> criteria = cb.createQuery(Member.class);
    Root<Member> member = criteria.from(Member.class);        

    criteria.select(member).where(cb.equal(member.get("email"), email));

    return em.createQuery(criteria).getSingleResult();

现在,如果我想添加一个条件,请检索使用电子邮件和密码的成员。我该如何写'select'语句?

criteria.select(member).where(cb.equal(member.get("email"), email));

2 个答案:

答案 0 :(得分:2)

where 子句更改为此

where(cb.equal(member.get("email"), email), cb.equal(member.get("password", password));

答案 1 :(得分:1)

如果您计划支持具有可选值的多个条件,请将其收集在谓词的集合中,并使用CriteriaQuery<T> where(Predicate... restrictions);方法。 这使您不仅可以在where子句中包含多个必需的条件过滤器,还可以忽略没有值的条件(例如,因为用户没有填写它们)。
示例

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Member> criteria = cb.createQuery(Member.class);
Root<Member> member = criteria.from(Member.class);        

//create a holder for all conditions in `where` clause
List<Predicate> predicates = new ArrayList<>();
criteria.select(member).where(predicates.toArray(new Predicate[predicates.length()]));

//email is required
predicates.add(cb.equal(member.get("email"), email));
//password is required
predicates.add(cb.equal(member.get("password"), password));

//'status' is optional, only add it if it was not empty
if (status != null) {
  predicates.add(cb.equal(member.get("status"), status));
}

return em.createQuery(criteria).getSingleResult();

如果提供status属性且不为null,则where子句将包含3个条件,如果为null,则只有2个。

这更易于维护,尤其是对于具有更多过滤器的查询。

另外一个建议:使用JPA Metamodel来避免类型错误并确保在编译时进行类型安全检查。根据您使用的JPA实现,您可能需要向项目添加一些额外的库,例如

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-jpamodelgen</artifactId>
        <scope>provided</scope>
    </dependency>