我对hql还是一个新手,我对我正在编写的查询的聚合函数和效率有疑问。
假设我在hibernate中映射了这个类(为了简洁省略了getters / setters / constructors / etc.):
public class Foo
{
private int i;
private String s;
private float f;
}
我想做一个hql查询来获取具有最高i值并指定s&的Foo实例。 f值。我目前的解决方案是:
List<Foo> fooList = (List<Foo>)session.createQuery(
"from Foo as foo where foo.s = :str and foo.f = :val order by foo.i desc").
setParameter("str", <stringgoeshere>).setParameter("val", <floatgoeshere>).
list();
return fooList.get(0);
如果我理解正确,这个方法会有N+1 selects problem(虽然只要我从列表中抓取第一个结果,N希望是1,但仍然是)。我假设有一些方法可以使用uniqueResult(),但我不太明白聚合函数在这种情况下如何工作。我能够找到“max()”的唯一例子是where子句或返回值。
如何编写此查询以在单个选择中执行此操作并获取具有最高i的Foo实例?
感谢您的帮助!
答案 0 :(得分:2)
如果我理解正确,这个方法会有N + 1选择问题
我看不出你的查询如何导致n + 1选择。 Hibernate没有理由迭代第一个查询的结果并在此处执行后续查询。
我认为有一些方法可以使用uniqueResult(),但我不太明白聚合函数在这种情况下是如何工作的。
如果您想要检索单个结果,不检索整个表格确实很明智。首先,查询会更有效率,其次,你不会浪费内存(甚至可能使会话爆炸)。如果您的表包含一百万条记录怎么办?
如何编写此查询以在单个选择中执行此操作并获取具有最高i的Foo实例?
如上所述,仅检索所需记录,使用setMaxResults(1)
来限制结果数量(这将根据您的数据库生成正确的SQL顺序):
Foo foo = (Foo) session.createQuery(
"from Foo as foo where foo.s = :str and foo.f = :val order by foo.i desc")
.setParameter("str", <stringgoeshere>).setParameter("val", <floatgoeshere>)
.setMaxResults(1)
.uniqueResult();
return foo;