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}%'
自分で入力を消毒する必要があります。
よりエレガントな解決策はありますか?
通常、これは、SQLの外部で使用している任意の言語で、渡す前に_%
_をパラメーター自体に追加することによって行われます。ただし、どちらの方法でも、検索語句に__
_または_%
_が含まれている可能性がある場合は、エスケープ手順を実行する必要があることに注意してください。背景については、例 この質問 を参照してください。)
一般的に連結の問題を修正するには、MySQLを ANSI sql_mode に入れます。これにより、_||
_演算子が適切にサポートされ、文字列リテラルではなくスキーマ名の二重引用符が正しく処理されます。
(それができない場合は、_||
_またはCONCAT()
のいずれかからステートメントを作成する関数を作成し、違いを抽象化する必要があります。)
bind構文を使用できます
引用 公式ドキュメント
Bind要素を使用すると、OGNL式から変数を作成し、それをコンテキストにバインドできます。例えば:
<select id="selectBlogsLike" resultType="Blog">
<bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
SELECT * FROM BLOG
WHERE title LIKE #{pattern}
</select>
mybatisを使用している場合は、これをsに書き込むことができます
SELECT(" * ");
FROM(" student ");
WHERE(" ten LIKE '%' #{ten} '%' ");
バインドが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>
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であることを考慮に入れてください。