首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java JDBC 數據庫連接完整實戰指南:從基礎到連接池優化

     編輯:Java 相關知識

JDBC 核心七步驟標準流程

  1. 加載驅動:Class.forName("com.mysql.cj.jdbc.Driver")
  2. 定義 URL:jdbc:mysql://host:3306/db?params
  3. 獲取連接:DriverManager.getConnection(url, user, pwd)
  4. 創建 Statement:conn.createStatement() / prepareStatement() / prepareCall()
  5. 執行 SQL:executeQuery() / executeUpdate() / execute()
  6. 處理結果:ResultSet 遍歷 / 影響行數
  7. 釋放資源:逆序關閉 ResultSet → Statement → Connection

三大 Statement 類型對比

類型用途特點防注入
Statement靜態 SQL簡單、無預編譯無
PreparedStatement參數化 SQL預編譯、緩存執行計劃✓ 佔位符 ?
CallableStatement存儲過程調用 {call proc(?,?)}✓

PreparedStatement 參數綁定完整指南

String sql = "INSERT INTO users(username, email, age, create_time, status) VALUES (?, ?, ?, ?, ?)";
PreparedStatement ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);

ps.setString(1, "張三");           // String
ps.setString(2, "zhang@example.com");
ps.setInt(3, 25);                  // 基本類型
ps.setTimestamp(4, new Timestamp(System.currentTimeMillis())); // 日期時間
ps.setBoolean(5, true);            // 布爾

int rows = ps.executeUpdate();

// 獲取自增主鍵
try (ResultSet keys = ps.getGeneratedKeys()) {
    if (keys.next()) {
        long id = keys.getLong(1);
        System.out.println("生成 ID: " + id);
    }
}

ResultSet 進階操作

// 滾動/可更新 ResultSet
Statement stmt = conn.createStatement(
    ResultSet.TYPE_SCROLL_INSENSITIVE,  // 可滾動
    ResultSet.CONCUR_UPDATABLE          // 可更新
);
ResultSet rs = stmt.executeQuery("SELECT * FROM users");

// 絕對/相對定位
rs.absolute(5);      // 第 5 行
rs.relative(-2);     // 向前 2 行
rs.first(); rs.last(); rs.beforeFirst(); rs.afterLast();

// 更新數據
rs.absolute(3);
rs.updateString("email", "new@email.com");
rs.updateRow();      // 同步到數據庫

// 插入行
rs.moveToInsertRow();
rs.updateString("username", "newuser");
rs.updateString("email", "new@test.com");
rs.insertRow();
rs.moveToCurrentRow();

事務管理

conn.setAutoCommit(false); // 開啟事務
try {
    // 多條 SQL
    ps1.executeUpdate();
    ps2.executeUpdate();
    conn.commit(); // 提交
} catch (SQLException e) {
    conn.rollback(); // 回滾
    throw e;
} finally {
    conn.setAutoCommit(true); // 恢復默認
}

// 保存點
Savepoint sp = conn.setSavepoint();
try { ... } catch (Exception e) { conn.rollback(sp); }

批量操作優化

conn.setAutoCommit(false);
String sql = "INSERT INTO logs(level, message) VALUES (?, ?)";
PreparedStatement ps = conn.prepareStatement(sql);

for (LogEntry entry : entries) {
    ps.setString(1, entry.getLevel());
    ps.setString(2, entry.getMessage());
    ps.addBatch(); // 累積批次
    
    if (count % 1000 == 0) {
        ps.executeBatch(); // 執行批次
        conn.commit();
    }
}
ps.executeBatch(); // 剩餘
conn.commit();

連接池配置最佳實踐 (HikariCP)

HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC");
config.setUsername("user");
config.setPassword("pwd");

// 核心池大小 = CPU 核心數 * 2 (IO 密集型)
config.setMaximumPoolSize(Runtime.getRuntime().availableProcessors() * 2);
config.setMinimumIdle(5);

// 超時設置
config.setConnectionTimeout(30000);      // 獲取連接超時 30s
config.setIdleTimeout(600000);           // 空閒回收 10min
config.setMaxLifetime(1800000);          // 最大存活 30min

// 連接驗證
config.setValidationTimeout(5000);
config.setLeakDetectionThreshold(60000); // 洩漏檢測 1min

DataSource ds = new HikariDataSource(config);

Oracle 數據庫連接差異

// 驅動: oracle.jdbc.driver.OracleDriver (ojdbc8.jar)
// URL 格式
jdbc:oracle:thin:@host:1521:sid        // SID 模式
jdbc:oracle:thin:@host:1521/service    // Service 模式
jdbc:oracle:thin:@(description=(address=(host=host)(protocol=tcp)(port=1521))(connect_data=(service_name=svc))) // TNS

// 分頁查詢 (Oracle 12c+)
SELECT * FROM users ORDER BY id OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY;

// 序列獲取自增 ID
INSERT INTO users(id, name) VALUES (seq_users.nextval, ?)

常見異常與排查

異常原因解決
Communications link failure網絡/防火牆/數據庫未啟動檢查連通性、端口、bind-address
Public Key Retrieval is not allowedMySQL 8 密碼插件URL 添加 allowPublicKeyRetrieval=true
Server Timezone value unrecognized時區不匹配serverTimezone=Asia/Shanghai
Connection reset連接空閒超時被斷開連接池配置 validationQuery/testOnBorrow
Packet for query is too largeSQL/結果集過大調大 max_allowed_packet

生產環境檢查清單

  • [ ] 使用連接池 (HikariCP 首選)
  • [ ] 所有查詢使用 PreparedStatement
  • [ ] 批量操作使用 addBatch/executeBatch
  • [ ] 事務邊界清晰,異常回滾
  • [ ] 連接池監控指標配置 (活躍/空閒/等待/洩漏)
  • [ ] 慢查詢日誌分析與索引優化
  • [ ] 數據庫密碼加密存儲 (配置中心/密碼服務)

JDBC 雖然底層,但掌握其核心模式與優化技巧,是構建高性能數據訪問層的基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved