動態 SQL 是 mybatis 的強大特性之一,也是它優於其餘 ORM 框架的一個重要緣由。mybatis 在對 sql 語句進行預編譯以前,會對 sql 進行動態解析,解析爲一個 BoundSql 對象,也sql
是在此處對動態 SQL 進行處理的。在動態 SQL 解析階段, #{ } 和 ${ } 會有不一樣的表現:mybatis
1.,$和#均可以獲取對象中的屬性值框架
2.#能夠防止sql注入.由於#在解析時,先把sql中使用#的地方變成?,而後經過預編譯設置參數值。code
例如以下SQL:對象
SELECT * FROM user WHERE name = #{name}
#{} 在動態解析的時候, 會解析成一個參數標記符。就是解析以後的語句是:字符串
SELECT * FROM user WHERE name = ?
那麼咱們使用 ${}的時候:編譯
select * from user where name = ${name};
當name="'xxx'"時,${}在動態解析的時候,會將咱們傳入的參數當作String字符串填充到咱們的語句中,就會變成下面的語句:class
select * from user where name = 'xxx';
預編譯以前的 SQL 語句已經不包含佔位符(?)了,徹底已是常量數據了select
基於上面的示例,$會致使sql注入,舉例以下:sql注入
#假如 name = "123' OR 'x' = 'x"; #SQL則變爲 SELECT * FROM user WHERE name = '123' OR 'x' = 'x'
總結下,
在使用#時,mybais會先將之解析爲佔位符(?),而後使用預編譯設置參數,可預防注入。
在使用$時,mybatis會直接使用未轉義的值進行替換。