【问题标题】:How to retrieve items with hibernate clustered by to_days + COUNT(*)如何检索由 to_days + COUNT(*) 聚类的休眠项目
【发布时间】:2013-05-10 10:21:18
【问题描述】:

我对再次休眠还是很陌生,所以这可能是一个愚蠢的问题;)。

没有 to_days,但按时间戳聚集,它的工作原理如下:

    CriteriaQuery<Tuple> query = criteriaBuilder.createQuery(Tuple.class);
    Root<Session> sessionRoot = query.from(Session.class);
    query.multiselect(
                sessionRoot.get("time").alias("time"),
                criteriaBuilder.count(sessionRoot).alias("count")
            );
    query.groupBy(sessionRoot.get("time"));
    List<Tuple> results = this.executeQuery(query);

所以我收到了:

time|count
13721938721|1
13721938722|2
13721938723|3
13721938724|4
13721938725|2
13721938726|1
13721938727|4

但这都是每毫秒的会话计数,但我需要按天而不是按时间戳聚集的那些:因此我在普通 mysql 中使用 to_days。

在 mysql 中我执行这个查询:

SELECT TO_DAYS(`time`) AS `days`, COUNT(*) as `count` FROM sessions WHERE 1 GROUP BY `days`

这给了我:

days|count
777594|123
777595|60
777596|61
777597|74

但我还不知道:如何在 hibernate 中使用 javax.persistence.criteria.CriteriaBuilder 和 CriteriaQuery 实现相同的功能?

【问题讨论】:

  • 你应该看看hibernate生成的查询,确保它是按别名而不是列名分组的。
  • 另外,我在标准构建器中看不到任何天数的转换。
  • @Ziul 这是对的,因为我不知道如何制作这个;)。如何将其转换为天数?

标签: mysql hibernate date


【解决方案1】:

我不知道如何使用标准构建器,但我知道如何在 Hibernate 4 标准 api 中:

query.setProjection(
    Projections.sqlProjection(
        "TO_DAYS(time) as days",
        new String[]{"days"},
        new Type[]{StandardBasicTypes.INTEGER}
    )
);

sqlProjection 允许您转换或转换数据类型,但要小心,使用投影只会检索您在其中指定的文件,结果列表将如下所示:

 List<Object[]> results = this.executeQuery(query);

但是您可以使用结果转换器使 hibernate 与属性进行别名匹配:

query.setResultTransformer(new AliasToBeanResultTransformer(Session.class));

列表像往常一样出现:

List<Session.class> results = this.executeQuery(query);

抱歉,我无法提供标准构建器解决方案,但我希望这能让您走上正轨。

【讨论】:

  • 谢谢齐尔。它让我走上了正轨!!我现在自己回答了这个问题。希望我没有错过任何东西。
【解决方案2】:

经过一番调查,事实证明,HQL 不支持 TO_DAYS。由于我想让 MySQL 和其他数据库成为可能,这是我的最终解决方案:

Query q = entityManager.createQuery("SELECT concat(day(e.time), '-', month(e.time), '-', year(e.time)) AS days, COUNT(*) FROM Event e GROUP BY concat(day(e.time), '-', month(e.time), '-', year(e.time))");

结果是:

3-5-2012|980
4-5-2012|200
10-6-2012|123
12-6-2012|144
13-11-2012|500

所以之后我在 java 中将所有丑陋的日期字符串转换为适当的毫秒数,并获得我需要的数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多