如何在 CriteriaBuilder 中编写此 JPA select 语句
How to write this JPA select statment in CriteriaBuilder
例如,这是根据email从数据库中检索成员:
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));
将 where 子句改成这样
where(cb.equal(member.get("email"), email), cb.equal(member.get("password", password));
如果您计划支持具有可选值的多个条件,请将它们收集在谓词 的集合中并使用CriteriaQuery<T> where(Predicate... restrictions);
方法。
这使您不仅可以在 where 子句中包含多个必需的条件过滤器,还可以忽略没有值的条件(e.g.because 用户未填写)。
示例
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
属性并且不为空,where子句将包含3个条件,如果为空,则只有2个。
这更容易维护,尤其是对于具有更多过滤器的查询。
一个额外的建议:使用JPA Metamodel来避免类型错误并确保在编译时进行类型安全检查。根据您使用的 JPA 实现,您可能需要向您的项目添加一些额外的库,例如
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<scope>provided</scope>
</dependency>
例如,这是根据email从数据库中检索成员:
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));
将 where 子句改成这样
where(cb.equal(member.get("email"), email), cb.equal(member.get("password", password));
如果您计划支持具有可选值的多个条件,请将它们收集在谓词 的集合中并使用CriteriaQuery<T> where(Predicate... restrictions);
方法。
这使您不仅可以在 where 子句中包含多个必需的条件过滤器,还可以忽略没有值的条件(e.g.because 用户未填写)。
示例
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
属性并且不为空,where子句将包含3个条件,如果为空,则只有2个。
这更容易维护,尤其是对于具有更多过滤器的查询。
一个额外的建议:使用JPA Metamodel来避免类型错误并确保在编译时进行类型安全检查。根据您使用的 JPA 实现,您可能需要向您的项目添加一些额外的库,例如
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<scope>provided</scope>
</dependency>