获取hql中具有最高成员值的对象?

时间:2010-05-24 19:24:37

标签: java hibernate hql

我对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实例?

感谢您的帮助!

1 个答案:

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