直接在業務代碼中管理 Connection、Statement、ResultSet 不僅冗長,更易導致資源洩漏。本文展示一個輕量級 DB 工具類,涵蓋連線獲取、Statement 建立、查詢執行與安全關閉,並說明生產環境應改用連線池的原因。
package com.zm.bbs;
import java.sql.*;
public final class DB {
private static final String URL = "jdbc:mysql://localhost:3306/bbs";
private static final String USER = "root";
private static final String PASS = "root";
private DB() {} // 工具類禁止實例化
/** 獲取新連線 (生產環境請替換為 HikariCP / Druid) */
public static Connection getConn() throws SQLException {
try { Class.forName("com.mysql.cj.jdbc.Driver"); }
catch (ClassNotFoundException e) { throw new IllegalStateException("Driver not found", e); }
return DriverManager.getConnection(URL, USER, PASS);
}
public static Statement getStmt(Connection conn) throws SQLException {
return conn.createStatement();
}
public static ResultSet getRs(Statement stmt, String sql) throws SQLException {
return stmt.executeQuery(sql);
}
/** 安全關閉 ResultSet */
public static void close(ResultSet rs) {
if (rs != null) try { rs.close(); } catch (SQLException ignore) {}
}
/** 安全關閉 Statement */
public static void close(Statement stmt) {
if (stmt != null) try { stmt.close(); } catch (SQLException ignore) {}
}
/** 安全關閉 Connection */
public static void close(Connection conn) {
if (conn != null) try { conn.close(); } catch (SQLException ignore) {}
}
/** 一鍵關閉全部資源 (Java 7+ try-with-resources 更優雅) */
public static void closeAll(Connection c, Statement s, ResultSet r) {
close(r); close(s); close(c);
}
}
close 先判 null,防止 NPE。Class.forName 可省略;保留以相容舊驅動。上述實作每次請求都建立新連線,效能極差。諜引 HikariCP (Spring Boot 默認) 或 Druid:
// HikariCP 範例
HikariConfig cfg = new HikariConfig();
cfg.setJdbcUrl(URL); cfg.setUsername(USER); cfg.setPassword(PASS);
cfg.setMaximumPoolSize(20);
DataSource ds = new HikariDataSource(cfg);
// 使用
try (Connection c = ds.getConnection();
PreparedStatement ps = c.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {
// 業務邏輯
}
PreparedStatement 防 SQL 注入、利用語句快取。maxLifetime、idleTimeout、connectionTimeout 避免僵屍連線。@Transactional (Spring) 或手動 commit/rollback 控制事務邊界。activeConnections、idleConnections、connectionAcquisitionTime。從手寫工具類到引入成熟連線池,是 Java 開發者資料庫存取能力進階的必經之路。