String url = "jdbc:oracle:thin:@localhost:1521:ora92";
String user = "scott", pwd = "tiger";
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection(url, user, pwd);
Context ctx = new InitialContext(env); // env 含 PROVIDER_URL、INITIAL_CONTEXT_FACTORY
DataSource ds = (DataSource) ctx.lookup("jdbc/db");
Connection conn = ds.getConnection();
優勢:連線池管理、聲明式事務、應用伺服器整合、配置與代碼分離。
| 介面 | 適用場景 | 關鍵方法 |
|---|---|---|
| Statement | 靜態 SQL、無參數 | executeQuery()、executeUpdate() |
| PreparedStatement | 參數化 SQL、防注入、重複執行 | setXxx()、executeQuery/Update() |
| CallableStatement | 預存程序 | registerOutParameter()、execute() |
String sql = "INSERT INTO users(id, name) VALUES(?, ?)";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, 1001);
ps.setString(2, "zhangsan");
int rows = ps.executeUpdate();
conn.setAutoCommit(false); // 關閉自動提交
try {
Statement stmt = conn.createStatement();
stmt.executeUpdate("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
stmt.executeUpdate("UPDATE accounts SET balance = balance + 100 WHERE id = 2");
stmt.close();
conn.commit(); // 全部成功提交
} catch (SQLException e) {
conn.rollback(); // 任一失敗回滾
throw e;
} finally {
// 關閉資源(見下節)
}
// JDK 7+ try-with-resources(推薦)
try (Connection conn = ds.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {
// 業務邏輯
} // 自動關閉,即使拋出異常
// JDK 6 手動關閉模板
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = ds.getConnection();
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
// 處理結果
} finally {
closeQuietly(rs);
closeQuietly(ps);
closeQuietly(conn);
}
// closeQuietly 內部捕獲異常,避免掩蓋原始異常
public class JdbcTemplate {
private DataSource ds;
public JdbcTemplate(DataSource ds) { this.ds = ds; }
public void transfer(int fromId, int toId, double amount) {
String sql1 = "UPDATE accounts SET balance = balance - ? WHERE id = ?";
String sql2 = "UPDATE accounts SET balance = balance + ? WHERE id = ?";
try (Connection conn = ds.getConnection()) {
conn.setAutoCommit(false);
try (PreparedStatement ps1 = conn.prepareStatement(sql1);
PreparedStatement ps2 = conn.prepareStatement(sql2)) {
ps1.setDouble(1, amount); ps1.setInt(2, fromId);
ps2.setDouble(1, amount); ps2.setInt(2, toId);
ps1.executeUpdate();
ps2.executeUpdate();
conn.commit();
} catch (SQLException e) {
conn.rollback();
throw new RuntimeException("Transfer failed", e);
}
} catch (SQLException e) {
throw new RuntimeException("DB connection failed", e);
}
}
}
ps.addBatch() + executeBatch() 大幅提升大量寫入效能Blob/Clob 流式讀寫,避免記憶體溢位PreparedStatement,絕不拼接 SQL 字串JDBC 核心流程:獲取連線 → 建立 Statement → 綁定參數 → 執行 → 處理結果 → 釋放資源。掌握 DataSource、PreparedStatement、聲明式事務與 try-with-resources,即可寫出健壯、安全、高效的資料存取代碼。現代框架(Spring JDBC、MyBatis、JPA)皆建立在此基礎之上,理解底層機制有助於排查疑難雜症與效能調優。