首先我們看看mybatis本身的說明:
String Substitution By default, using the #{} syntax will cause MyBatis to generate PreparedStatement properties and set the values safely against the PreparedStatement parameters (e.g. ?). While this is safer, faster and almost always preferred, sometimes you just want to directly inject a string unmodified into the SQL Statement. For example, for ORDER BY, you might use something like this: ORDER BY ${columnName} Here MyBatis won't modify or escape the string. NOTE It's not safe to accept input from a user and supply it to a statement unmodified in this way. This leads to potential SQL Injection attacks and therefore you should either disallow user input in these fields, or always perform your own escapes and checks.
從上文可以看出:
1. 使用#{}格式的語法在mybatis中使用Preparement語句來安全的設置值,執行sql類似下面的:
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1,id);
這樣做的好處是:更安全,更迅速,通常也是首選做法。
2. 不過有時你只是想直接在 SQL 語句中插入一個不改變的字符串。比如,像 ORDER BY,你可以這樣來使用:
ORDER BY ${columnName}
此時MyBatis 不會修改或轉義字符串。
這種方式類似於:
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(sql);
這種方式的缺點是: 以這種方式接受從用戶輸出的內容並提供給語句中不變的字符串是不安全的,會導致潛在的 SQL 注入攻擊,因此要么不允許用戶輸入這些字段,要么自行轉義並檢驗。
小結:
Mybatis本身是基於JDBC封裝的。
#{para}是預編譯處理(PreparedStatement)范疇的。
${para}是字符串替換。
Mybatis在處理#時,會調用PreparedStatement的set系列方法來賦值;處理$時,就是把${para}替換成變量的值。
使用#{para}可以有效的防止SQL注入,提高系統安全性。
參見[文檔](mybatis – MyBatis 3)
http://www.mybatis.org/mybatis-3/sqlmap-xml.html#String_Substitution