MyBatis 批量插入通過 <foreach> 動態拼接 VALUES 子句實現,配合 <selectKey> 實現自增主鍵回填。本文詳細講解 Mapper XML 核心標籤屬性、參數綁定、主鍵策略差異(MySQL/Oracle/PostgreSQL),附帶生產級最佳實踐。
<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>
| 屬性 | 說明 | 範例值 |
|---|---|---|
| collection | 要遍歷的集合,List 傳 "list",數組傳 "array",Map 需指定 key | list |
| item | 當前迭代元素別名 | item |
| index | 索引別名(List 為 int,Map 為 key) | index |
| separator | 元素間分隔符 | , |
| open/close | 整體前後綴(可選) | open="(" close=")" |
生成 SQL 示例:
INSERT INTO workflow_info (...) VALUES
(?, ?, ?, ?, ?, ?, ?, ?),
(?, ?, ?, ?, ?, ?, ?, ?),
(?, ?, ?, ?, ?, ?, ?, ?)
| 屬性 | 說明 |
|---|---|
| keyProperty | 實體類主鍵屬性名,回填目標 |
| resultType | 主鍵類型(Long/Integer/String 等) |
| order | AFTER:插入後查詢(MySQL 自增);BEFORE:插入前查詢(Oracle Sequence、PostgreSQL serial) |
| statementType | STATEMENT/PREPARED/CALLABLE(默認 PREPARED) |
order="AFTER" + SELECT LAST_INSERT_ID() 或啟用 useGeneratedKeys="true"(推薦,無需 selectKey)。order="BEFORE" + SELECT seq_name.NEXTVAL FROM DUAL。order="AFTER" + SELECT CURRVAL('seq_name') 或 INSERT ... RETURNING id (PG 8.2+)。order="AFTER" + SELECT SCOPE_IDENTITY()。
@Mapper
public interface WorkflowMapper {
void insertAll(List<WorkflowInfo> list);
}
@Service
@Transactional
public class WorkflowService {
@Autowired WorkflowMapper mapper;
public void batchSave(List<WorkflowInfo> list) {
if (list != null && !list.isEmpty()) {
mapper.insertAll(list);
// 插入後,list 中每個對象的 id 已被回填
}
}
}
max_allowed_packet 或解析超時。defaultExecutorType=BATCH 或代碼中 sqlSessionFactory.openSession(ExecutorType.BATCH),複用 PreparedStatement,大幅提升批量寫入速度。useCache="false"、flushCache="true"。@Param 並開啟 mapUnderscoreToCamelCase。keyProperty 拼寫、order 是否匹配數據庫策略、實體類 setter 是否存在。@Param("list") 指定。@Transactional,確保原子性。掌握 <foreach> 與 <selectKey>,配合 useGeneratedKeys 與 ExecutorType.BATCH,即可構建高效、可靠的 MyBatis 批量寫入方案。