SQL 映射中使用 #stuid# 查詢無結果 (返回空列表),改用 $stuid$ 正常。參數類型為 parameterClass="java.util.Map"。
| 語法 | 機制 | 適用場景 | 安全性 |
|---|---|---|---|
#param# | 預編譯參數佔位符 (PreparedStatement) 生成 WHERE id = ?,JDBC 驅動綁定值 | **所有數據值** (WHERE 條件、INSERT 值、UPDATE 值等) | ✅ 防 SQL 注入,類型安全 |
$param$ | 字符串直接替換 (簡單文本替換) 生成 WHERE id = 'value',SQL 解析器視為字面量 | **動態 SQL 結構** (表名、列名、排序字段、IN 列表等) | ❌ 存在注入風險,需自行驗證/轉義 |
原映射配置:
問題點:
stuid 作為鍵,Map 中必須包含 key="stuid" 的條目。"stuid",值為 String/Integer,**應使用 #stuid#**,iBATIS 會自動處理類型轉換和引號。$stuid$ 能工作是因為字符串替換後 SQL 變為 ... student stuid = '123',語法正確但**不安全**。#stuid# 返回空列表,可能原因:
select ... from student stuid = ... 缺少 WHERE 關鍵字!
Map params = new HashMap<>();
params.put("stuid", "2021001"); // 或 Integer,iBATIS 自動處理
List list = sqlMapClient.queryForList("getProd", params);
iBATIS 2.x 使用 #param# 和 $param$。
MyBatis 3.x 統一使用 #{param} (預編譯) 和 ${param} (字符串替換),語義相同但語法不同。遷移時注意替換。
**結論**:加上 WHERE 關鍵字,改用 #stuid#,確保 Map key 名稱完全匹配,即可安全正確查詢。