java hibernate 5使用CriteriaBuilder和CriteriaSelect进行subselect查询

时间:2017-08-29 11:40:45

标签: hibernate jpa dao jpa-criteria

我有一个使用Hibernate的dropwizard应用程序,并希望使用Hibernate 5的CriteriaQuery在DAO(DataAccessObject)中实现一个函数。 更确切地说,我想查询一个表格,其中的对象都配备了一个“id”'列和' user_id'专栏(它是一个PostgreSQL数据库,表中有更多字段,但另一个不重要)。

我想计算每个用户对该表中对象的平均数量,所以如果该表名为table_a,我想用Java' s / Hibernates CriteriaQuery编写以下查询:

    SELECT avg(counts) FROM
        (SELECT user_id, COUNT(id) as counts FROM table_a GROUP BY user_id) AS foo

我尝试调查this documentationthis one,但我找不到关于做这种子查询的任何参考。

我的DAO方法如下所示:

    public double avgCountPerUser() {
        CriteriaBuilder criteriaBuilder = this.currentSession().getCriteriaBuilder();
        CriteriaQuery<Tuple> criteriaQuery = criteriaBuilder.createQuery(Tuple.class);
        Root<TableA> tableARoot = criteriaQuery.from(TableA.class);

        criteriaQuery
            .multiselect(tableARoot.get("user_id"),criteriaBuilder.count(tableARoot.get("id")))
            .groupBy(tableARoot.get("user_id"))
            .orderBy(criteriaBuilder.desc(criteriaBuilder.count(tableARoot.get("id"))));
        List<Tuple> tuples= currentSession().createQuery(criteriaQuery).getResultList();
        double result = 0;
        for (Tuple tuple : tuples) {
            result += (Integer) tuple.get(1);
        }
        return tuples.size() == 0 ? 0 : result / tuples.size();
    }

你能帮我解决一下如何正确地做到这一点吗?并且不需要将所有结果都拉到Java-Objects,然后以低效率计算它?

1 个答案:

答案 0 :(得分:0)

HQL中的子查询只能出现在select或where子句中。

https://docs.jboss.org/hibernate/stable/core.old/reference/en/html/queryhql-subqueries.html

如果没有办法创建一个hql查询,那么你应该创建一个本机查询,并尝试不使用某些dbms中的特定sintax。