#{}Mapper XML 中:
<select id="findByStatus" resultType="User">
SELECT * FROM user WHERE status = "" -- 錯誤:雙引號或空字串
</select>
控制台報錯:SQL 語法錯誤、參數綁定失敗。
status = '1'、name = 'admin'。#{paramName}:status = #{statusId},MyBatis 會生成 ? 佔位符並設定 PreparedStatement 參數,防 SQL 注入、自動處理型別轉換。${paramName} 是字串直接替換(如 ORDER BY ${col}),**極度危險**,僅用於不可參數化的 SQL 片段(表名、欄位名、排序方向),且必須嚴格白名單驗證。<!-- 固定值查詢 -->
<select id="findActiveUsers" resultType="User">
SELECT * FROM user WHERE status = '1' AND deleted = '0'
</select>
<!-- 動態參數查詢 -->
<select id="findByStatus" resultType="User">
SELECT * FROM user WHERE status = #{statusId}
</select>
<!-- 多條件動態 SQL -->
<select id="searchUsers" resultType="User">
SELECT * FROM user
<where>
<if test="name != null and name != ''">
AND name LIKE CONCAT('%', #{name}, '%')
</if>
<if test="status != null">
AND status = #{status}
</if>
</where>
ORDER BY create_time DESC
</select>
| 寫法 | 結果 | 適用場景 |
|---|---|---|
status = '1' | 正確 | 固定字串/數值字面量 |
status = "1" | 錯誤(MySQL 模式下雙引號為識別符) | — |
status = #{status} | 正確 | 動態參數(預處理語句) |
status = ${status} | 危險(字串拼接,注入風險) | 僅用於表名/欄位名/排序 |
status = '' | 語法合法但邏輯錯(查空字串) | — |
#{}**,除非確定需要動態 SQL 結構(表名、欄位名)。'1', 100),別用 #{} 傳常數(增加參數綁定開銷)。log4j.logger.org.apache.ibatis=DEBUG),觀察生成的 PreparedStatement 與參數值。<where>, <if>, <trim> 構建動態條件,避免手工拼接 AND/OR 導致語法錯誤。總結: Mapper XML 中,**固定值用單引號 'val',變數用 #{var}**。雙引號、空字串、${} 濫用是新手最常見的 SQL 語法/注入 Bug 來源。