假设我有3张桌子
STUDENT
----------------------
STUDENT_ID | FULL_NAME
======================
SUBJECT
-----------------------------------------------------------------------
SUBJECT_ID | SUBJECT_NAME | STATUS | START_DATE | END_DATE | STUDENT_ID
=======================================================================
CLAZZ
-------------------------------------------
CLAZZ_ID | CLAZZ_NAME | STATUS | STUDENT_ID
===========================================
我希望获得学生在一段时间内学到的科目和课程数量。所以我可以使用这个原生SQL:
WITH SUBJECT_COUNT AS (
SELECT STUDENT_ID, COUNT(*) AS SUB_COUNT
FROM SUBJECT
WHERE STATUS=1 AND DateParam >= START_DATE AND DateParam <= END_DATE
GROUP BY STUDENT_ID
), CLAZZ_COUNT AS (
SELECT STUDENT_ID, COUNT(*) AS CLZ_COUNT
FROM CLAZZ
WHERE STATUS=1
GROUP BY STUDENT_ID
)
SELECT S.STUDENT_ID, S.FULL_NAME, SC.SUB_COUNT, CC.CLZ_COUNT
FROM STUDENT S
LEFT JOIN SUBJECT_COUNT SC ON S.STUDENT_ID=SC.STUDENT_ID
LEFT JOIN CLAZZ_COUNT CC ON S.STUDENT_ID=CC.STUDENT_ID
ORDER BY SC.SUB_COUNT, CC.CLZ_COUNT
如何将此本机SQL转换为JPA 2.1 SQL。或者我能得到相同结果的任何其他解决方案都会很好。 非常感谢你
答案 0 :(得分:0)
您可以使用EntityManager.createNativeQuery
如果您没有具体理由使用HQL
,这是正常的。最简单的方法是使用原生查询:
em.createNativeQuery("WITH SUBJECT_COUNT AS ( " +
" SELECT STUDENT_ID, COUNT(*) AS SUB_COUNT " +
" FROM SUBJECT " +
" WHERE STATUS=1 AND DateParam >= :START_DATE AND DateParam <= :END_DATE " +
" GROUP BY STUDENT_ID " +
"), CLAZZ_COUNT AS ( " +
" SELECT STUDENT_ID, COUNT(*) AS CLZ_COUNT " +
" FROM CLAZZ " +
" WHERE STATUS=1 " +
" GROUP BY STUDENT_ID " +
")\n" +
"SELECT S.STUDENT_ID, S.FULL_NAME, SC.SUB_COUNT, CC.CLZ_COUNT " +
"FROM STUDENT S " +
" LEFT JOIN SUBJECT_COUNT SC ON S.STUDENT_ID=SC.STUDENT_ID " +
" LEFT JOIN CLAZZ_COUNT CC ON S.STUDENT_ID=CC.STUDENT_ID " +
"ORDER BY SC.SUB_COUNT, CC.CLZ_COUNT").setParameter("START_DATE", startDate).setParameter("END_DATE", endDate).getSingleResult();
您可以将查询添加到实体的@NamedNativeQuery
注释中,然后对于创建查询,您需要使用EntityManager.createNamedQuery
代替EntityManager.createNativeQuery
。这将在编译时看到查询中的错误。
您可以将自然查询结果包装到POJO对象look more info