首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

iBATIS 參數傳遞:#參數# vs $參數$ 的區別與使用場景

     編輯:程式設計綜合問答

現象

SQL 映射中使用 #stuid# 查詢無結果 (返回空列表),改用 $stuid$ 正常。參數類型為 parameterClass="java.util.Map"。

核心區別

語法機制適用場景安全性
#param#預編譯參數佔位符 (PreparedStatement)
生成 WHERE id = ?,JDBC 驅動綁定值
**所有數據值** (WHERE 條件、INSERT 值、UPDATE 值等)✅ 防 SQL 注入,類型安全
$param$字符串直接替換 (簡單文本替換)
生成 WHERE id = 'value',SQL 解析器視為字面量
**動態 SQL 結構** (表名、列名、排序字段、IN 列表等)❌ 存在注入風險,需自行驗證/轉義

問題根因分析

原映射配置:



問題點:

  1. parameterClass="java.util.Map" 但 SQL 中直接用 stuid 作為鍵,Map 中必須包含 key="stuid" 的條目。
  2. 若 Map 中 key 為 "stuid",值為 String/Integer,**應使用 #stuid#**,iBATIS 會自動處理類型轉換和引號。
  3. 使用 $stuid$ 能工作是因為字符串替換後 SQL 變為 ... student stuid = '123',語法正確但**不安全**。
  4. #stuid# 返回空列表,可能原因:
    • Map 中 key 名稱不匹配 (如 "stuId" vs "stuid" 大小寫)。
    • 值類型不匹配 (數據庫字段 VARCHAR,傳入 Integer 導致隱式轉換失敗)。
    • SQL 語法錯誤:select ... from student stuid = ... 缺少 WHERE 關鍵字!

修正後的映射文件





Java 調用代碼


Map params = new HashMap<>();
params.put("stuid", "2021001"); // 或 Integer,iBATIS 自動處理
List list = sqlMapClient.queryForList("getProd", params);

最佳實踐原則

  1. 默認用 #參數#:95% 場景 (值傳遞) 都應用預編譯參數。
  2. 只在必須時用 $參數$:動態表名、列名、ORDER BY 字段、IN 列表展開 (需自行拼接字符串)。
  3. 使用 $參數$ 時必須驗證輸入:白名單校驗、轉義單引號、長度限制。
  4. 檢查 SQL 語法:缺少 WHERE 是導致「不報錯但無結果」的常見原因。

iBATIS / MyBatis 版本提示

iBATIS 2.x 使用 #param# 和 $param$。
MyBatis 3.x 統一使用 #{param} (預編譯) 和 ${param} (字符串替換),語義相同但語法不同。遷移時注意替換。

**結論**:加上 WHERE 關鍵字,改用 #stuid#,確保 Map key 名稱完全匹配,即可安全正確查詢。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved