web-dev-qa-db-fra.com

Comment faites-vous une requête limite dans HQL?

Dans Hibernate 3, existe-t-il un moyen de faire l'équivalent de la limite MySQL suivante en HQL?

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

Je ne veux pas utiliser setMaxResults si possible. C'était certainement possible dans l'ancienne version de Hibernate/HQL, mais cela semble avoir disparu.

206
stevedbrown

Ceci a été posté sur le forum Hibernate il y a quelques années, lorsqu'on lui a demandé pourquoi cela fonctionnait dans Hibernate 2 mais pas dans Hibernate 3:

La limite était jamais une clause prise en charge en HQL. Vous êtes censé utiliser setMaxResults ().

Donc, si cela a fonctionné dans Hibernate 2, il semble que ce soit par coïncidence, plutôt que par conception. Je pense c'était parce que l'analyseur Hibernate 2 HQL remplaçait les éléments de la requête qu'il reconnaissait sous le nom HQL et laissait le reste tel qu'il était afin que vous puissiez introduire du SQL natif. Hibernate 3, cependant, a un analyseur HQL correct AST, et il est beaucoup moins tolérant.

Je pense que Query.setMaxResults() est vraiment votre seule option.

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

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

Si vous ne souhaitez pas utiliser setMaxResults() sur l'objet Query, vous pouvez toujours revenir à l'utilisation de SQL normal.

16
pjp

Si vous ne souhaitez pas utiliser setMaxResults, vous pouvez également utiliser Query.scroll au lieu de list et extraire les lignes souhaitées. Utile pour la pagination par exemple. 

5
Lluis Martinez

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

Cela a fonctionné pour moi sans utiliser setmaxResults();

Indiquez simplement la valeur maximale dans la dernière (dans ce cas 5) sans utiliser le mot clé limit.: P

3
Dilawar

Mon observation est que même si vous avez une limite dans le HQL (hibernate 3.x), cela causera une erreur d’analyse ou sera simplement ignoré. (si vous avez ordre de + desc/asc avant limite, il sera ignoré, si vous n'avez pas desc/asc avant limite, cela entraînera une erreur d'analyse)

1
Xingsheng

Si peut gérer une limite dans ce 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();
}

C'est un code très simple pour gérer une limite ou une liste. 

1
biancardi
@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);
1
Leena Varshney
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());
            }
0
Deep Chand Jaipur

Vous devez écrire une requête native, référez-vous 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);
0
swatisinghi

Vous pouvez facilement utiliser la pagination pour cela.

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

vous devez passer new PageRequest(0, 1)pour récupérer les enregistrements et depuis la liste, récupérer le premier enregistrement.

0
tk_