【问题标题】:HQL to return the index of an object in an ordered query result?HQL 在有序查询结果中返回对象的索引?
【发布时间】:2009-02-09 14:36:24
【问题描述】:

我可以使用 HQL 来获取 ordered 查询结果的索引吗?

我知道这样做的唯一方法是从数据库中取回所有结果,然后遍历所有结果。

例如,给定:

<hibernate-mapping>
<class name="Dog" table="DOG">

    <id name="id" type="int" column="DOG_id">
        <meta attribute="scope-set">protected</meta>
        <generator class="native"/>
    </id>

    <property name="age" type="int" />

    <property name="name" type="string" />
</class>    
</hibernate-mapping>

那么这些类型的查询:

//determine where dog with id 43 is in the current search results for dogs ordered by age
Query dogQuery = sess.createQuery("select d.id from Dog as d order by d.age");
List<Dog> dogList = dogQuery.list();
int idx = dogList.indexOf( 43 );

或者,通过狗列表进行更精细的搜索:

Query dogQuery = sess.createQuery("select d.id from Dog as d where (d.name='fluffy' OR d.age >= 3) order by d.age");
List<Dog> dogList = dogQuery.list();
int idx = dogList.indexOf( 43 );

这里的缺点是我们将每个 dog.id 加载到内存中。

我需要这个的场景:

  • 将特定查询结果(数千个)显示为一行上的一个点。线和点每分钟左右更新一次。这种可视化可以“实时”更新搜索查询的排名

【问题讨论】:

    标签: hibernate hql


    【解决方案1】:

    使用 List.indexOf() 如果列表特别大,则使列表“超懒”。

    但是为什么需要索引呢?也许你真的不需要(因此你不需要解决这个问题)


    修改后的答案:

    你完全错了。您只需要:

    select count(*) from dog d, dog d1 where d.age d.id


    为什么会这样: 此查询查找与所讨论的狗 (d1) 年龄相同或更小的每只狗,但 不是 d1。 (但实际上并没有归还所有这些狗——因为我们不关心它们)。

    计数会告诉您“在”d1 之前的狗数量。因此,您可以知道 d1 在完整的狗列表中的位置。由于您不需要知道列表中所有狗的位置,因此您不需要检索所有狗。

    【讨论】:

    • 我需要这个的一个场景:如果我需要返回到产品结果的正确页面,并且目录总是在变化。
    • 即使列表非常懒惰,除非我检查每个项目(克服额外懒惰),否则我仍然不知道我要查找的索引是哪个索引。 (如果我正确理解了额外的懒惰)。
    • "extra-lazy" 表示仅根据需要获取列表中的元素。 hibernate.org/hib_docs/v3/reference/en-US/html_single/… 所以 List.indexOf() 应该可以工作,因为支持 PersistantList 应该只生成查询以返回结果。
    • 但是再看你的问题,List 是错误的集合。 Hibernate 存储一个 int 0-to-whatever 作为每个元素的一部分。如果列表中的项目不断更改顺序,那就是很多更新。我会建议 bag 或者 sorted set。
    • 我们坚持一个集合。该查询从该集合返回一个列表。我正在该列表中寻找项目索引。 (顺便说一句,在尝试超级懒惰的过程中)。
    【解决方案2】:

    将整个结果列表加载到内存中,然后使用应用程序逻辑来过滤您需要的内容,这是与数据库交互的错误方式。

    首先使用 SQL WHERE 和 HAVING 子句从数据库中获取您需要的内容

    【讨论】:

      【解决方案3】:

      从这个 HQL 开始(在这种情况下也是有效的 SQL):

      select dog.id as dogId from canines dog order by dog.codename asc
      

      可以稍加修改并插入到有效的 SQL 查询中(仅适用于具有 rownum 列的 Oracle):

      select rn from 
      ( select dogid dogId, rownum rn from canines dog order by dogname asc)
      where dogid=206
      

      很遗憾,这不是有效的 HQL...

      为了使用我的初始 HQL 查询来获取与那个 SQL 查询相同的信息,我计划:

      • 让 hibernate 将我的 HQL 查询生成到 SQL 中,它将用于生成所有结果的列表(希望不要先运行查询)
      • 使用 sessionObj.createSQLQuery 将此休眠生成的 SQL 插入到新的 SQL 查询中。这个新查询看起来就像上面的工作 sql。

      这是一个疯狂的解决方案吗?

      --

      笔记

      SQL to return the rownum of a specific row? (using Oracle db)

      【讨论】:

        【解决方案4】:

        您应该能够使用诸如 Hibernates Criteria 对象之类的东西来仅返回查询的一小部分。

        我猜你正在尝试实现分页。

        Criteria criteria=session.createCriteria(Item.class);
        criteria.addOrder(Order.asc("name"));
        criteria.setFirstResult(100);
        criteria.setMaxResults(50);
        List pageResults=criteria.list();
        

        以上代码摘自: http://forum.springframework.org/archive/index.php/t-9658.html

        这也适用于始终更新的目录,因为您应该在每个页面请求上进行此查询。

        【讨论】:

        • 我想知道结果的 哪个 页面有我正在寻找的项目,以便我可以正确使用 setFirstResult。
        • 如果您知道要查找的项目,则只需显示该项目。然后显示指向该项目来自的目录的链接。当然,我不知道您的所有要求,但是尝试转到目录的特定页面以显示您知道 id 的项目有点奇怪。
        • 谢谢,hooknc。这是另一个用例(没有分页):将特定查询结果(数千个)显示为一行上的一个点。线和点每分钟左右更新一次。这种可视化提供了搜索查询排名的“实时”更新。
        【解决方案5】:

        在 java 列表中,您可以调用 indexOf(Object)。

        有关 API,请参阅 List

        【讨论】:

        • 谢谢,但我希望避免将整个列表从数据库加载到内存中......让我澄清一下我的问题。
        猜你喜欢
        • 2015-01-20
        • 2011-09-15
        • 2017-12-19
        • 1970-01-01
        • 2016-11-16
        • 2013-08-13
        • 1970-01-01
        • 1970-01-01
        • 2013-11-11
        相关资源
        最近更新 更多