JDBC (Java Database Connectivity) 是 Java 操作關係型數據庫的統一規範。本文系統梳理核心接口、使用步驟、CRUD、PreparedStatement、批處理、事務、SQL 注入防範,含完整可運行代碼。
| 特性 | Statement | PreparedStatement |
| SQL 注入 | 風險高 | 參數化查詢,自動轉義,安全 |
| 預編譯 | 每次編譯 | 一次編譯多次執行,效率高 |
| 佔位符 | 不支援 | 支援 ? 佔位符,簡化拼接 |
| 批處理 | addBatch(sql) | addBatch() 綁定參數後加入 |
4. ResultSet
- 游標模型:初始指向第一行前,
next() 移動到下一行
- 滾動:
previous()、absolute(row)、beforeFirst()、afterLast()(需創建時指定 TYPE_SCROLL_INSENSITIVE)
- 獲取數據:
getObject() 通用,getString()、getInt()、getDate() 等類型安全方法
四、URL 格式與常用參數
jdbc:mysql://host:port/db?key=value&key=value
# 核心參數
useUnicode=true&characterEncoding=UTF-8
autoReconnect=true&failOverReadOnly=false
rewriteBatchedStatements=true # 關鍵:啟用批處理重寫,大幅提升批量寫入性能
useSSL=false&serverTimezone=Asia/Shanghai # 8.0+ 必加
五、CRUD 完整示例
String url = "jdbc:mysql://localhost:3306/skyfin?useUnicode=true&characterEncoding=UTF-8";
String user = "root", pass = "skyfin";
Class.forName("com.mysql.jdbc.Driver");
try (Connection conn = DriverManager.getConnection(url, user, pass);
Statement st = conn.createStatement()) {
// Query
try (ResultSet rs = st.executeQuery("SELECT * FROM user")) {
while (rs.next()) {
System.out.println(rs.getInt("id") + " " + rs.getString("name"));
}
}
// Insert
int n = st.executeUpdate("INSERT INTO user(name,pwd) VALUES('staff','staff')");
System.out.println(n > 0 ? "Insert OK" : "Insert Fail");
// Update
n = st.executeUpdate("UPDATE user SET name='skstaff' WHERE name='staff'");
// Delete
n = st.executeUpdate("DELETE FROM user WHERE name='skstaff'");
}
六、PreparedStatement + 批處理 + 事務(高性能寫入模板)
String url = "jdbc:mysql://localhost:3306/skyfin?rewriteBatchedStatements=true";
Connection conn = DriverManager.getConnection(url, user, pass);
conn.setAutoCommit(false); // 開啟事務
String sql = "INSERT INTO user1(id,name) VALUES(?,?)";
try (PreparedStatement ps = conn.prepareStatement(sql)) {
for (int i = 0; i < 10000; i++) {
ps.setInt(1, i);
ps.setString(2, "skyfin" + i);
ps.addBatch();
if (i % 500 == 0) { // 分批提交,避免大事務
ps.executeBatch();
conn.commit();
}
}
ps.executeBatch();
conn.commit();
} catch (SQLException e) {
conn.rollback();
throw e;
} finally {
conn.setAutoCommit(true);
}
關鍵點:
- URL 必須加
rewriteBatchedStatements=true,否則批處理退化為逐條執行
PreparedStatement 對象在循環外創建,循環內僅綁定參數 + addBatch()
- 分批提交(如每 500 條)平衡事務大小與網絡往返
七、SQL 注入防範
- 根因:拼接 SQL 字串,用戶輸入含特殊字符(
' OR 1=1 --)改變語義
- 核心防禦:全量使用 PreparedStatement 參數化查詢
- 輔助:輸入校驗(長度、格式、白名單)、最小權限賬號、WAF
八、資源管理最佳實踐
// Java 7+ try-with-resources 自動關閉
try (Connection conn = DriverManager.getConnection(url, user, pass);
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {
// 業務邏輯
} // 自動按相反順序 close()
JDBC 看似基礎,但「連接池、預處理、批處理、事務邊界、資源釋放」五大核心掌握得好壞,直接決定數據層的穩定性與吞吐上限。
- 上一篇文章: Mycat 實戰:聊天消息表按月分表與 Java 客戶端跨月查詢
- 下一篇文章: Windows 7 64位安裝 MySQL 5.6.24 圖文完整教程
Copyright ©
程式碼之家 All Rights Reserved