问题描述
如何在CriteriaQuery中编写此sql连接?实体之间没有关系。
from
Table_A a
left join Table_B b on b.B_id = a.B_id
left join Table_C c on c.C_id = a.column_x
left join Table_C d on d.C_id = a.column_y
left join Table_K k on k.K_id = a.column_z
left join Table_F f on f.F_id = a.column_t
left join Table_V v on v.V_id = a.column_t
and v.col_s <= b.col_w
and v.col_g >= b.col_w
类似这样的东西:
CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
CriteriaQuery<A> criteriaQuery = criteriaBuilder.createquery(getClazz());
Root<A> root = criteriaQuery.from(getClazz());
Join<B,A> join = root.join(B_.ID)
.join(C_.ID);
CriteriaQuery<A> query = criteriaQuery.select(join);
但是我无法确定哪一列应该匹配。
.join(C_.ID == A_.X)
.join(K_.ID == A_.Z)
.join(V_.ID == A_.t &&
V_.S <= B_.W &&
V_.G >= B_.W
)
解决方法
如果实体之间没有关系,则对于CriteriaAPI,您将必须对查询进行建模,就好像它们都是根表一样,并且where子句中的条件如下:
CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
CriteriaQuery<A> criteriaQuery = criteriaBuilder.createQuery(A.class);
Root<A> rootA = criteriaQuery.from(A.class);
Root<B> rootB = criteriaQuery.from(B.class);
Root<C> rootC1 = criteriaQuery.from(C.class);
Root<C> rootC2 = criteriaQuery.from(C.class);
Root<K> rootK = criteriaQuery.from(K.class);
Root<F> rootF = criteriaQuery.from(F.class);
Root<V> rootV = criteriaQuery.from(V.class);
List<Predicate> predicates = new ArrayList<>();
predicates.add(criteriaBuilder.equal(rootA.get(A_.bId),rootB.get(B_.bId)));
predicates.add(criteriaBuilder.equal(rootA.get(A_.columnX),rootC1.get(C_.cId)));
predicates.add(criteriaBuilder.equal(rootA.get(A_.columnY),rootC2.get(C_.cId)));
predicates.add(criteriaBuilder.equal(rootA.get(A_.columnZ),rootK.get(K_.kId)));
predicates.add(criteriaBuilder.equal(rootA.get(A_.columnT),rootF.get(K_.fId)));
predicates.add(
criteriaBuilder.and(
criteriaBuilder.equal(rootA.get(A_.columnT),rootV.get(V_.vId)),criteriaBuilder.and(
criteriaBuilder.lessThanOrEqualTo(rootV.get(V_.colS),rootB.get(B_.colW)),criteriaBuilder.greaterThanOrEqualTo(rootV.get(V_.colG),rootB.get(B_.colW))
)
)
);
criteriaQuery.where(predicates.toArray(new Predicate[predicates.size()]));
尽管我的建议是您对实体中的关系进行建模,因为这会使N个笛卡尔乘积等于根数的N个,这并不是最佳选择