Dynamique requête HQL à l'aide de requêtes hql expressions plutôt que des Critères?
Je suis en train d'écrire une partie dynamique requête HQL sans avoir recours à l'API des Critères pour diverses raisons. Je voulais savoir si il existe un moyen facile de court-circuit où restriction à l'aide de HQLs expressions. Pour exemple, voici l'original de la requête qui fonctionne très bien:
SELECT customer
FROM Customer as customer
INNER JOIN customer.profile as profile
WHERE profile.status IN :statusCodes
AND profile.orgId IN :orgIds
StatusCodes est une liste de Chaînes et orgIds est une liste d'Entiers. Cependant, l'un des deux est facultatif et ne doit pas limiter si la valeur null est passé à la place d'une collection. J'ai essayé d'accomplir cette manière:
SELECT customer
FROM Customer as customer
INNER JOIN customer.profile as profile
WHERE (:statusCodes IS NULL OR profile.status IN :statusCodes)
AND (:orgIds IS NULL OR profile.orgId IN :orgIds)
Cela ne fonctionnait pas, malheureusement, mais est-il une autre approche qui pourrait fonctionner, soit avec l'aide de différentes expressions ou de passage dans les valeurs par défaut?
EDIT: Juste pour être clair, je suis à la recherche d'une façon d'utiliser une NamedQuery, pas dynamiquement la construction de la requête d'une quelconque manière.
SOLUTION: j'ai utilisé le supplément de paramètres de requête pour l'accomplir. J'ai créé deux méthodes d'aide:
private void setRequiredParameter(TypedQuery<?> query, String name, Object value) {
query.setParameter(name, value);
}
private void setOptionalParameter(TypedQuery<?> query, String name, Object value) {
query.setParameter(name, value);
query.setParameter(name + "Optional", value == null ? 1 : 0);
}
Et la requête comme ceci:
SELECT customer
FROM Customer as customer
INNER JOIN customer.profile as profile
WHERE (:statusCodesOptional = 1 OR profile.status IN :statusCodes)
AND (:orgIdsOptional = 1 OR profile.orgId IN :orgIds)
OriginalL'auteur ant-depalma | 2012-05-17
Vous devez vous connecter pour publier un commentaire.
Si vous devez absolument éviter de requêtes dynamiques, vous pouvez le faire au détriment de deux autres paramètres:
Dans votre code Java, vous serait alors de faire quelque chose comme:
Vous devez vous assurer que les tableaux sont de longueur égale à zéro plutôt que de
null
ou d'alimentation supplémentaire, si des contrôles pour gérernull
scénario.Tout ce que dit, HQL est vraiment mieux pour bien définie (par exemple, statique) des requêtes. Vous pouvez contourner les paramètres de la dynamique, vous ne serez pas capable de travailler autour de la dynamique de tri.
Il n'y a pas - à- pas pour les listes. Hibernate du processeur de requêtes a faire de la magie derrière les scènes à l'appui de listes (plus précisément, de compter le nombre d'éléments et de générer le nombre de paramètres positionnels en résultant SQL) ainsi passer dans <code>null,</code> n'est pas une option.
Qu'en injection SQL possibilité?
OriginalL'auteur ChssPly76
Ma suggestion est de mettre tous les paramètres d'une carte et de construire la requête dynamique, après la construction du bâtiment avant l'exécution de définir tous les paramètres requis par la requête en prenant les valeurs de la carte:
Bien sûr, certaines améliorations sont nécessaires, par exemple, jeter l'exception lorsque des paramètres n'est pas défini, l'utilisation tapé paramètre si la complexité est plus grande que quelques paramètres simples et ainsi de suite.
Il n'y a aucune chance pour l'injection sql dans ce cas, il est traité comme un paramètre et en tant que tel, il a son contenu s'est échappé.
Il est clair maintenant, merci.
OriginalL'auteur Francisco Spaeth
Vous devrez générer votre requête dynamiquement:
Bien sûr, vous devez également définir les paramètres de la requête uniquement si elles ne sont pas nulles.
Alors, autant que je sache, vous aurez besoin de 4 requêtes différentes: une pour chaque combinaison possible (null, null, notnull null, null-notnull, notnull-notnull). Vous avez juste à espérer que vous n'aurez pas besoin d'un troisième paramètre. Notez que je ne vois vraiment pas comment une modification de la statique HQL pour SQL dans un fichier xml est beaucoup plus facile que de changer la dynamique HQL dynamique SQL dans le fichier Java.
L'avantage vient du fait que l'application n'a pas besoin de savoir si un nom de requête hql ou sql. Ils peuvent tout simplement être échangé dans un fichier xml par un dba même. Et je suis à la recherche de l'utilisation OU de conditions pour éviter d'avoir plusieurs requêtes.
OriginalL'auteur JB Nizet