ホームページ  >  記事  >  Java  >  Java の ${} と #{} の違いは何ですか?

Java の ${} と #{} の違いは何ですか?

王林
王林転載
2023-05-01 13:52:063870ブラウズ

    まえがき

    ${} と #{} は、MyBatis のパラメータを置き換えるために使用されます。どちらもユーザーを置き換えることができます。渡されたパラメータは最終的に MyBatis によって生成される SQL に置き換えられますが、それらの違いは非常に大きいので、次にそれらを見てみましょう。

    1. さまざまな関数

    ${} はパラメータを SQL に直接置き換えます,たとえば、次のコード:

    <select id="getUserById" resultType="com.example.demo.model.UserInfo">
        select * from userinfo where id=${id}
    </select>

    最終的に生成される実行 SQL は次のとおりです:

    Java の ${} と #{} の違いは何ですか?

    上の図からわかるように、前のパラメータ ${id} は次のとおりです。特定のパラメータに直接置き換えられます。値は 1 です。 #{} はプレースホルダーと前処理を使用してビジネス を実行します。上記のケースを #{} の形式に変換します。実装コードは次のとおりです:

    <select id="getUserById" resultType="com.example.demo.model.UserInfo">
        select * from userinfo where id=#{id}
    </select>

    最終的に生成される SQL は次のとおりです。

    Java の ${} と #{} の違いは何ですか?

    ##1.1 ${}に関する問題

    パラメータが の場合 パラメータの型が a の場合数値型(セキュリティ問題を考慮しない場合)の場合、

    ${} と #{} の実行効果は同じですが、パラメータの型が文字の場合、${} を使用すると問題が発生します。 次のコードが表示されます:

    <select id="getUserByName" resultType="com.example.demo.model.UserInfo">
        select * from userinfo where name=${name}
    </select>

    上記のプログラムを実行すると、生成される SQL ステートメントは次のようになります:

    Java の ${} と #{} の違いは何ですか?

    これにより、プログラムはエラーを報告します。渡されたパラメーターは文字型であり、SQL 構文では、文字型の場合は値に一重引用符を追加する必要があり、そうでない場合はエラーが発生します。

    ${} は直接置換であり、一重引用符は自動的に追加されないため、実行時にエラーが報告されます。 #{} の使用はプレースホルダ実行前なので問題ありませんが、その実装コードは以下の通りです:

    <select id="getUserByName" resultType="com.example.demo.model.UserInfo">
        select * from userinfo where name=#{name}
    </select>

    上記のプログラムで最終的に生成される実行SQLは以下の通りです:

    Java の ${} と #{} の違いは何ですか?##2. さまざまな使用シナリオ

    {} メソッドを使用するとあらゆる種類のパラメータを処理できますが、渡されたパラメータが SQL コマンドまたは SQL の場合は、キーワード #{} を使用すると問題が発生します。たとえば、価格の高値から安値 (逆順)、または安値から高値 (正順) に基づいてクエリを実行する場合、

    このとき、ソート キーワード desc reverse order (価格の高値から高値 Low) または asc 正のシーケンス (価格の低値から高値)、現時点では

    ${}

    Ryan: <pre class="brush:xml;">&lt;select id=&quot;getAll&quot; resultType=&quot;com.example.demo.model.Goods&quot;&gt; select * from goods order by price ${sort} &lt;/select&gt;</pre>

    の実装コードを使用します。上記のコードは実行 SQL を生成し、実行結果は次のとおりです。

    Java の ${} と #{} の違いは何ですか?

    ただし、コード内の ${} が #{} に変更されると、 、プログラムの実行中にエラーが報告されます。 #{ } 実装コードは次のとおりです。

    <select id="getAll" resultType="com.example.demo.model.Goods">
      select * from goods order by price #{sort}
    </select>

    上記のコードによって生成される実行 SQL と実行結果は次のとおりです。

    Java の ${} と #{} の違いは何ですか?

    上記の実行結果から、次のことがわかります。

    通常のパラメータを渡す場合は、 #{} メソッドを使用する必要があります。 SQL コマンドまたは SQL キーワードの場合、${ } を使用して SQL 内のパラメータを直接置き換えて実行する必要があります。 3. 異なるセキュリティ

    ##${}

    と #{} 主な違いはセキュリティの側面に反映されています。セキュリティ上の問題、つまり SQL インジェクションの問題が発生します。ただし、#{} を使用しても前処理が行われるため、セキュリティ上の問題は発生しません。以下のログイン関数を通じて 2 つの違いを観察してみましょう。

    3.1 ${} を使用してユーザー ログインを実装します。 UserMapper.xml の実装コードは次のとおりです。

    <select id="login" resultType="com.example.demo.model.UserInfo">
      select * from userinfo where name=&#39;${name}&#39; and password=&#39;${password}&#39;
    </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", "&#39; or 1=&#39;1");
        System.out.println(userInfo);
    }
    Java の ${} と #{} の違いは何ですか?

    上記コードにより生成される実行SQLと実行結果は以下のとおりです。

    #

     从上述结果可以看出,当使用 ${} 时,在不知道正确密码的情况下也能得到用户的私人数据,这就像一个小偷在没有你们家钥匙的情况下,也能轻松的打开你们家大门一样,这是何其恐怖的事情。那使用 #{} 有没有安全问题呢?接下来我们来测试一下。

    3.2 使用 #{} 实现用户登录

    首先将 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", "&#39; or 1=&#39;1");
        System.out.println(userInfo);
    }

    最终生成的 SQL 和执行结果如下: 

    Java の ${} と #{} の違いは何ですか?

     从上述代码可以看出,使用 SQL 注入是无法攻破 #{} 的“大门”的,所以可以放心使用。

    以上がJava の ${} と #{} の違いは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    声明:
    この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。