首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

MyBatis Oracle 多條件批量刪除:從 #{ } 到 ${ } 的關鍵突破

     編輯:程式設計綜合問答

問題背景

使用 MyBatis <foreach> 搭配 #{item.property} 進行 Oracle 多條件批量刪除,SQL 語法正確、參數日誌無誤,但資料庫執行計畫顯示未命中索引、實際未刪除任何資料。

核心原因

#{ } 會生成 PreparedStatement 佔位符 (?),Oracle 在解析含大量 OR 條件的 SQL 時,可能無法正確推導執行計畫,導致全表掃描或參數綁定失效。

解決方案:改用 ${ } 進行字串替換 + EXISTS + UNION ALL

<delete id="delMultiByIds2" parameterType="java.util.List">
  delete from tb_duty A where exists (
    select 1 from (
      <foreach collection="list" item="item" separator="union all">
        select * from tb_duty B 
        where 1=1 
          and B.dscd=${item.dscd}
          and B.unit_id=${item.unitId}
          and B.year=${item.year}
          and B.month=${item.month}
          and B.flag=${item.flag}
      </foreach>
    ) S where A.duty_id = S.duty_id
  )
</delete>

關鍵點解析

  • ${item.xxx}:直接將值拼接進 SQL 字串,Oracle 能精確解析字面值,選擇最優索引。
  • EXISTS + UNION ALL:避免巨大 IN 或 OR 列表,利用集合運算提升效率。
  • 參數類型安全:確保 List 物件屬性非 null,防止 SQL 注入風險 (僅限受信內部介面使用)。

適用場景

Oracle 大量資料多條件批量刪除/更新,且需確保索引生效時。MySQL/PostgreSQL 通常 #{ } 即可正常工作。

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