代码之家  ›  专栏  ›  技术社区  ›  stevedbrown

如何在HQL中执行限制查询?

  •  206
  • stevedbrown  · 技术社区  · 15 年前

    在Hibernate3中,有没有一种方法可以等效于HQL中的以下MySQL限制?

    select * from a_table order by a_table_column desc limit 0, 20;
    

    9 回复  |  直到 4 年前
        1
  •  326
  •   skaffman    13 年前

    This was posted 几年前,在Hibernate论坛上,当被问及为什么在Hibernate 2中有效而在Hibernate 3中无效时:

    极限是 从不 支持的子句 在HQL中。你注定要使用它 setMaxResults()。

    因此,如果它在Hibernate2中工作,那么这似乎是巧合,而不是设计。我

    Query.setMaxResults() 真的是你唯一的选择。

        2
  •  152
  •   Jessu    13 年前
     // SQL: SELECT * FROM table LIMIT start, maxRows;
    
    Query q = session.createQuery("FROM table");
    q.setFirstResult(start);
    q.setMaxResults(maxRows);
    
        3
  •  20
  •   pjp    15 年前

    如果你不想使用 setMaxResults() Query 对象,则始终可以恢复到使用普通SQL。

        4
  •  6
  •   Vlad Mihalcea    3 年前

    setFirstResult setMaxResults Query 方法

    查询 这个 setFirstResult OFFSET ,以及 方法相当于极限:

    List<Post> posts = entityManager
    .createQuery(
        "select p " +
        "from Post p " +
        "order by p.createdOn ")
    .setFirstResult(10)
    .setMaxResults(10)
    .getResultList();
    

    这个 LimitHandler 抽象

    冬眠 利米汉德尔 定义特定于数据库的分页逻辑,如下图所示,Hibernate支持许多特定于数据库的分页选项:

    LimitHandler implementations

    现在,根据您使用的底层关系数据库系统,上面的JPQL查询将使用正确的分页语法。

    MySQL

    SELECT p.id AS id1_0_,
           p.created_on AS created_2_0_,
           p.title AS title3_0_
    FROM post p
    ORDER BY p.created_on
    LIMIT ?, ?
    

    SELECT p.id AS id1_0_,
           p.created_on AS created_2_0_,
           p.title AS title3_0_
    FROM post p
    ORDER BY p.created_on
    LIMIT ?
    OFFSET ?
    

    SQL Server

    SELECT p.id AS id1_0_,
           p.created_on AS created_on2_0_,
           p.title AS title3_0_
    FROM post p
    ORDER BY p.created_on
    OFFSET ? ROWS 
    FETCH NEXT ? ROWS ONLY
    

    神谕

    SELECT *
    FROM (
        SELECT 
            row_.*, rownum rownum_
        FROM (
            SELECT 
                p.id AS id1_0_,
                p.created_on AS created_on2_0_,
                p.title AS title3_0_
            FROM post p
            ORDER BY p.created_on
        ) row_
        WHERE rownum <= ?
    )
    WHERE rownum_ > ?
    

    setFirstResult setMaxResults Hibernate可以为任何受支持的关系数据库生成特定于数据库的分页语法。

    而且,您不仅限于JPQL查询。你可以使用 setFirstResult setMaxResults 本机SQL查询的方法七。

    使用本机SQL查询时,不必硬编码特定于数据库的分页。Hibernate可以将其添加到查询中。

    因此,如果您在PostgreSQL上执行此SQL查询:

    List<Tuple> posts = entityManager
    .createNativeQuery(
        "SELECT " +
        "   p.id AS id, " +
        "   p.title AS title " +
        "from post p " +
        "ORDER BY p.created_on", Tuple.class)
    .setFirstResult(10)
    .setMaxResults(10)
    .getResultList();
    

    Hibernate将对其进行如下转换:

    SELECT p.id AS id,
           p.title AS title
    FROM post p
    ORDER BY p.created_on
    LIMIT ?
    OFFSET ?
    

    很酷,对吧?

    超越基于SQL的分页

    当您可以为筛选和排序条件编制索引时,分页是很好的。如果分页要求意味着动态筛选,那么使用反向索引解决方案(如ElasticSearch)是一种更好的方法。

        5
  •  5
  •   Lluis Martinez    14 年前

        6
  •  4
  •   tk_ Collin Price    5 年前

    您可以轻松地为此使用分页。

        @QueryHints({ @QueryHint(name = "org.hibernate.cacheable", value = "true") })
        @Query("select * from a_table order by a_table_column desc")
        List<String> getStringValue(Pageable pageable);
    

    你必须通过考试 new PageRequest(0, 1) 取录 从列表中获取第一条记录。

        7
  •  2
  •   swatisinghi    6 年前

    您需要编写本机查询,请参阅 this .

    @Query(value =
        "SELECT * FROM user_metric UM WHERE UM.user_id = :userId AND UM.metric_id = :metricId LIMIT :limit", nativeQuery = true)
    List<UserMetricValue> findTopNByUserIdAndMetricId(
        @Param("userId") String userId, @Param("metricId") Long metricId,
        @Param("limit") int limit);
    
        8
  •  1
  •   Casey    13 年前

    String hql = "select userName from AccountInfo order by points desc 5";

    这对我来说很有效,没有使用 setmaxResults();

    只需提供最后一个(在本例中为5)中的最大值,而不使用关键字 limit :P

        9
  •  0
  •   Xingsheng    14 年前

    我的观察是,即使您在HQL(Hibernate3.x)中有限制,它也会导致解析错误或被忽略。(如果您在限制之前有order by+desc/asc,它将被忽略,如果您在限制之前没有desc/asc,它将导致解析错误)

        10
  •  0
  •   alexandrum    9 年前

    如果您可以在此模式下管理限额

    public List<ExampleModel> listExampleModel() {
        return listExampleModel(null, null);
    }
    
    public List<ExampleModel> listExampleModel(Integer first, Integer count) {
        Query tmp = getSession().createQuery("from ExampleModel");
    
        if (first != null)
            tmp.setFirstResult(first);
        if (count != null)
            tmp.setMaxResults(count);
    
        return (List<ExampleModel>)tmp.list();
    }
    

        11
  •  0
  •   Deep Chand Jaipur    8 年前
    Criteria criteria=curdSession.createCriteria(DTOCLASS.class).addOrder(Order.desc("feild_name"));
                    criteria.setMaxResults(3);
                    List<DTOCLASS> users = (List<DTOCLASS>) criteria.list();
    for (DTOCLASS user : users) {
                    System.out.println(user.getStart());
                }
    
        12
  •  0
  •   ButchMonkey Rojin Gharooni    4 年前

    您可以使用下面的查询

    NativeQuery<Object[]> query = session.createNativeQuery(select * from employee limit ?)
    query.setparameter(1,1);
    
        13
  •  0
  •   Hari Krishna    4 年前

    下面的代码段用于使用HQL执行限制查询。

    Query query = session.createQuery("....");
    query.setFirstResult(startPosition);
    query.setMaxResults(maxRows);
    

    link .

        14
  •  -2
  •   Andreas    5 年前
    @Query(nativeQuery = true,
           value = "select from otp u where u.email =:email order by u.dateTime desc limit 1")
    public List<otp> findOtp(@Param("email") String email);
    
    推荐文章