mybatis xml 文件中處理參數引號,避免 sql 注入與解析錯誤
在使用 MyBatis 時,XML 文件中的 SQL 參數處理,尤其包含特殊字符(如引號)時,容易引發 SQL 注入或解析錯誤。本文將通過一個案例,講解如何在 MyBatis XML 文件中安全地處理參數引號。
問題:
使用 MyBatis 查詢 tb_goods 表,條件是 fulldiscountreductionid 字段(存儲 json 數組)包含特定值。數據庫直接執行 SQL 語句正常,但在 MyBatis XML 文件中卻出錯。這是因為 XML 和 SQL 對引號的處理方式不同,導致參數傳遞錯誤。
錯誤的 XML 代碼片段:
<select id="selectGoods" resultType="com.example.Goods"> select * from tb_goods <where> <if test="fulldiscountreductionid != null"> json_contains(full_discount_reduction_id_list, #{fulldiscountreductionid}) </if> </where> </select>
數據庫可執行的 SQL 語句:
select * from tb_goods where json_contains(full_discount_reduction_id_list, '"1615237656678371329"');
#{fulldiscountreductionid} 會在參數周圍添加單引號,導致 SQL 語法錯誤。
解決方案:
為了避免這個問題,應使用${} 代替 #{ } 直接將參數嵌入 SQL 語句中。
正確的 XML 代碼片段:
<select id="selectGoods" resultType="com.example.Goods"> select * from tb_goods <where> <if test="fullDiscountReductionId != null"> JSON_CONTAINS(full_discount_reduction_id_list, ${fullDiscountReductionId}) </if> </where> </select>
使用 ${} 可以避免 MyBatis 自動添加單引號。
安全警告:
使用 ${} 會增加 SQL 注入風險。 務必對所有用戶輸入的參數進行嚴格的驗證和過濾,以防止 SQL 注入攻擊。 建議優先使用預編譯語句 (#{ }),并結合合適的參數類型和輸入校驗來保證安全性。 只有在無法使用預編譯語句的情況下,才謹慎考慮使用 ${} ,并做好充分的安全防護措施。
本例中,如果 fullDiscountReductionId 來自用戶輸入,必須在 Java 代碼中進行嚴格的輸入驗證和轉義處理,確保其安全后再傳遞給 MyBatis。 例如,可以使用正則表達式或其他安全方法來過濾掉潛在的惡意代碼。