ibatis 中#和 $ 符號的區別

  • 一、數據類型匹配
    • #:會進行預編譯,並且進行類型匹配(自動肯定數據類型);
    • $:不進行數據類型匹配。
  • 二、實現方式:
    •  # 用於變量替換(先生成一個佔位符,而後替換)
      • select * from users  where name = #name#
      • 等效於
      • prepareStement=stmt.createPrepareStement("select * from users where name = ?")
      • prepareStement.setString (1,' 張三 ');
    • $ 的做用其實是字符串拼接()
      • select * from users where name= $name$
      • 等效於
      • StringBuffer sb = newStringBuffer(256);
      • sb.append("select * from userswhere name=").append(name);
      • sb.toString();
  • 三、使用場景
    • -#主要用於變量的傳遞。# 是用 prepareStement,提高效率。#方式通常用於傳入添加 / 修改的值或查詢 / 刪除的 where 條件
    • $ 只是簡單的字符拼接而已,對於非變量部分, 只能使用 $。$ 方式通常用於傳入數據庫對象。例如傳入表名,select  * from  $tableName$  對於不一樣的表執行統一的查詢
  • 四、爲何會出現SQL注入?
    • $沒有預編譯,只是字符串替換,因此語句可能被注入,傳給數據庫時是多條語句;
    • 而#會先預編譯,驗證SQL語句,預防了問題的出現。
  • 五、關於預編譯的理解:
    • 爲何須要預編譯
      • JDBC 中使用對象 PreparedStatement 來抽象預編譯語句,使用預編譯
      • 預編譯階段能夠優化 sql 的執行。
        • 預編譯以後的 sql 多數狀況下能夠直接執行,DBMS 不須要再次編譯,越複雜的 sql,編譯的複雜度將越大,預編譯階段能夠合併屢次操做爲一個操做。
      • 預編譯語句對象能夠重複利用。
        • 把一個 sql 預編譯後產生的 PreparedStatement 對象緩存下來,下次對於同一個 sql,能夠直接使用這個緩存的 PreparedState 對象。
      • mybatis 默認狀況下,將對全部的 sql 進行預編譯。
    • 參考附錄:
      • 說明下,就是$時傳給DBMS的時一個Statement對象,該對象會被DBMS先編譯後執行;
      • 而#時傳給DBMS的時一個PrepareStatement 對象,該對象會直接傳給DBMS進行編譯,DBMS執行時會直接執行編譯後的語句。
  • 六、參考:
相關文章
相關標籤/搜索