如何通过在 JPA 或 Hibernate 中使用条件生成器加入相同的 table 来 select 值
how to select values by joining same table using criteria builder in JPA or Hibernate
我们的 table 中有以下员工数据,我们需要找到标志为假的所有员工,如果报告人标志为真,即使此标志为假,我们也应该排除经理
示例数据
id name manager_name flag
1 a null false
2 b a true
3 c d false
4 e null false
5 f e false
输出应该是
id name manager_name flag
3 c d false
4 e null false
5 f e false
如何使用 Hibernate Criteria builder 实现上述要求?
在 SQL
中,这是使用以下查询实现的
select * from employee where flag = false and id not in (
select e1.id from employee e1, employee e2 where e1.name = e2.manager_name
and e2.flag= true)
添加到员工class --->
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="managerName", referencedColumnName="name",insertable=false,
updatable=false)
private Employee manager;
条件查询--->
CriteriaBuilder cb = em.getCriteriaBuilder() ;
CriteriaQuery<Employee> cq = cb.createQuery(Employee.class);
Root<Employee> root = cq.from(Employee.class);
Subquery<Integer> sub = cq.subquery(Integer.class);
Root<Employee> subRoot = sub.from(Employee.class);
Join <Employee,Employee> empJoin = subRoot.join("manager",JoinType.INNER);
Predicate subP2 = cb.equal(subRoot.get("flag"),true);
sub.where(subP2);
sub.select(empJoin.get("id"));
Predicate flagP = cb.equal(root.get("flag"),false);
Predicate idNot = cb.not(root.get("id").in(sub)) ;
Predicate finalP = cb.and(flagP,idNot);
cq.where(finalP);
TypedQuery<Employee>query = em.createQuery(cq.select(root));
List<Employee> result = query.getResultList();
已生成 Hibernate 查询 --->
select
employee0_.id as id1_0_,
employee0_.flag as flag2_0_,
employee0_.manager_name as manager_3_0_,
employee0_.name as name4_0_
from
employee employee0_
where
employee0_.flag=?
and (
employee0_.id not in (
select
employee2_.id
from
employee employee1_
inner join
employee employee2_
on employee1_.manager_name=employee2_.name
where
employee1_.flag=?
)
)
我们的 table 中有以下员工数据,我们需要找到标志为假的所有员工,如果报告人标志为真,即使此标志为假,我们也应该排除经理
示例数据
id name manager_name flag
1 a null false
2 b a true
3 c d false
4 e null false
5 f e false
输出应该是
id name manager_name flag
3 c d false
4 e null false
5 f e false
如何使用 Hibernate Criteria builder 实现上述要求?
在 SQL
中,这是使用以下查询实现的
select * from employee where flag = false and id not in (
select e1.id from employee e1, employee e2 where e1.name = e2.manager_name
and e2.flag= true)
添加到员工class --->
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="managerName", referencedColumnName="name",insertable=false,
updatable=false)
private Employee manager;
条件查询--->
CriteriaBuilder cb = em.getCriteriaBuilder() ;
CriteriaQuery<Employee> cq = cb.createQuery(Employee.class);
Root<Employee> root = cq.from(Employee.class);
Subquery<Integer> sub = cq.subquery(Integer.class);
Root<Employee> subRoot = sub.from(Employee.class);
Join <Employee,Employee> empJoin = subRoot.join("manager",JoinType.INNER);
Predicate subP2 = cb.equal(subRoot.get("flag"),true);
sub.where(subP2);
sub.select(empJoin.get("id"));
Predicate flagP = cb.equal(root.get("flag"),false);
Predicate idNot = cb.not(root.get("id").in(sub)) ;
Predicate finalP = cb.and(flagP,idNot);
cq.where(finalP);
TypedQuery<Employee>query = em.createQuery(cq.select(root));
List<Employee> result = query.getResultList();
已生成 Hibernate 查询 --->
select
employee0_.id as id1_0_,
employee0_.flag as flag2_0_,
employee0_.manager_name as manager_3_0_,
employee0_.name as name4_0_
from
employee employee0_
where
employee0_.flag=?
and (
employee0_.id not in (
select
employee2_.id
from
employee employee1_
inner join
employee employee2_
on employee1_.manager_name=employee2_.name
where
employee1_.flag=?
)
)