web-dev-qa-db-ja.com

(方法)MyBatisとDBに依存しないSQLクエリで「LIKE」を安全に使用できますか?

MyBatis では、パラメーターをSQLに挿入する場所を次のようにマークします。

SELECT * FROM Person WHERE id =#{id}

この構文は、特にSQLインジェクション攻撃を回避するために適切なエスケープなどをアクティブにします。信頼できる入力があり、エスケープをスキップしたい場合は、パラメータをそのまま挿入できます。

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

今、私は安全ではない入力でLIKE検索をしたいので、私がしたいのはこれです:

SELECT * FROM Person WHERE name LIKE#{beginningOfName} || '%'

残念ながらただし、重要なDBサーバー ||連結の構文

MSSQL-'||'の代わりに '+'演算子を使用して標準を破ります。

...

MySQL-再定義することにより、標準をひどく壊します|| ORを意味します。

だから、私はどちらかをすることができました

SELECT * FROM Person WHERE name LIKECONCAT(#{beginningOfName}、 '%')

この場合、MySQLに制限されます。

SELECT * FROM Person WHERE name LIKE '{beginningOfName}%'

自分で入力を消毒する必要があります。

よりエレガントな解決策はありますか?

16
Hanno Fietz

通常、これは、SQLの外部で使用している任意の言語で、渡す前に_%_をパラメーター自体に追加することによって行われます。ただし、どちらの方法でも、検索語句に___または_%_が含まれている可能性がある場合は、エスケープ手順を実行する必要があることに注意してください。背景については、例 この質問 を参照してください。)

一般的に連結の問題を修正するには、MySQLを ANSI sql_mode に入れます。これにより、_||_演算子が適切にサポートされ、文字列リテラルではなくスキーマ名の二重引用符が正しく処理されます。

(それができない場合は、_||_またはCONCAT()のいずれかからステートメントを作成する関数を作成し、違いを抽象化する必要があります。)

11
bobince

bind構文を使用できます

引用 公式ドキュメント

Bind要素を使用すると、OGNL式から変数を作成し、それをコンテキストにバインドできます。例えば:

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

mybatisを使用している場合は、これをsに書き込むことができます

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

バインドがif内に含まれる

<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>
4
JORGE ROMERO

Bindを使用できます。 bind要素を使用すると、式から変数を作成し、それをコンテキストにバインドできます。例えば:

<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>

検索するパラメータがP_NAMEであることを考慮に入れてください。