以下是使用 JDBC 插入數據并獲取自動生成的主鍵(如 MySQL 的 AUTO_INCREMENT
或 Oracle 的序列) 的完整示例代碼,包含詳細注釋:
import java.sql.*;public class GeneratedKeysExample {// 數據庫連接參數private static final String URL = "jdbc:mysql://localhost:3306/mydatabase";private static final String USER = "root";private static final String PASSWORD = "your_password";public static void main(String[] args) {Connection conn = null;try {// 1. 加載數據庫驅動Class.forName("com.mysql.cj.jdbc.Driver");// 2. 獲取數據庫連接conn = DriverManager.getConnection(URL, USER, PASSWORD);// 3. 定義插入語句(包含自增主鍵)String sql = "INSERT INTO users (name, email) VALUES (?, ?)";// 4. 創建 PreparedStatement 并啟用返回生成的鍵try (PreparedStatement pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS // 關鍵:啟用生成鍵的返回)) {// 5. 設置參數pstmt.setString(1, "Alice");pstmt.setString(2, "alice@example.com");// 6. 執行插入操作int affectedRows = pstmt.executeUpdate();System.out.println("插入成功,影響行數:" + affectedRows);// 7. 獲取生成的主鍵try (ResultSet generatedKeys = pstmt.getGeneratedKeys()) {if (generatedKeys.next()) {long userId = generatedKeys.getLong(1); // 獲取第一列(主鍵)System.out.println("生成的用戶ID:" + userId);} else {throw new SQLException("創建用戶時未獲取到主鍵!");}}}} catch (ClassNotFoundException e) {System.out.println("JDBC驅動未找到!");e.printStackTrace();} catch (SQLException e) {System.out.println("數據庫操作失敗!");e.printStackTrace();} finally {// 8. 關閉連接try {if (conn != null) conn.close();} catch (SQLException e) {e.printStackTrace();}}}
}
代碼說明
1. 核心步驟
-
啟用生成鍵返回:
在prepareStatement()
中傳入Statement.RETURN_GENERATED_KEYS
,告知 JDBC 需要返回生成的鍵。 -
執行插入并獲取鍵:
executeUpdate()
執行插入操作。getGeneratedKeys()
返回包含生成鍵的ResultSet
。
-
處理結果集:
generatedKeys.next()
移動到第一條記錄(假設每次插入一條)。getLong(1)
獲取第一列(主鍵列)的值。
2. 數據庫表結構(MySQL 示例)
CREATE TABLE users (id BIGINT AUTO_INCREMENT PRIMARY KEY, -- 自增主鍵name VARCHAR(50),email VARCHAR(100)
);
關鍵注意事項
-
數據庫支持:
- MySQL:使用
AUTO_INCREMENT
主鍵。 - Oracle:需指定
RETURNING
子句或使用序列(代碼需調整)。 - PostgreSQL:支持
RETURNING
子句,但需調整 SQL 語法。
- MySQL:使用
-
多行插入:
如果插入多行,getGeneratedKeys()
返回所有生成的鍵,需遍歷ResultSet
。 -
列索引:
generatedKeys.getLong(1)
中的1
表示主鍵是結果集的第一列。若表有多個生成列,需根據列順序調整。
擴展場景:Oracle 示例
Oracle 需要使用 RETURNING
子句和序列:
// Oracle 示例代碼片段
String sql = "INSERT INTO users (id, name, email) " +"VALUES (user_seq.NEXTVAL, ?, ?) " +"RETURNING id INTO ?";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {pstmt.setString(1, "Alice");pstmt.setString(2, "alice@example.com");pstmt.registerOutParameter(3, OracleTypes.NUMBER); // 注冊輸出參數int rows = pstmt.executeUpdate();long userId = pstmt.getLong(3); // 通過輸出參數獲取主鍵
}
常見問題
Q1:為什么獲取不到生成的鍵?
- 原因:未在
prepareStatement()
中啟用RETURN_GENERATED_KEYS
。 - 解決:確保代碼中包含
Statement.RETURN_GENERATED_KEYS
。
Q2:如何處理批量插入的生成鍵?
// 批量插入示例
pstmt.addBatch(); // 添加多條數據
pstmt.executeBatch();// 獲取所有生成的鍵
try (ResultSet keys = pstmt.getGeneratedKeys()) {while (keys.next()) {long id = keys.getLong(1);// 處理每個生成的鍵}
}
最佳實踐
- 始終使用
try-with-resources
:確保資源自動關閉。 - 驗證返回結果:檢查
ResultSet
是否有數據,避免空指針異常。 - 數據庫兼容性測試:根據實際數據庫調整 SQL 語法(如 Oracle 的序列)。
通過此示例,你可以輕松實現插入數據并獲取自動生成的主鍵,適用于大多數關系型數據庫!