à l'aide d'un ParameterExpression par rapport à une variable en JPA Critères d'API
Lors de l'utilisation de la JPA API criteria, quel est l'avantage de l'utilisation d'un ParameterExpression sur une variable directement? E. g. quand je veux rechercher un client par son nom dans une variable de type String, je pourrais écrire quelque chose comme
private List<Customer> findCustomer(String name) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Customer> criteriaQuery = cb.createQuery(Customer.class);
Root<Customer> customer = criteriaQuery.from(Customer.class);
criteriaQuery.select(customer).where(cb.equal(customer.get("name"), name));
return em.createQuery(criteriaQuery).getResultList();
}
Avec des paramètres, cela devient:
private List<Customer> findCustomerWithParam(String name) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Customer> criteriaQuery = cb.createQuery(Customer.class);
Root<Customer> customer = criteriaQuery.from(Customer.class);
ParameterExpression<String> nameParameter = cb.parameter(String.class, "name");
criteriaQuery.select(customer).where(cb.equal(customer.get("name"), nameParameter));
return em.createQuery(criteriaQuery).setParameter("name", name).getResultList();
}
De concision, je préfère la première méthode, en particulier lorsque la requête est plus longue avec des paramètres optionnels. Quels sont les inconvénients de l'utilisation de paramètres comme ceci, comme l'injection SQL?
Je ne peux pas parler pour JPA en général, mais j'ai trouvé que OpenJPA en interne convertit un des Critères de requête JPQL, ce qui peut être imprimé à l'aide de OpenJPA de fonctionnalités spécifiques (voir la section openjpa.apache.org/builds/2.1.1/apache-openjpa/docs/...). La première requête se traduit par "SELECT c from Client c OÙ c.name = "test " Client". Cela signifie qu'il n'utilisez PAS un paramètre donc, si cela devient de plus amples traduit de SQL correspondant de l'instruction préparée à ne PAS utiliser un paramètre. La seconde version se traduit par la JPQL "SELECT c from Client c OÙ c.nom = :nom de", donc je vais utiliser des paramètres.
Après quelques essais, j'ai trouvé que l'écriture de la même requête JPQL et en utilisant le nom de "' OU 'x'='x" injecte JPQL. Lors de l'utilisation de l'API criteria, à la génération de JPQL que OpenJPA journaux semble exactement le même. Mais la réelle SQL qui est connecté par OpenJPA puis utilise une instruction préparée avec un paramètre de valeur "' OU 'x'='x" au lieu de " dans la JPQL cas. Cela signifie que l'injection SQL ne fonctionne pas ici! Malheureusement, je n'ai aucune idée de quelle est la fiabilité de ce qui est. Il semble que cette une fonctionnalité non documentée.
Astuce: j'ai juste donné querydsl.com de l'essayer et c'est la syntaxe est beaucoup plus concis et lisible. Il semble que pour se prémunir contre les injections sql en utilisant les paramètres par défaut.
C'est, si vous n'utilisez pas de paramètres, l'injection SQL est possible?
Après quelques essais, j'ai trouvé que l'écriture de la même requête JPQL et en utilisant le nom de "' OU 'x'='x" injecte JPQL. Lors de l'utilisation de l'API criteria, à la génération de JPQL que OpenJPA journaux semble exactement le même. Mais la réelle SQL qui est connecté par OpenJPA puis utilise une instruction préparée avec un paramètre de valeur "' OU 'x'='x" au lieu de " dans la JPQL cas. Cela signifie que l'injection SQL ne fonctionne pas ici! Malheureusement, je n'ai aucune idée de quelle est la fiabilité de ce qui est. Il semble que cette une fonctionnalité non documentée.
Astuce: j'ai juste donné querydsl.com de l'essayer et c'est la syntaxe est beaucoup plus concis et lisible. Il semble que pour se prémunir contre les injections sql en utilisant les paramètres par défaut.
C'est, si vous n'utilisez pas de paramètres, l'injection SQL est possible?
OriginalL'auteur Henno Vermeulen | 2013-05-08
Vous devez vous connecter pour publier un commentaire.
Lors de l'utilisation d'un paramètre, probablement (en fonction de la JPA mise en œuvre, la banque de données en cours d'utilisation, et le pilote JDBC) SQL sera optimisé pour un JDBC paramètre donc, si vous exécutez la même chose avec une autre valeur du paramètre que l'on utilise le même JDBC déclaration.
Injection SQL est toujours vers le bas pour le développeur que pour qu'ils valident certains l'entrée d'utilisateur qui est utilisé en tant que paramètre.
OriginalL'auteur DataNucleus
vous pouvez utiliser ParameterExpression comme ceci:
supposons que vous avez des filtre d'entrée, un exemple pourrait être celui-ci:
commençons:
tout d'abord créer criteriaQuery et criteriaBuilder et de la racine
1) inizialize un predicateList(utilisation de la clause where) et un paramList(à utiliser pour les param)
2 )vérifiez si l'entrée est nulle et de créer predicateList et param
3) de créer la clause where
4) jeu de param valeur
oui, il sera possible
OriginalL'auteur Taioli Francesco