How do you do a limit query in HQL?

2018-12-31 18:27发布

问题:

In Hibernate 3, is there a way to do the equivalent of the following MySQL limit in HQL?

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

I don\'t want to use setMaxResults if possible. This definitely was possible in the older version of Hibernate/HQL, but it seems to have disappeared.

回答1:

This was posted on the Hibernate forum a few years back when asked about why this worked in Hibernate 2 but not in Hibernate 3:

Limit was never a supported clause in HQL. You are meant to use setMaxResults().

So if it worked in Hibernate 2, it seems that was by coincidence, rather than by design. I think this was because the Hibernate 2 HQL parser would replace the bits of the query that it recognised as HQL, and leave the rest as it was, so you could sneak in some native SQL. Hibernate 3, however, has a proper AST HQL Parser, and it\'s a lot less forgiving.

I think Query.setMaxResults() really is your only option.



回答2:

 // SQL: SELECT * FROM table LIMIT start, maxRows;

Query q = session.createQuery(\"FROM table\");
q.setFirstResult(start);
q.setMaxResults(maxRows);


回答3:

If you don\'t want to use setMaxResults() on the Query object then you could always revert back to using normal SQL.



回答4:

If you don\'t want to use setMaxResults, you can also use Query.scroll instead of list, and fetch the rows you desire. Useful for paging for instance.



回答5:

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

This worked for me without using setmaxResults();

Just provide the max value in the last (in this case 5) without using the keyword limit. :P



回答6:

My observation is that even you have limit in the HQL (hibernate 3.x), it will be either causing parsing error or just ignored. (if you have order by + desc/asc before limit, it will be ignored, if you don\'t have desc/asc before limit, it will cause parsing error)



回答7:

If can manage a limit in this mode

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();
}

This is a really simple code to handle a limit or a list.



回答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());
            }


回答9:

You need to write a native query, refer 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);