Quels sont les avantages et les inconvénients de l'utilisation des critères ou HQL ? L'API Criteria est une belle façon orientée objet d'exprimer des requêtes dans Hibernate, mais parfois les requêtes Criteria sont plus difficiles à comprendre / construire que HQL.
Quand utilisez-vous les critères et quand HQL? Que préférez-vous dans quels cas d'utilisation? Ou est-ce juste une question de goût?
Réponses:
Je préfère principalement les requêtes de critères pour les requêtes dynamiques. Par exemple, il est beaucoup plus facile d'ajouter de l'ordre de façon dynamique ou de laisser certaines parties (par exemple des restrictions) en fonction de certains paramètres.
D'un autre côté, j'utilise HQL pour des requêtes statiques et complexes, car il est beaucoup plus facile de comprendre / lire HQL. De plus, HQL est un peu plus puissant, je pense, par exemple pour différents types de jointures.
la source
Il existe une différence en termes de performances entre HQL et critèresQuery, chaque fois que vous lancez une requête à l'aide de critèresQuery, il crée un nouvel alias pour le nom de table qui ne se reflète pas dans le dernier cache interrogé pour n'importe quelle base de données. Cela entraîne une surcharge de compilation du SQL généré, ce qui prend plus de temps à exécuter.
Concernant les stratégies de récupération [http://www.hibernate.org/315.html]
la source
Les critères sont une API orientée objet, tandis que HQL signifie la concaténation de chaînes. Cela signifie que tous les avantages de l'orientation objet s'appliquent:
Étant donné que HQL ressemble beaucoup à SQL (que la plupart des développeurs connaissent déjà très bien), ces arguments "ne pas avoir à se rappeler" n'ont pas autant de poids. Si HQL était plus différent, alors ce serait plus important.
la source
J'utilise généralement des critères lorsque je ne sais pas quelles entrées seront utilisées sur quels éléments de données. Comme sur un formulaire de recherche où l'utilisateur peut saisir de 1 à 50 éléments et je ne sais pas ce qu'il recherchera. Il est très facile d'ajouter simplement plus de critères au fur et à mesure que je vérifie ce que recherche l'utilisateur. Je pense qu'il serait un peu plus gênant de mettre une requête HQL dans cette circonstance. HQL est génial quand je sais exactement ce que je veux.
la source
HQL est beaucoup plus facile à lire, plus facile à déboguer à l'aide d'outils comme le plugin Eclipse Hibernate et plus facile à enregistrer. Les requêtes de critères sont meilleures pour créer des requêtes dynamiques où une grande partie du comportement est déterminée lors de l'exécution. Si vous ne connaissez pas SQL, je pourrais comprendre à l'aide de requêtes de critères, mais dans l'ensemble, je préfère HQL si je sais ce que je veux à l'avance.
la source
Les critères sont le seul moyen de spécifier des recherches de clés naturelles qui tirent parti de l'optimisation spéciale dans le cache de requêtes de deuxième niveau. HQL n'a aucun moyen de spécifier le conseil nécessaire.
Vous pouvez trouver plus d'informations ici:
la source
Criteria Api est l'un des bons concepts d'Hibernate. selon moi, ce sont les quelques points par lesquels nous pouvons faire la différence entre HQL et Criteria Api
la source
limit offset:rows
En hql vous pouvez éviter l'injection sql en utilisantsetParameter
Pour utiliser le meilleur des deux mondes, l'expressivité et la concision de HQL et la nature dynamique de Criteria envisagent d'utiliser Querydsl .
Querydsl prend en charge JPA / Hibernate, JDO, SQL et Collections.
Je suis le responsable de Querydsl, donc cette réponse est biaisée.
la source
Pour moi, les critères sont assez faciles à comprendre et à effectuer des requêtes dynamiques. Mais le défaut que je dis jusqu'à présent est qu'il charge toutes les relations multiples, etc. car nous n'avons que trois types de FetchModes, c'est-à-dire Select, Proxy et Default et dans tous ces cas, il charge plusieurs (je peux me tromper si l'aide moi :))
Le deuxième problème avec les critères est qu'il charge un objet complet, c'est-à-dire que si je veux simplement charger EmpName d'un employé, il ne fournira pas cet objet, il proposera un objet employé complet et je peux obtenir EmpName à cause de cela, cela fonctionne vraiment mal dans rapports . où en tant que HQL, il suffit de charger (ne charge pas l'association / les relations) ce que vous voulez, donc augmentez les performances plusieurs fois.
Une caractéristique de Criteria est qu'il protégera u de SQL Injection en raison de sa génération de requêtes dynamiques où, comme dans HQL, vos requêtes sont soit fixes, soit paramétrées et ne sont donc pas à l'abri de SQL Injection.
De plus, si vous écrivez HQL dans vos fichiers aspx.cs, vous êtes étroitement couplé avec ur DAL.
Dans l'ensemble, ma conclusion est qu'il y a des endroits où vous ne pouvez pas vivre sans rapports HQL, alors utilisez-les autrement. Les critères sont plus faciles à gérer.
la source
API de critères
L'API de critères est mieux adaptée aux requêtes générées dynamiquement. Ainsi, si vous souhaitez ajouter des filtres de clause WHERE, des clauses JOIN ou modifier la clause ORDER BY ou les colonnes de projection, l'API Criteria peut vous aider à générer la requête de manière dynamique d'une manière qui empêche également les attaques par injection SQL .
D'un autre côté, les requêtes Criteria sont moins expressives et peuvent même conduire à des requêtes SQL très compliquées et inefficaces, comme expliqué dans cet article .
JPQL et HQL
JPQL est le langage de requête d'entité standard JPA tandis que HQL étend JPQL et ajoute des fonctionnalités spécifiques à Hibernate.
JPQL et HQL sont très expressifs et ressemblent à SQL. Contrairement à l'API Criteria, JPQL et HQL facilitent la prédiction de la requête SQL sous-jacente générée par le fournisseur JPA. Il est également beaucoup plus facile de revoir ses requêtes HQL que celles de critères.
Il convient de noter que la sélection d'entités avec JPQL ou l'API Criteria est logique si vous devez les modifier. Sinon, une projection DTO est un bien meilleur choix.
Conclusion
Si vous n'avez pas besoin de varier la structure de requête d'entité, utilisez JPQL ou HQL. Si vous devez modifier les critères de filtrage ou de tri ou modifier la projection, utilisez l'API Criteria.
Cependant, ce n'est pas parce que vous utilisez JPA ou Hibernate que vous ne devez pas utiliser SQL natif. Les requêtes SQL sont très utiles et JPQL et l'API Criteria ne remplacent pas SQL. Consultez cet article pour plus de détails sur ce sujet.
la source
Pour moi, la plus grande victoire sur les critères est l'exemple d'API, où vous pouvez passer un objet et hibernate construira une requête basée sur ces propriétés d'objet.
En plus de cela, l'API critères a ses caprices (je pense que l'équipe hibernate retravaille l'api), comme:
J'ai tendance à utiliser HQL lorsque je veux des requêtes similaires à sql (supprimer des utilisateurs où status = 'bloqué'), et j'ai tendance à utiliser des critères lorsque je ne veux pas utiliser l'ajout de chaîne.
Un autre avantage de HQL est que vous pouvez définir toutes vos requêtes à l'avance, et même les externaliser dans un fichier.
la source
L'API des critères fournit une fonctionnalité distincte que ni SQL ni HQL ne fournit. c'est à dire. il permet de compiler le temps de vérification d'une requête.
la source
Nous avons utilisé principalement des critères dans notre application au début, mais après son remplacement par HQL en raison de problèmes de performances.
Nous utilisons principalement des requêtes très complexes avec plusieurs jointures, ce qui conduit à plusieurs requêtes dans Criteria mais est très optimisé dans HQL.
Le cas est que nous utilisons seulement plusieurs propriétés sur un objet spécifique et non des objets complets. Avec Criteria, le problème était également la concaténation de chaînes.
Supposons que si vous devez afficher le nom et le prénom de l'utilisateur dans HQL, c'est assez facile,
(name || ' ' || surname)
mais dans Crteria, ce n'est pas possible.Pour surmonter cela, nous avons utilisé ResultTransormers, où il y avait des méthodes où une telle concaténation était implémentée pour le résultat souhaité.
Aujourd'hui, nous utilisons principalement HQL comme ceci:
dans notre cas, les enregistrements renvoyés sont des cartes des propriétés nécessaires.
la source
la source
la source
CriteriaUpdate<T>
etCriteriaDelete<T>
pour référence.Critère requête pour dynamiquement nous pouvons construire une requête basée sur nos entrées .. Dans le cas de la requête Hql est la requête statique une fois que nous construisons, nous ne pouvons pas changer la structure de la requête.
la source
Je ne veux pas frapper un cheval mort ici, mais il est important de mentionner que les requêtes sur les critères sont désormais obsolètes. Utilisez HQL.
la source
Je préfère également les requêtes de critères pour les requêtes dynamiques. Mais je préfère hql pour supprimer les requêtes, par exemple si supprimer tous les enregistrements de la table enfant pour l'ID parent 'xyz', cela est facilement réalisé par HQL, mais pour les critères API, nous devons d'abord déclencher n nombre de requêtes de suppression où n est le nombre d'enfants enregistrements de table.
la source
La plupart des réponses ici sont trompeuses et mentionnent qu'elles
Criteria Queries
sont plus lentes queHQL
, ce qui n'est en fait pas le cas.Si vous approfondissez et effectuez des tests, vous verrez que les requêtes de critères fonctionnent bien mieux que le HQL normal .
Et aussi avec Criteria Query, vous obtenez un contrôle orienté objet qui n'est pas là avec HQL .
Pour plus d'informations, lisez cette réponse ici .
la source
Il y a une autre manière. J'ai fini par créer un analyseur HQL basé sur la syntaxe d'origine hibernate afin qu'il analyse d'abord le HQL, puis il pourrait injecter dynamiquement des paramètres dynamiques ou ajouter automatiquement des filtres communs pour les requêtes HQL. Ça marche super!
la source
Ce message est assez ancien. La plupart des réponses parlent de critères Hibernate, pas de critères JPA. JPA 2.1 a ajouté CriteriaDelete / CriteriaUpdate et EntityGraph qui contrôle exactement ce qu'il faut récupérer. L'API de critères est meilleure puisque Java est OO. C'est pourquoi JPA est créé. Lorsque JPQL est compilé, il sera traduit en arborescence AST (modèle OO) avant d'être traduit en SQL.
la source
HQL peut entraîner des problèmes de sécurité comme l'injection SQL.
la source