動態 SQL 是 mybatis 的強大特性之一,也是它優於其他 ORM 框架的一個重要原因。mybatis 在對 sql 語句進行預編譯之前,會對 sql 進行動態解析,解析為一個 BoundSql 物件,也是在此處對動態 SQL 進行處理的。在動態 SQL 解析階段, #{ } 和 ${ } 會有不同的表現:#{ } 解析為一個 JDBC 預編譯語句(prepared statement)的引數標記符。例如,sqlMap 中如下的 sql 語句select * from user where name = #{name};解析為:select * from user where name = ?;一個 #{ } 被解析為一個引數佔位符 ? 。而,${ } 僅僅為一個純碎的 string 替換,在動態 SQL 解析階段將會進行變數替換例如,sqlMap 中如下的 sqlselect * from user where name = "${name}";當我們傳遞的引數為 "ruhua" 時,上述 sql 的解析為:select * from user where name = "ruhua";預編譯之前的 SQL 語句已經不包含變數 name 了。綜上所得, ${ } 的變數的替換階段是在動態 SQL 解析階段,而 #{ }的變數的替換是在 DBMS 中
動態 SQL 是 mybatis 的強大特性之一,也是它優於其他 ORM 框架的一個重要原因。mybatis 在對 sql 語句進行預編譯之前,會對 sql 進行動態解析,解析為一個 BoundSql 物件,也是在此處對動態 SQL 進行處理的。在動態 SQL 解析階段, #{ } 和 ${ } 會有不同的表現:#{ } 解析為一個 JDBC 預編譯語句(prepared statement)的引數標記符。例如,sqlMap 中如下的 sql 語句select * from user where name = #{name};解析為:select * from user where name = ?;一個 #{ } 被解析為一個引數佔位符 ? 。而,${ } 僅僅為一個純碎的 string 替換,在動態 SQL 解析階段將會進行變數替換例如,sqlMap 中如下的 sqlselect * from user where name = "${name}";當我們傳遞的引數為 "ruhua" 時,上述 sql 的解析為:select * from user where name = "ruhua";預編譯之前的 SQL 語句已經不包含變數 name 了。綜上所得, ${ } 的變數的替換階段是在動態 SQL 解析階段,而 #{ }的變數的替換是在 DBMS 中