La prise en charge des critères Hibernate fournit une méthode setMaxResults()
pour limiter les résultats renvoyés par la base de données.
Je ne trouve aucune réponse à cela dans leur documentation - comment cela est-il implémenté? Est-ce qu'il interroge l'ensemble des résultats et ne renvoie que le numéro de la demande? Ou est-ce vraiment limiter la requête à la fin de la base de données (pensez au mot clé LIMIT comme dans mySql).
Ceci est important car si une requête pouvait potentiellement renvoyer beaucoup de résultats, j'ai vraiment besoin de savoir si la fonction setMaxResults()
interrogera toujours toutes les lignes de la base de données (ce qui serait mauvais).
Aussi - si cela limite réellement le nombre de lignes sur la fin de la base de données, comment réalise-t-il cette cross-db (puisque je ne pense pas que chaque rdbms supporte une fonctionnalité LIMIT comme celle de mySql).
Hibernate demande à la base de données de limiter les résultats renvoyés par la requête. Pour ce faire, il utilise le dialecte, qui utilise le mécanisme spécifique à la base de données pour le faire (donc, pour SQL Server, il utilisera quelque chose comme "select top n * from table", Oracle le fera "select * from table où rownum <n ", MySQL fera" sélectionnez * dans la limite de table n "etc). Ensuite, il retourne simplement ce que la base de données renvoie.
La classe org.hibernate.dialect.Dialect
contient une méthode appelée supportsLimit()
. Si les sous-classes de dialecte surchargent cette méthode, ils peuvent implémenter la gestion des limites de lignes de manière native pour leur base de données. Vous pouvez voir d'où ce code est appelé dans la classe org.hibernate.loader.Loader qui a une méthode intitulée prepareQueryStatement
, il suffit de rechercher le mot limit .
Toutefois, si le dialecte ne prend pas en charge cette fonctionnalité, il existe une vérification stricte de l'itérateur ResultSet
qui garantit que les résultats des objets Java (entités) cesseront d'être construits lorsque la limite sera atteinte. Ce code se trouve également dans Loader
.
J'utilise à la fois Hibernate et Hibernate Search et, sans regarder l'implémentation sous-jacente, je peux vous dire qu'ils ne renvoient certainement pas tous les résultats. J'ai implémenté la même requête en renvoyant tous les résultats, puis je l'ai modifié pour définir le premier résultat et le maximum de résultats (pour implémenter la pagination) et les gains de performances ont été énormes.
Ils utilisent probablement pour cela un langage SQL spécifique au dialecte, par exemple. LIMIT dans MySQL, ROWNUM dans Oracle. Votre responsable d'entité est conscient du dialecte que vous utilisez, c'est donc simple.
Enfin, si vous voulez vraiment vérifier ce que SQL Hibernate produit pour cette requête, il suffit de définir la propriété "show_sql" sur true lorsque vous créez votre gestionnaire/fabrique d’entités et que tout le code SQL exécuté sur la console est extrait.
HQL ne prend pas en charge une limitation dans une requête comme dans SQL, mais uniquement la setMaxResults()
que vous avez également trouvée.
Pour savoir s'il transforme la setMaxResults()
en une requête LIMIT, vous pouvez activer votre journalisation SQL.
Je sais que la question est un peu vieille. Mais oui, setMaxResults()
limite réellement le nombre de lignes à la fin de la base de données.
Si vous regardez vraiment dans votre sortie Hibernate SQL, vous trouverez que l’instruction SQL suivante a été ajoutée à votre requête.
limit ?