推薦架構
Excel 解析 (POI)
→ 批量 DTO 列表
→ Service 層分批 (如 500 條/批)
→ 調用存儲過程 / MERGE 語句
→ 數據庫去重入庫
存儲過程示例
CREATE PROCEDURE BatchInsertStudent(
IN p_name VARCHAR(50), IN p_sex INT, IN p_age INT,
IN p_grade INT, IN p_wishType INT, IN p_wishDesc VARCHAR(200),
IN p_wishStory VARCHAR(500), IN p_teacherWords VARCHAR(500),
IN p_teacherMobile VARCHAR(20)
)
BEGIN
-- 唯一鍵假設為 name + wishType
IF NOT EXISTS (SELECT 1 FROM student WHERE name = p_name AND wishType = p_wishType) THEN
INSERT INTO student(name, sex, age, grade, wishType, wishDesc, wishStory, teacherWords, teacherMobile)
VALUES (p_name, p_sex, p_age, p_grade, p_wishType, p_wishDesc, p_wishStory, p_teacherWords, p_teacherMobile);
END IF;
END;
Java 批量調用
String sql = "{call BatchInsertStudent(?,?,?,?,?,?,?,?,?)}";
try (CallableStatement cs = conn.prepareCall(sql)) {
for (Student s : batchList) {
cs.setString(1, s.getName());
cs.setInt(2, s.getSex());
// ... 設置其餘參數
cs.addBatch();
}
cs.executeBatch(); // 一次網絡往返執行整批
}
優勢
- 性能:減少應用↔數據庫網絡往返,利用數據庫索引高效去重。
- 一致性:事務內原子操作,避免應用層檢查-插入間隙的並發重複。
- 簡潔:應用層無需加載現有數據對比,邏輯下推數據庫。
替代方案
- MERGE 語句(Oracle/SQL Server/PostgreSQL 9.5+):單條 SQL 實現 upsert。
- 唯一索引 + INSERT IGNORE / ON DUPLICATE KEY UPDATE(MySQL)。
- 應用層去重:
Set keys = new HashSet<>(); 適用于小數據量(< 10萬)。