先測試,再說結論
userService.selectStudentByClssIds(10000, "'wzh' or 1=1");
List<StudentEntity> selectStudentByClssIds(@Param("stuId") int stuId, @Param("field") String field);
<select id="selectStudentByClssIds" resultMap="StudentResultMap">SELECTstudent_id, name, age, genderFROM students where name = ${field}</select>
控制臺sql執行日志
對比一下,如果是把${field}替換成#{filed}
再玩個更有趣的,如果我們某個sql查詢字段需要通過入參確定,如下
<select id="selectStudentByClssIds" resultMap="StudentResultMap">SELECTstudent_id, #{field}, age, genderFROM students;</select>
我們的入參為name,測試結果如下
也就是說這個sql變成了SELECT student_id, 'wzh', age, gender FROM students;
我們把#{field}替換成${filed}再看一下
<select id="selectStudentByClssIds" resultMap="StudentResultMap">SELECTstudent_id, ${field}, age, genderFROM students;</select>
如下,恢復正常了
綜上
在 MyBatis 中,#{} 和 ${} 是兩種不同的占位符語法,用于處理 SQL 語句中的參數。它們的用途和效果各不相同,不可以混淆
#{} 用于將參數值作為預編譯語句的參數。MyBatis 會將該參數值綁定到 SQL 語句中,并自動轉換為 SQL 對應類型和進行轉義,從而提高安全性,防止 SQL 注入。
${} 用于字符串替換,它直接將傳入的參數值插入到 SQL 語句中。MyBatis 不會對使用 ${} 的參數進行處理或轉義。 使用 ${} 時,參數直接拼接到 SQL 語句中,因此,如果傳入的參數是用戶輸入的值,沒有經過適當的驗證和清理,會導致 SQL 注入風險。當您需要動態生成 SQL 語句的部分,如表名、列名等結構時。此時參數不能是用戶輸入,如,動態指定表名或列名
SELECT * FROM ${tableName} WHERE id = #{id}