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

MyBatis 批量插入數據 Mapper XML 寫法詳解:foreach、selectKey 主鍵回填實戰

     編輯:Java 相關知識

MyBatis 批量插入通過 <foreach> 動態拼接 VALUES 子句實現,配合 <selectKey> 實現自增主鍵回填。本文詳細講解 Mapper XML 核心標籤屬性、參數綁定、主鍵策略差異(MySQL/Oracle/PostgreSQL),附帶生產級最佳實踐。

核心 Mapper XML 範例


<insert id="insertAll" parameterType="java.util.List" useGeneratedKeys="true">
  <selectKey resultType="long" keyProperty="id" order="AFTER">
    SELECT LAST_INSERT_ID()
  </selectKey>
  INSERT INTO workflow_info (
    belong_program, workflow_comment, schedule_id, job_id,
    parent_job_id, job_level, exec_time, created_user
  ) VALUES
  <foreach collection="list" item="item" index="index" separator=",">
    (#{item.belongProgram}, #{item.workFlowComment}, #{item.scheduleId},
     #{item.jobId}, #{item.parentJobId}, #{item.jobLevel},
     #{item.execTime}, #{item.createdUser})
  </foreach>
</insert>

關鍵標籤深度解析

1. <foreach> 批量拼接

屬性說明範例值
collection要遍歷的集合,List 傳 "list",數組傳 "array",Map 需指定 keylist
item當前迭代元素別名item
index索引別名(List 為 int,Map 為 key)index
separator元素間分隔符,
open/close整體前後綴(可選)open="(" close=")"

生成 SQL 示例:

INSERT INTO workflow_info (...) VALUES
(?, ?, ?, ?, ?, ?, ?, ?),
(?, ?, ?, ?, ?, ?, ?, ?),
(?, ?, ?, ?, ?, ?, ?, ?)

2. <selectKey> 主鍵回填

屬性說明
keyProperty實體類主鍵屬性名,回填目標
resultType主鍵類型(Long/Integer/String 等)
orderAFTER:插入後查詢(MySQL 自增);BEFORE:插入前查詢(Oracle Sequence、PostgreSQL serial)
statementTypeSTATEMENT/PREPARED/CALLABLE(默認 PREPARED)

數據庫差異對策

  • MySQL (AUTO_INCREMENT):order="AFTER" + SELECT LAST_INSERT_ID() 或啟用 useGeneratedKeys="true"(推薦,無需 selectKey)。
  • Oracle (Sequence):order="BEFORE" + SELECT seq_name.NEXTVAL FROM DUAL。
  • PostgreSQL (SERIAL/IDENTITY):order="AFTER" + SELECT CURRVAL('seq_name') 或 INSERT ... RETURNING id (PG 8.2+)。
  • SQL Server (IDENTITY):order="AFTER" + SELECT SCOPE_IDENTITY()。

Java 代碼調用

Mapper 接口


@Mapper
public interface WorkflowMapper {
    void insertAll(List<WorkflowInfo> list);
}

Service 層


@Service
@Transactional
public class WorkflowService {
    @Autowired WorkflowMapper mapper;
    public void batchSave(List<WorkflowInfo> list) {
        if (list != null && !list.isEmpty()) {
            mapper.insertAll(list);
            // 插入後,list 中每個對象的 id 已被回填
        }
    }
}

效能優化建議

  1. 批次大小控制:單次 500-1000 條,避免 SQL 過大超過 max_allowed_packet 或解析超時。
  2. ExecutorType.BATCH:MyBatis 配置 defaultExecutorType=BATCH 或代碼中 sqlSessionFactory.openSession(ExecutorType.BATCH),複用 PreparedStatement,大幅提升批量寫入速度。
  3. 關閉不必要的緩存:useCache="false"、flushCache="true"。
  4. 參數綁定優化:實體類屬性名與數據庫列名一致時,可省略 @Param 並開啟 mapUnderscoreToCamelCase。

常見坑點

  • 主鍵未回填:檢查 keyProperty 拼寫、order 是否匹配數據庫策略、實體類 setter 是否存在。
  • 集合參數名錯誤:單參數 List 默認名 "list",數組 "array",多參數時需 @Param("list") 指定。
  • 批量插入事務:務必在 Service 層加 @Transactional,確保原子性。

掌握 <foreach> 與 <selectKey>,配合 useGeneratedKeys 與 ExecutorType.BATCH,即可構建高效、可靠的 MyBatis 批量寫入方案。

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