溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

MyBatis中的#{}和${}有什么區別

發布時間:2021-12-07 11:33:36 來源:億速云 閱讀:219 作者:小新 欄目:開發技術
# MyBatis中的#{}和${}有什么區別

## 引言

在MyBatis框架中,`#{}`和`${}`是兩種常見的參數占位符語法,它們在SQL語句中用于動態替換參數值。雖然表面上看功能相似,但底層實現機制、安全性和適用場景存在顯著差異。本文將深入解析兩者的區別,并通過代碼示例幫助開發者正確選擇和使用。

---

## 1. 核心機制對比

### 1.1 `#{}`(預編譯占位符)
- **實現原理**  
  采用預編譯(PreparedStatement)機制,運行時會被替換為`?`占位符,參數值通過JDBC的set方法安全注入。

- **示例代碼**  
  ```xml
  <select id="findUserById" resultType="User">
    SELECT * FROM users WHERE id = #{userId}
  </select>

實際執行SQL:

  SELECT * FROM users WHERE id = ?

1.2 ${}(字符串拼接)

  • 實現原理
    直接進行字符串替換(Statement),參數值按原樣拼接到SQL語句中。

  • 示例代碼

    <select id="findUserByName" resultType="User">
    SELECT * FROM users WHERE name = '${userName}'
    </select>
    

    userName值為"John",最終SQL為:

    SELECT * FROM users WHERE name = 'John'
    

2. 關鍵差異詳解

特性 #{} ${}
SQL注入風險 安全(自動參數化) 高風險(直接拼接)
預編譯支持
參數類型處理 自動類型轉換(如Date→Timestamp) 原樣輸出
動態表名/列名 不支持 支持
性能 通常更優(數據庫可緩存執行計劃) 每次需重新解析SQL

3. 安全風險案例

SQL注入示例

<!-- 危險寫法 -->
<select id="login" resultType="User">
  SELECT * FROM users 
  WHERE username = '${username}' AND password = '${password}'
</select>

攻擊者輸入:

username: admin' --
password: any

最終執行:

SELECT * FROM users WHERE username = 'admin' --' AND password = 'any'

安全解決方案

<!-- 正確寫法 -->
<select id="login" resultType="User">
  SELECT * FROM users 
  WHERE username = #{username} AND password = #{password}
</select>

4. 適用場景指南

推薦使用#{}的情況

  • 所有用戶輸入參數(表單數據、URL參數等)
  • WHERE條件中的值
  • INSERT/UPDATE語句的字段值

謹慎使用${}的場景

  1. 動態表名/列名
    
    <select id="queryByField" resultType="map">
     SELECT * FROM ${tableName} ORDER BY ${columnName}
    </select>
    
  2. SQL函數/特殊語法
    
    <select id="findRecent" resultType="User">
     SELECT * FROM users 
     WHERE create_time > DATE_SUB(NOW(), INTERVAL ${days} DAY)
    </select>
    

5. 進階技巧

混合使用案例

<select id="dynamicQuery" resultType="User">
  SELECT * FROM ${tablePrefix}_users
  WHERE status = #{status}
  <if test="orderBy != null">
    ORDER BY ${orderBy}
  </if>
</select>

類型處理器擴展

通過自定義TypeHandler可增強#{}的處理能力:

@MappedTypes(JSONObject.class)
public class JsonTypeHandler extends BaseTypeHandler<JSONObject> {
  // 實現JSON與數據庫字段的轉換
}

6. 總結

選擇原則 說明
默認使用#{} 保障安全性,預防SQL注入
${}僅用于非值部分 表名、列名等元數據操作
動態SQL優先用OGNL表達式 <if>, <choose>等標簽更安全

正確理解這兩種占位符的區別,能夠幫助開發者在保證系統安全性的同時,靈活應對各種復雜SQL場景。 “`

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女