あなたは本当に$#{}のMyBatisのと{}は何を知っていますか?アプリケーション・シナリオを理解するかどうか?

転送します。https://www.cnblogs.com/mytzq/p/9321526.html

動的SQLは、MyBatisのの主な特徴の一つです。渡されたマッパーXMLで定義されたパラメータの後、MyBatisのは、動的にクエリの前に解決されます。

MyBatisの2つのサポート動的SQL構文を提供します:#{}、$ {}。

t_userユーザ名= '$ {ユーザー名}' から選択*;

選択* t_userから場所名=#{ユーザー名}。

ユーザ名パラメータ受け渡しが一致して、両方の実装の結果は同じであるが、動的SQL構文解析段階における2つのハンドルは同じではありません。

1、#{}

これは、パラメーター・マーカー、プレースホルダでパラメータセクションをJDBCプリペアドステートメントに解決(準備書)?代わりに。動的に解決します。

t_userユーザー名から選択* =?;

渡された引数は必須検査と保安検査のPreparedStatementメソッドを渡し、最後に渡された正当な文字列としてします。

2、$ {}

アリスに渡されたパラメータは、最終処理結果が次のようにしている場合にのみ、単純な文字列置換を行うこのように、それは、変数置換の動的SQLの構文解析段階になります。

t_userユーザ名= 'アリスから選択*;

このような従来のプリコンパイルされたSQLステートメントが既に変数が含まれていない、$ {}従って置換変数動的SQL構文解析ステージの段階ことがわかります。

3、#{}、{} $二つの方法の比較

1)SQLインジェクションを防ぐためです

前}#{SQLインジェクションを防止することができる; $ {}後、またはそれ以上の異なるアプローチが、見ることができ、注入されたプリコンパイルされ、リスク、次の例の前に置換されています。

入ってくるユーザー名は、SQLに解決するために処理した後「または」1 = 1、その後、直接置換文字列$は{}の場合:

t_userから選択*どこ名= A」または '1 = 1';

この場合、すべてのユーザーデータがチェックアウトされるので、SQLインジェクションに属します。

#{}場合は、動的な解像度とプリコンパイルされたSQLの後に、単一引用符は、その後、最終的に解決される\「SQLとしてエスケープされます:

これは、任意のデータを見つけることができません//効果的にSQLインジェクションを防ぐため、;ユーザ名=「\ 『または\』 1 = 1」はどこt_userから選択*

いくつかのビジネスシナリオが頻繁にファジークエリを使用し、その処理のように、ある、次のアプローチをお勧めします。

#ユーザー名#のようなt_user.username

Javaコード:

(もし!StringUtil.isEmpty(this.username)){

table.setUsername( "%" + this.username + "%")。

}

それとも、データベース接続処理機能を使用することがあります:

t_userから選択* U CONCATのようなユーザー名( '%'、#ユーザー名#、 '%')

注:上記のようなので、同じ定数を交換する必要のソートフィールド、テーブル名、カラム名、順として、特定のシナリオができるだけ$ {}、に見出すことができます。#{}場合は、次のようにテーブル名が、次のようになります。

#{テーブル名} SELECT * FROM - >テーブル名のパラメータ渡しをt_user --->「t_user」からの選択に後処理*、そのようなテーブルであり、誤差は、そう同じトークンによって順序であろう。

2)パフォーマンスの考慮事項

プリコンパイルされた文オブジェクトをプリコンパイルされ、キャッシュされた後、SQL PreparedStatementオブジェクトを生成するために再利用できるので、同じSQLの次は、直接キャッシュされたPreparedStatementオブジェクトを使用することができ、すべてのSQL用にコンパイル済みのデフォルトを、MyBatisの、この場合、#{}は処理性能が相対的に高いです。

要約:

{#}が} {#を使用することが可能な場合に使用でき

$ {}を使用して変数としてソートフィールドによってテーブル、オーダー。

おすすめ

転載: www.cnblogs.com/l3306/p/11465961.html