บทนำ: Batch Update คืออะไร?
Batch Update คือการรวมกลุ่มคำสั่ง SQL หลายคำสั่ง (INSERT, UPDATE, DELETE) ที่สร้าง Update Count เข้าด้วยกัน และส่งไป Execute ที่ Database ครั้งเดียว เพื่อลด Network Round-trip และเพิ่มประสิทธิภาพ
Parameterized Batch Update คืออะไร?
การใช้ PreparedStatement ร่วมกับ Placeholder (?) แทนค่าจริง แล้วตั้งค่าพารามิเตอร์ด้วย Setter Methods (setString, setInt เป็นต้น) และเพิ่มแต่ละชุดพารามิเตอร์เข้า Batch ด้วย addBatch() ก่อน Execute ทั้งหมดด้วย executeBatch()
ขั้นตอนการสร้าง Parameterized Batch Update
- สร้าง
PreparedStatementพร้อม Placeholder (?) - ปิด Auto-commit:
con.setAutoCommit(false) - วนลูปตั้งค่าพารามิเตอร์ →
addBatch() - Execute:
executeBatch() - Commit:
con.commit()
ตัวอย่างโค้ดเต็มรูปแบบ
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.Statement;
public class ParameterizedBatchUpdate {
public static void main(String args[]) throws Exception {
// 1. เชื่อมต่อฐานข้อมูล
String mysqlUrl = "jdbc:mysql://localhost/testDB";
Connection con = DriverManager.getConnection(mysqlUrl, "root", "password");
System.out.println("Connection established......");
// 2. ปิด Auto-commit (สำคัญมาก!)
con.setAutoCommit(false);
// 3. เตรียม PreparedStatement พร้อม Placeholder
PreparedStatement pstmt = con.prepareStatement(
"INSERT INTO Sales VALUES (?, ?, ?, ?, ?)"
);
// 4. ชุดข้อมูลที่ 1
pstmt.setString(1, "KeyBoard");
pstmt.setString(2, "Amith");
pstmt.setString(3, "January");
pstmt.setInt(4, 1000);
pstmt.setString(5, "Hyderabad");
pstmt.addBatch();
// 5. ชุดข้อมูลที่ 2
pstmt.setString(1, "Earphones");
pstmt.setString(2, "Sumith");
pstmt.setString(3, "March");
pstmt.setInt(4, 500);
pstmt.setString(5, "Vishakhapatnam");
pstmt.addBatch();
// 6. ชุดข้อมูลที่ 3
pstmt.setString(1, "Mouse");
pstmt.setString(2, "Sudha");
pstmt.setString(3, "September");
pstmt.setInt(4, 500);
pstmt.setString(5, "Vijayawada");
pstmt.addBatch();
// 7. Execute Batch
int[] results = pstmt.executeBatch(); // คืนค่า int[] จำนวนแถวที่เปลี่ยนแปลงแต่ละคำสั่ง
// 8. Commit ธุรกรรม
con.commit();
System.out.println("Records inserted......");
// 9. ปิดทรัพยากร
pstmt.close();
con.close();
}
}
โครงสร้างตาราง Sales (ตัวอย่าง)
+-------------------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------------------+--------------+------+-----+---------+-------+ | Product_Name | varchar(255) | YES | | NULL | | | Name_Of_Customer | varchar(255) | YES | | NULL | | | Month_Of_Dispatch | varchar(255) | YES | | NULL | | | Price | int(11) | YES | | NULL | | | Location | varchar(255) | YES | | NULL | | +-------------------+--------------+------+-----+---------+-------+
ผลลัพธ์ Output
Connection established...... Records inserted......
ข้อดีของ Parameterized Batch Update
| ประเด็น | Statement Batch | Parameterized Batch (PreparedStatement) |
|---|---|---|
| Security | เสี่ยง SQL Injection | ปลอดภัย (Parameterized) |
| Performance | Parse SQL ทุกครั้ง | Parse/Compile ครั้งเดียว ใช้ซ้ำ |
| Readability | SQL ผสมค่าทำให้อ่านยาก | แยก SQL และ Data ชัดเจน |
| Type Safety | ไม่มี | มี (setInt, setString, setDate) |
Best Practices และข้อควรระวัง
- Batch Size: ไม่ควรเพิ่มมากเกินไป (แนะนำ 500-1000 records/batch) เพื่อป้องกัน OutOfMemory
- Error Handling:
executeBatch()อาจโยนBatchUpdateExceptionตรวจสอบgetUpdateCounts() - Transaction: ต้อง
commit()หลัง Execute และrollback()หาก Error - Resource Cleanup: ปิด PreparedStatement และ Connection ใน finally block
- Rewriting: บาง Driver (MySQL) ต้องเพิ่ม
rewriteBatchedStatements=trueใน JDBC URL เพื่อ Performance ดีที่สุด
JDBC URL สำหรับ MySQL Batch Optimization
jdbc:mysql://localhost/testDB?rewriteBatchedStatements=true&useServerPrepStmts=true
สรุป
Parameterized Batch Update เป็นวิธีที่ ปลอดภัย เร็ว และ อ่านง่าย สำหรับการ Insert/Update/Delete ข้อมูลจำนวนมากใน JDBC ควรใช้ PreparedStatement ร่วมกับ addBatch()/executeBatch() และจัดการ Transaction ให้ถูกต้อง