我正在尝试使用以下结构上的JPA Criteria API进行简单查询
1)员工
public class Employee {
@Id
@Column(name = "ID", length = 64)
private String id;
@Column(name = "NAME", length = 512)
private String name;
@ManyToOne(optional = true)
@JoinColumn(name = "ORG_ID", nullable = true)
private InternalOrg organization;
}
2)InternalOrg
public class InternalOrg {
@Id
@Column(name = "ID", length = 64)
private String id;
@Column(name = "ORGANIZATION", length = 512)
private String organization;
@Column(name = "CODE", length = 64)
private String code;
}
3)查询
EntityManager em = getEntityManager();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Employee> cq = cb.createQuery(Employee.class);
Root<Employee> emp = cq.from(Employee.class);
cq.where(cb.or(emp.get(Employee_.organization).isNull(),
cb.equal(emp.get(Employee_.organization).get(InternalOrg_.code), "1")));
return em.createQuery(cq).getResultList();
正如您所见,Employee上的“organization”属性是可选的。我正在尝试做的是使用条件API的查询,该API返回“employee.organization”为NULL或“employee.organization.code”等于参数的所有记录。我该怎么办?
我做了一些测试并意识到如果我改变了这个:
cq.where(cb.or(emp.get(Employee_.organization).isNull(),
cb.equal(emp.get(Employee_.organization).get(InternalOrg_.code), "1")));
对此:
cq.where(cb.or(emp.get(Employee_.organization).isNull()));
它可以工作但只返回组织为NULL的记录。
如果我改为:
cq.where(cb.equal(emp.get(Employee_.organization).get(InternalOrg_.code), "1"));
忽略employee.organization为NULL的记录。
如何返回组织满足条件的员工以及组织为空的员工?
提前致谢,
答案 0 :(得分:1)
终于找到了解决方案。
创建获得所需结果的唯一方法是先获取(JoinType.LEFT)关系,这是最终的条件查询:
EntityManager em = getEntityManager();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Employee> cq = cb.createQuery(Employee.class);
Root<Employee> emp = cq.from(Employee.class);
emp.fetch(Employee_.domain, JoinType.LEFT);
cq.where(cb.or(emp.get(Employee_.organization).isNull(),
cb.equal(emp.get(Employee_.organization).get(InternalOrg_.code), "1")));
return em.createQuery(cq).getResultList();
感谢您的支持!
答案 1 :(得分:0)
通过调用CriteriaQuery.where方法设置的条件可以限制CriteriaQuery对象上的查询结果。调用where方法类似于在JPQL查询中设置WHERE子句。
示例:
EntityManager em = ...;
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Employee> cq = cb.createQuery(Employee.class);
Root<Employee> emp = cq.from(Employee.class);
cq.where(emp.get(Employee_.organization).isNull());
要指定多个条件谓词,请使用CriteriaBuilder接口的复合谓词方法(和/或/不)。
cq.where(emp.get(Employee_.organization).isNull())
.or(cb.eq(emp.get(Employee_.organization.code), "ABC"));
<强>更新强>
试试这个:
cq.where(
cb.or(
cb.isNull(emp.get(Employee_.organization)),
cb.equal(emp.get(Employee_.organization).get(InternalOrg_.code), "1")));