前の記事では、#{}と$ {}パラメーターの違いと、MyBatisの#と$の差を紹介しました。必要な場合は、参照できます。
$ and#簡単な説明:
#はデータに二重引用符を追加するのと同等であり、$はデータを直接表示するのと同等です。
1。概要
MyBatisでSQLクエリにSQLMAPを使用する場合、パラメーターを動的に渡す必要があることがよくあります。動的SQLは、MyBatisの強力な機能の1つであり、他のORMフレームワークよりも優れている重要な理由です。 SQLステートメントを事前にコンパイルする前に、MyBatisはSQLを動的に解析し、BoundSQLオブジェクトに解析します。これもここで処理されます。動的なSQL解析段階では、#{}と$ {}は異なるパフォーマンスを持ち、#{}はJDBCプレタコンパイルされたステートメントのパラメーターマーカーに解析されます。
#{}はパラメータープレースホルダーに解析されますか? 。 $ {}は単なる純粋な文字列置換であり、動的なSQL解析段階で可変交換が実行されます。
2。バグの説明
フロントエンドパラメーター:
スキップ:0
テイク:10
ルールネーム:A、B、c
ビジネスレイヤー処理:
パッケージSQL;/*** SQLステートメントコンテンツとしてフロントエンドマルチセレクトパラメーターをエスケープする*/パブリッククラスsqlutil {private final static string fany Static String fanyChar_comma = "、"; private final static string tacelchar_semicolon = ";"; " "abc"; system.out.println( "comma separated:" + formatinstr(s1)); system.out.println( "space-separated:" + formatinstr(s2));} private static string formatinstr(string querystr){runter queryinstr(slipt querystr); private string); queryStr){if(null == querystr || "" .equals(querystr.trim()))return null; querystr = querystr.replaceall(sqlutil.replacechar_comma、 "").replaceall(replaceecholon、 "); QueryStr.split( "// s+");} private static string queryinstr(string [] querystrs){if(null == querystrs || 0 == querystrs.length)return null; stringbuffer buf = new Stringbuffer(); buf.append( "、"); buf.append( "'")。append(querystrs [i])。append( "'");} return buf.tostring();}}}を返しますマッパーレイヤー処理:
// ERRER処理<if test = "rulename!= null and rulename!= ''"> and a.rule_name in(#{rulename})<//正しいハンドリング<test = "rulename!= null and rulename!= ''"> and a.rule_name in($ {rulename})</if> if> if> if>ログの説明:
[デバッグ] [2016-08-02 17:42:42.226] [QTP1457334982-157] java.sql.connection- ==>準備:A.id、a.is_valid、a.rule_lable、a.rule_name、a.type、b。 A.gmt_modified、a.ordc_logistics_assign_rules左joing app_user c on C.work_no = a.Modifierおよびc.is_deleted = 'n'、idc_sp_info b bere a.is_deleted = 'n'およびb.is_deleted = 'n'およびa.sp_id = b.id = b.sp_idとa.sp_id = b.sp_id = ASC制限?、? [Debug] [2016-08-02 17:42:42.226] [QTP1457334982-157] Java.sql.PreparedStatement- ==>パラメーター: 'A'、 'B'(string)、0(integer)、10(整数)
結果分析:Mapper層はSQLを事前に拡張し、#のプレースホルダーがありますか? 、しかし、$に直接置き換えられます。
PS:MyBatisをソートするときに動的パラメーターで注文を使用する場合、#の代わりに$を使用することに注意を払う必要があります。
文字列置換
デフォルトでは、#{}形式の構文を使用すると、MyBatisが前処理されたステートメントプロパティを作成し、背景(?など)として安全な値を設定します。これは安全で迅速であり、SQLステートメントに直接変更されない文字列を挿入するだけです。たとえば、注文のように、次のように使用できます。
コードコピーは次のとおりです。
$ {columnName}で注文
ここで、MyBatisは文字列を変更または脱出しません。
重要:ユーザーからのコンテンツ出力を受け入れて、ステートメントの変更されていない文字列に提供することは安全ではありません。これにより、潜在的なSQLインジェクション攻撃につながる可能性があるため、ユーザーがこれらのフィールドに入ることを許可したり、通常はエスケープして自分でチェックすることを許可しないでください。