資料庫操作是 Java 後端核心,本文梳理三種層次的 JdbcUtils 實現:基礎連接、簡易連接池、完整事務管理,代碼可直接落地專案。
public class JdbcUtils {
private static final String CONFIG = "dbconfig.properties";
private static Properties prop = new Properties();
static {
try (InputStream in = Thread.currentThread()
.getContextClassLoader().getResourceAsStream(CONFIG)) {
prop.load(in);
Class.forName(prop.getProperty("driverClassName"));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static Connection getConnection() {
try {
return DriverManager.getConnection(
prop.getProperty("url"),
prop.getProperty("username"),
prop.getProperty("password")
);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
適用場景: 單體小應用、測試環境、無高併發需求。
c3p0-config.xml)配置片段:
<c3p0-config>
<default-config>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb1</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="user">root</property>
<property name="password">123</property>
<property name="initialPoolSize">10</property>
<property name="maxPoolSize">20</property>
</default-config>
</c3p0-config>
工具類:
public class JdbcUtils2 {
private static ComboPooledDataSource ds = new ComboPooledDataSource(); // 讀取默認配置
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
public static DataSource getDataSource() { return ds; }
}
優勢: 連接復用、池參數可配、支援多命名配置(如 Oracle 專用)。
核心難點:同一事務必須共用同一 Connection,且不能與普通查詢混淆。採用 ThreadLocal<Connection> 綁定當前線程事務連接。
public class JdbcUtils3 {
private static DataSource ds = new ComboPooledDataSource();
private static ThreadLocal<Connection> tl = new ThreadLocal<>();
// 獲取連接:有事務則返事務連接,否則從池取新連接
public static Connection getConnection() throws SQLException {
Connection conn = tl.get();
return (conn != null) ? conn : ds.getConnection();
}
// 開啟事務
public static void beginTransaction() throws SQLException {
if (tl.get() != null) throw new SQLException("事務已開啟");
Connection conn = ds.getConnection();
conn.setAutoCommit(false);
tl.set(conn);
}
// 提交事務
public static void commitTransaction() throws SQLException {
Connection conn = tl.get();
if (conn == null) throw new SQLException("無事務可提交");
conn.commit();
conn.close();
tl.remove();
}
// 回滾事務
public static void rollbackTransaction() throws SQLException {
Connection conn = tl.get();
if (conn == null) throw new SQLException("無事務可回滾");
conn.rollback();
conn.close();
tl.remove();
}
// 釋放連接:區分事務連接與普通連接
public static void releaseConnection(Connection conn) throws SQLException {
Connection txConn = tl.get();
if (txConn == null) { // 無事務 → 直接關閉
conn.close();
} else if (txConn != conn) { // 有事務但非事務連接 → 關閉
conn.close();
} // 否則為事務連接,暫不關閉,待 commit/rollback 統一處理
}
}
| 版本 | 核心組件 | 事務支援 | 適用場景 |
|---|---|---|---|
| v1 | DriverManager + Properties | 無 | 簡單工具/測試 |
| v2 | C3P0 ComboPooledDataSource | 無(需手動管理 Connection) | 一般 Web 應用 |
| v3 | C3P0 + ThreadLocal | 完整(begin/commit/rollback) | 企業級業務系統 |