Ras*_*nke 5 criteria-api java-ee-6 jpa-2.0
以某种方式可以使用JPA 2 Criteria API执行以下查询之一吗?基本上,Profiles使用了许多模板.系统中的每个用户都有任意数量的配置文件和两个活动配置文件.我想获取所有模板以及拥有使用它的活动配置文件的用户数.
备选方案1
SELECT t.id, count(p.id)
FROM template t
LEFT JOIN profile p ON p.template_id = t.id
LEFT JOIN users u ON (u.active_profile_id = p.id OR u.active_personal_profile_id = p.id)
GROUP BY t.id
Run Code Online (Sandbox Code Playgroud)
备选方案2
SELECT t.id, count(p.id)
FROM COMPETENCE.template t
LEFT JOIN COMPETENCE.profile p ON (p.template_id = t.id)
LEFT JOIN users u1 on u1.active_profile_id = p.id
LEFT JOIN users u2 on u2.active_personal_profile_id = p.id
GROUP BY t.id
Run Code Online (Sandbox Code Playgroud)
如果我跳过了获取所有模板的要求,我可以简单地使用User和Profile作为Roots,以下就足够了:
CriteriaQuery<Tuple> cq = cb.createTupleQuery();
Root<User> from = cq.from(User.class);
Root<Profile> from2 = cq.from(Profile.class);
Join<Profile, Template> join = from2.join(Profile_.template);
cq.where(cb.or(
cb.equal(from.get(User_.activeCompetenceProfile), from2),
cb.equal(from.get(User_.activePersonalProfile), from2)
));
cq.groupBy(join.get(Template_.id));
cq.multiselect(join.get(Template_.id), cb.count(from2.get(Profile_.id)));
List<Tuple> tuples = em.createQuery(cq).getResultList();
Run Code Online (Sandbox Code Playgroud)
但是为了获得所有模板,我相信我不能使用WHERE子句,但是在第一次查询中需要外连接.但是,备选方案1似乎不可能,因为您无法为连接设置特定的ON子句,而备选方案2似乎不可能,因为用户和模板都需要同时为Root.要获取所有模板,我需要使用模板作为root,并将其与Profile连接.这很顺利,但由于ON参数存储在User而不是Profile中,因此我无法加入Profile with User.据我所知,你不能在第二个表中存储的参数上与另一个表连接.
该任务当然可以通过循环方式解决,例如选择所有模板进行第二次查询并将其与第一个查询的结果合并,但如果可以在单个查询中进行,则可以创建更清晰的代码.
| 归档时间: |
|
| 查看次数: |
3987 次 |
| 最近记录: |