${}
と #{} は、MyBatis のパラメータを置き換えるために使用されます。どちらもユーザーを置き換えることができます。渡されたパラメータは最終的に MyBatis によって生成される SQL に置き換えられますが、それらの違いは非常に大きいので、次にそれらを見てみましょう。
${} はパラメータを SQL に直接置き換えます,たとえば、次のコード:
<select id="getUserById" resultType="com.example.demo.model.UserInfo"> select * from userinfo where id=${id} </select>
最終的に生成される実行 SQL は次のとおりです:
上の図からわかるように、前のパラメータ ${id} は次のとおりです。特定のパラメータに直接置き換えられます。値は 1 です。 #{} はプレースホルダーと前処理を使用してビジネス を実行します。上記のケースを #{} の形式に変換します。実装コードは次のとおりです:
<select id="getUserById" resultType="com.example.demo.model.UserInfo"> select * from userinfo where id=#{id} </select>
最終的に生成される SQL は次のとおりです。
##1.1 ${}に関する問題パラメータが の場合 パラメータの型が a の場合数値型(セキュリティ問題を考慮しない場合)の場合、${} と #{} の実行効果は同じですが、パラメータの型が文字の場合、${} を使用すると問題が発生します。
次のコードが表示されます:
<select id="getUserByName" resultType="com.example.demo.model.UserInfo"> select * from userinfo where name=${name} </select>
上記のプログラムを実行すると、生成される SQL ステートメントは次のようになります:
これにより、プログラムはエラーを報告します。渡されたパラメーターは文字型であり、SQL 構文では、文字型の場合は値に一重引用符を追加する必要があり、そうでない場合はエラーが発生します。${} は直接置換であり、一重引用符は自動的に追加されないため、実行時にエラーが報告されます。 #{} の使用はプレースホルダ実行前なので問題ありませんが、その実装コードは以下の通りです:
<select id="getUserByName" resultType="com.example.demo.model.UserInfo"> select * from userinfo where name=#{name} </select>
上記のプログラムで最終的に生成される実行SQLは以下の通りです:
##2. さまざまな使用シナリオ
このとき、ソート キーワード desc reverse order (価格の高値から高値 Low) または asc 正のシーケンス (価格の低値から高値)、現時点では
${} Ryan: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:xml;"><select id="getAll" resultType="com.example.demo.model.Goods">
select * from goods order by price ${sort}
</select></pre><div class="contentsignin">ログイン後にコピー</div></div>
ただし、コード内の ${} が #{} に変更されると、 、プログラムの実行中にエラーが報告されます。 #{ } 実装コードは次のとおりです。
<select id="getAll" resultType="com.example.demo.model.Goods">
select * from goods order by price #{sort}
</select>
上記の実行結果から、次のことがわかります。
通常のパラメータを渡す場合は、 #{} メソッドを使用する必要があります。 SQL コマンドまたは SQL キーワードの場合、${ } を使用して SQL 内のパラメータを直接置き換えて実行する必要があります。 3. 異なるセキュリティ
3.1 ${} を使用してユーザー ログインを実装します。
UserMapper.xml の実装コードは次のとおりです。
<select id="login" resultType="com.example.demo.model.UserInfo"> select * from userinfo where name='${name}' and password='${password}' </select>
ユニットテスト コードは次のとおりです。
@Test void login() { UserInfo userInfo = userMapper.login("java", "java"); System.out.println(userInfo); }
上記のコードによって生成される実行 SQL と実行結果は次のとおりです。
結果からわかるように、正しいユーザー名とパスワードが渡されると、データは正常にクエリできます。ただし、
${}を使用すると、正しいパスワードがわからない場合に、SQL インジェクション ステートメントを使用してユーザーの個人情報を取得することもできます。SQL インジェクションの実装コードは次のとおりです。 #
@Test void login() { UserInfo userInfo = userMapper.login("java", "' or 1='1"); System.out.println(userInfo); }
#
从上述结果可以看出,当使用 ${} 时,在不知道正确密码的情况下也能得到用户的私人数据,这就像一个小偷在没有你们家钥匙的情况下,也能轻松的打开你们家大门一样,这是何其恐怖的事情。那使用 #{} 有没有安全问题呢?接下来我们来测试一下。
首先将 UserMapper.xml 中的代码改成以下内容:
<select id="login" resultType="com.example.demo.model.UserInfo"> select * from userinfo where name=#{name} and password=#{password} </select>
接着我们使用上面的 SQL 注入来测试登录功能:
@Test void login() { UserInfo userInfo = userMapper.login("java", "' or 1='1"); System.out.println(userInfo); }
最终生成的 SQL 和执行结果如下:
从上述代码可以看出,使用 SQL 注入是无法攻破 #{} 的“大门”的,所以可以放心使用。
以上がJava の ${} と #{} の違いは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。