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執行時會直接執行編譯後的語句。
- 六、參考:
歡迎關注本站公眾號,獲取更多信息