我在项目中使用 hibernate,并且尝试将现有的 sql 查询从 DaoImplementation 类转换为 hql,
我的sql查询是
JdbcTemplate select = new JdbcTemplate(dataSource);
String sql = "SELECT * FROM (SELECT site_id,rtc,sigplan,cycle_time,health,phase_no,phase_time,active_groups,groupscolour,ip "+
"FROM status_data where rtc>='" + fromDate + "' and rtc<'" + toDate + "' and "+
"site_id=" + SiteId + " order by rtc desc limit "+recordLimit+" )as temp ORDER BY RTC ASC";
我编写了 hql 版本来从 HealthLog 表中获取数据
String hql = " select f from (select h from HealthLog h where rtc>='"+fromDate+"' and rtc <'"+toDate+"' "
+ "and siteId = "+siteId+" order by rtc desc limit "+limit+" ) as f order by rtc asc ";
return super.readListByHql(hql);
但是上面的 hql 抛出以下异常
org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: ( near line 1, column 16 [ select f from (select h from com.traff.hibernate.model.HealthLog as h where rtc>='1974-08-01 14:10:00.0' and rtc <'1974-09-01 23:46:20.6' and siteId = 20 order by rtc desc limit 50000 ) as f order by rtc asc ]
at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:54)
at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:47)
at org.hibernate.hql.internal.ast.ErrorCounter.throwQueryException(ErrorCounter.java:79)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:276)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:180)
at org.hibernate.hql.intern
我也尝试了下面的代码片段,但给了我错误的结果
Criteria criteria = createEntityCriteria();
criteria.add(Restrictions.ge("rtc", fromDate));
criteria.add(Restrictions.lt("rtc", toDate));
criteria.add(Restrictions.eq("siteId", siteId));
criteria.setMaxResults(limit);
criteria.addOrder(Order.asc("rtc"));
criteria2 = criteria;
criteria2.addOrder(Order.desc("rtc"));
return criteria2.list();
实现结果的正确方法是什么?
最佳答案
首先,正如评论中已经提到的,您不能在 HQL 的 FROM 子句中执行子查询。 请参阅:Hibernate Documentation
其次,HQL不支持limit关键字。
通常您会使用 query.setFirstResult(0)
和query.setMaxResults(recordLimit)
查询具有查询接口(interface)类型的方法。但由于您在子查询中使用限制,因此没有办法。
请参阅:How to set a limit to inner query in Hibernate?
一些选项:
- 使用 native SQLQuery
- 因为您仅在外部查询中进行排序。您只能在 Java 中执行内部查询和排序。
选项 2 的示例:
Session session = factory.openSession();
Query query = session
.createQuery("FROM HealthLog "
+ "WHERE rtc >= :rtcL and rtc < :rtcG and siteId = :siteId "
+ "ORDER BY rtc DESC");
query.setParameter("rtcL", fromDate);
query.setParameter("rtcG", toDate);
query.setParameter("siteId", siteId);
query.setFirstResult(0);
query.setMaxResults(recordLimit);
List<HealthLog> res = query.list();
session.close();
Collections.sort(res, new Comparator<HealthLog>() {
public int compare(HealthLog o1, HealthLog o2) {
return o1.getRtc().compareTo(o2.getRtc());
}
});
上面的查询返回包含所有属性的 HealthLogs。如果只想检索特定属性,可以添加 SELECT new HealthLog(siteId,rtc,sigplan,cycle_time,...)
使用 HealthLog
中合适的构造函数到您的查询.
请注意,代码片段可能无法使用,因为我不知道您的模型和属性名称。
关于java - sql 到 hql 抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39306642/