如何将本机查询转换为JPA查询

时间:2016-04-25 11:07:54

标签: sql jpa subquery

假设我有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。或者我能得到相同结果的任何其他解决方案都会很好。 非常感谢你

1 个答案:

答案 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