mybatis xml 文件中 sql 語句引號處理及 json_CONTaiNS 函數使用
在使用 MyBatis 等框架操作數據庫時,XML 文件中的 SQL 語句引號處理常常令人頭疼,尤其是在使用 JSON_CONTAINS 等函數時。本文將通過一個案例,講解如何正確處理 XML 文件中的 SQL 語句引號,避免因引號轉義不當導致的 JSON_CONTAINS 函數錯誤。
問題:
在 MyBatis XML 映射文件中,使用 JSON_CONTAINS 函數判斷 tb_goods 表的 full_discount_reduction_id_list 列(JSON 類型)是否包含特定值。直接在數據庫中執行 SQL 語句結果正確,但在 XML 文件中卻失敗。問題源于 XML 文件中引號的轉義處理。
錯誤 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"');
問題在于 XML 中的 #{fulldiscountreductionid} 缺少必要的引號,直接添加雙引號需要轉義,增加了復雜性。
解決方案:
關鍵在于 MyBatis 參數占位符的使用。#{fulldiscountreductionid} 會被 MyBatis 自動處理類型和引號轉義,但 JSON_CONTAINS 需要參數作為字符串字面量,而非參數占位符。
因此,應將 #{fulldiscountreductionid} 替換為 ${fulldiscountreductionid}。$ 符號表示直接替換參數值,無需 MyBatis 額外處理,避免了引號轉義問題。MyBatis 將直接將參數值插入 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 注入風險,務必確保參數值的安全性。 建議優先使用 #{},只有在確實需要避免 MyBatis 自動轉義的情況下才使用 ${},并對輸入參數進行嚴格的校驗和過濾。