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

JDBC 數據庫編程核心技巧:可滾動結果集、批量更新與事務控制

     編輯:Java 相關知識

標準 JDBC 操作流程

  1. 加載驅動:Class.forName("com.mysql.cj.jdbc.Driver")
  2. 獲取連接:DriverManager.getConnection(url, user, pwd) 或 DataSource (JNDI)
  3. 創建 Statement / PreparedStatement
  4. 執行 SQL:executeQuery() (SELECT) / executeUpdate() (DML/DDL)
  5. 處理 ResultSet 或更新行數
  6. 按逆序關閉:ResultSet → Statement → Connection

技巧一:可滾動、可更新結果集


// 創建時指定類型與併發性
Statement stmt = conn.createStatement(
    ResultSet.TYPE_SCROLL_INSENSITIVE,   // 可滾動,不感知他人修改
    ResultSet.CONCUR_UPDATABLE           // 可更新
);
ResultSet rs = stmt.executeQuery("SELECT id, name, score FROM students");

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

// 更新當前行
rs.updateInt("score", 100);
rs.updateRow();      // 同步到數據庫

// 插入新行
rs.moveToInsertRow();
rs.updateString("name", "新生");
rs.updateInt("score", 88);
rs.insertRow();
rs.moveToCurrentRow();

注意:MySQL 需主鍵且查詢單表才支持可更新結果集;Oracle/PostgreSQL 支持更豐富。

技巧二:批量更新

Statement.addBatch()

Statement stmt = conn.createStatement();
stmt.addBatch("INSERT INTO log VALUES (1, 'msg1')");
stmt.addBatch("INSERT INTO log VALUES (2, 'msg2')");
stmt.addBatch("UPDATE stats SET cnt = cnt + 1");
int[] counts = stmt.executeBatch(); // 每條語句影響行數

PreparedStatement 參數化批量

String sql = "INSERT INTO orders(user_id, amount) VALUES (?, ?)";
PreparedStatement ps = conn.prepareStatement(sql);
for (Order o : orders) {
    ps.setLong(1, o.getUserId());
    ps.setBigDecimal(2, o.getAmount());
    ps.addBatch();
}
int[] results = ps.executeBatch(); // 單次網絡往返執行所有

性能提升數量級,必須配合 rewriteBatchedStatements=true (MySQL) 或類似驅動參數。

技巧三:事務控制

conn.setAutoCommit(false); // 關閉自動提交
try {
    // 業務邏輯:多條 SQL
    try (PreparedStatement ps1 = conn.prepareStatement(sql1);
         PreparedStatement ps2 = conn.prepareStatement(sql2)) {
        ps1.executeUpdate();
        ps2.executeUpdate();
    }
    conn.commit(); // 全部成功提交
} catch (SQLException e) {
    conn.rollback(); // 任一失敗回滾
    throw e;
} finally {
    conn.setAutoCommit(true); // 恢復默認
}

關鍵點:同一事務內多條 SQL 必須共用同一 Connection;每條執行前關閉上一個 Statement 避免游標衝突。

進階最佳實踐

  • 連接池:HikariCP / Druid,生產環境必備
  • PreparedStatement 緩存:池層面緩存 PreparedStatement 減少解析開銷
  • 異常分類處理:SQLTransientException 可重試,SQLNonTransientException 需人工干預
  • 大對象處理:Blob/Clob 使用流式讀寫,避免一次性載入內存
  • 避免 N+1:批量查詢 IN 列表或 JOIN,而非循環單查
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved