首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

MyBatis 多參數傳遞技巧:#{ } 與 ${ } 的關鍵差異與實戰應用

     編輯:Java 相關知識

前言

MyBatis 作為一款優秀的持久層框架,極大地簡化了 JDBC 代碼與參數手動設置的繁瑣工作。在實際開發中,如何靈活且安全地傳遞多個參數至 SQL 語句,是每位開發者必須掌握的核心技能。本文將深入解析 #{ } 與 ${ } 兩種參數佔位符的本質差異,並通過實例演示動態排序、多條件查詢等常見場景的最佳實踐。

核心概念:#{ } vs ${ }

#{ } —— 預編譯佔位符(推薦)

#{ } 採用預編譯機制,MyBatis 會將其解析為 JDBC 的參數佔位符 ?,由數據庫驅動進行類型安全的參數綁定。這能有效防止 SQL 注入,並自動處理字符串轉義、日期格式等類型轉換。

// XML 映射示例
SELECT * FROM users WHERE username = #{username} AND status = #{status}

若傳入 username = "admin' OR '1'='1",最終執行的 SQL 為:

SELECT * FROM users WHERE username = ? AND status = ?
-- 參數綁定:["admin' OR '1'='1", 1]

數據庫會將整個字符串視為用戶名查詢,而非執行惡意邏輯。

${ } —— 字符串直接替換(慎用)

${ } 進行簡單的字符串拼接,將變量值直接嵌入 SQL 文本。這雖允許動態指定表名、列名或排序字段,但極易引發 SQL 注入漏洞,嚴禁用於用戶輸入的業務參數。

// 僅適用於可信的動態列名/表名
SELECT * FROM ${tableName} ORDER BY ${columnName} ${order}

實戰場景:動態多參數排序

需求:前端傳遞排序字段 sortField 與排序方向 sortOrder,實現通用列表排序。

<select id="queryList" resultType="map">
  SELECT * FROM t_order
  <where>
    <if test="status != null"> status = #{status} </if>
  </where>
  <if test="sortField != null and sortOrder != null">
    ORDER BY ${sortField} ${sortOrder}
  </if>
</select>

安全加固建議:在 Service 層對 sortField 進行白名單校驗,僅允許預期的列名(如 create_time, amount),杜絕注入風險。

多參數傳遞的三種主流方式

1. @Param 註解(單參數/少量參數)

public List<Order> findOrders(@Param("userId") Long userId, @Param("status") Integer status);

XML 中直接使用 #{userId}, #{status}。

2. Map 集合(參數數量不固定)

Map<String, Object> params = new HashMap<>();
params.put("userId", 1001);
params.put("statusList", Arrays.asList(1,2,3));
params.put("startDate", "2023-01-01");

3. POJO/DTO 封裝(推薦:類型安全、易維護)

public class OrderQueryDTO {
    private Long userId;
    private List<Integer> statusList;
    private String startDate;
    private String sortField;
    private String sortOrder;
    // getter/setter
}

總結

  • 業務參數值:堅決使用 #{ },享受預編譯帶來的安全與性能。
  • 動態 SQL 結構(表名、列名、排序關鍵字):不得已使用 ${ } 時,務必在 Java 端實施嚴格白名單校驗。
  • 複雜查詢:優先封裝 DTO 對象,配合 <where>, <trim>, <foreach> 等動態標籤,構建清晰可維護的映射文件。

掌握參數傳遞的本質與邊界,是編寫高質量 MyBatis 代碼的基石。願本文能助你避開坑洼,寫出更安全、優雅的持久層代碼。

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