web-dev-qa-db-fra.com

(Comment) puis-je utiliser "LIKE" dans les requêtes SQL avec MyBatis en toute sécurité et indépendamment de la base de données?

Dans MyBatis , vous marquez les endroits où les paramètres doivent être insérés dans votre code SQL comme ceci:

SELECT * FROM Personne WHERE id = # {id}

Cette syntaxe active les échappements appropriés, entre autres, pour éviter les attaques par injection SQL. Si vous avez une entrée de confiance et que vous souhaitez ignorer l'échappement, vous pouvez insérer les paramètres tels quels:

SELECT * FROM {nomTable} WHERE id = # {id}

Maintenant, je veux faire une recherche LIKE sur une entrée non sécurisée, alors voici ce que je veux faire:

SELECT * FROM Person WHERE nom LIKE # {nomDébut} || '%'

Malheureusement toutefois, les serveurs de base de données importants ne prennent pas en charge la syntaxe || pour la concaténation :

MSSQL - Brise la norme en utilisant l'opérateur '+' au lieu de '||'.

...

MySQL - Passe mal la norme en redéfinissant || pour signifier OU.

Donc, je pourrais faire soit

SELECT * FROM Personne WHERE nom LIKE CONCAT (# {nomDébut}, '%')

et se limiter à, dans ce cas, MySQL, ou je pourrais le faire

SELECT * FROM Personne WHERE nom LIKE '{beginOfName}%'

et aurait à assainir l'entrée moi-même.

Y a-t-il une solution plus élégante?

13
Hanno Fietz

Cela se fait généralement en ajoutant le % au paramètre lui-même avant de le transmettre, dans la langue utilisée en dehors de SQL. Cependant, notez que dans les deux cas, vous devrez peut-être encore effectuer une étape d'échappement si votre terme de recherche peut contenir _ ou %. Voir par exemple cette question pour le fond.)

Pour résoudre le problème de concaténation en général, placez MySQL dans ANSI sql_mode et vous obtiendrez un support approprié pour l'opérateur ||, ainsi qu'un traitement correct des guillemets doubles pour les noms de schéma plutôt que des chaînes de caractères.

(Si vous ne pouvez pas faire cela, vous devrez créer une fonction pour construire l'instruction à partir de || ou de CONCAT(), en résumant la différence.)

10
bobince

Vous pouvez utiliser bind syntax

Citations Documentation officielle

L'élément bind vous permet de créer une variable à partir d'une expression OGNL Et de la lier au contexte. Par exemple:

<select id="selectBlogsLike" resultType="Blog">
  <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
  SELECT * FROM BLOG
  WHERE title LIKE #{pattern}
</select>
9
Bartosz Bilicki

la liaison comprend à l'intérieur du si

<select id="select" parameterType="Java.util.Map" resultType="ViajeDTO">

SELECT A.ID_VIAJE ID, A.NOMBRE, A.DESCRIPCION, A.FINICIO, A.FFIN, A.LOGO, A.URL, 
        A.ID_CLIENTE IDCLIENTE, B.NOMBRE CLIENTE
FROM VIAJE A
INNER JOIN CLIENTE B ON (A.ID_CLIENTE = B.ID_CLIENTE)
WHERE A.ESTATUS = 1 

<if test="P_NOMBRE != null">
    <bind name="pattern" value="'%' + P_NOMBRE + '%'" />
      AND A.NOMBRE LIKE #{pattern}
</if>
</select>
3
JORGE ROMERO

si vous utilisez mybatis, vous pouvez écrire ceci pour

SELECT(" * ");
FROM(" student ");
WHERE(" ten LIKE '%' #{ten} '%' ");
1
Trang NT

Nous pouvons utiliser Bind . L'élément bind vous permet de créer une variable à partir d'une expression et de la lier au contexte. Par exemple:

<select id="select" parameterType="Java.util.Map" resultType="ViajeDTO">

    <bind name="pattern" value="'%' + P_NOMBRE + '%'" />

    SELECT A.ID_VIAJE ID, A.NOMBRE, A.DESCRIPCION, A.FINICIO, A.FFIN, A.LOGO, A.URL, 
            A.ID_CLIENTE IDCLIENTE, B.NOMBRE CLIENTE
    FROM VIAJE A
    INNER JOIN CLIENTE B ON (A.ID_CLIENTE = B.ID_CLIENTE)
    WHERE A.ESTATUS = 1 

    <if test="P_NOMBRE != null">
        AND A.NOMBRE LIKE #{pattern}
    </if>
</select>

En prenant en compte que le paramètre à rechercher est P_NAME.