JDBC (Java Database Connectivity) 是 Java 操作關係資料庫的標準 API。本文以 MySQL 為例,從驅動下載與模組化依賴、DriverManager 基礎連線、Druid/HikariCP 連接池整合、PreparedStatement 防注入 CRUD 範本、try-with-resources 資源管理 五大維度,提供可直接落地的完整代碼。
<dependencies>
<!-- MySQL 驅動 8.0+ -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.3.0</version>
</dependency>
<!-- 連接池:HikariCP (Spring Boot 預設) -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>5.1.0</version>
</dependency>
</dependencies>
MySQL 8.0+ 驅動類為com.mysql.cj.jdbc.Driver,舊版com.mysql.jdbc.Driver已棄用但仍兼容。
public class JdbcQuickStart {
private static final String URL = "jdbc:mysql://localhost:3306/students?useSSL=false&serverTimezone=Asia/Taipei&characterEncoding=UTF-8";
private static final String USER = "root";
private static final String PASS = "";
public static void main(String[] args) {
try {
// 1. 載入驅動 (JDBC 4.0+ SPI 自動載入,可省略)
Class.forName("com.mysql.cj.jdbc.Driver");
System.out.println("驅動載入成功");
// 2. 建立連線
try (Connection conn = DriverManager.getConnection(URL, USER, PASS)) {
System.out.println("資料庫連線成功: " + conn.getMetaData().getURL());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class DataSourceUtil {
private static final HikariDataSource ds = new HikariDataSource();
static {
ds.setJdbcUrl("jdbc:mysql://localhost:3306/students?useSSL=false&serverTimezone=Asia/Taipei");
ds.setUsername("root");
ds.setPassword("");
ds.setMaximumPoolSize(20);
ds.setMinimumIdle(5);
ds.setConnectionTimeout(30000);
ds.setIdleTimeout(600000);
ds.setMaxLifetime(1800000);
ds.setPoolName("MyPool");
}
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
public static void close() { ds.close(); }
}
DruidDataSource ds = new DruidDataSource();
ds.setUrl(...); ds.setUsername(...); ds.setPassword(...);
ds.setInitialSize(5); ds.setMaxActive(20);
ds.setFilters("stat,wall,log4j2"); // 監控、防注入、日誌
ds.setWebStatFilterEnabled(true);
ds.setStatViewServletEnabled(true);
public class UserDao {
public void insert(User u) {
String sql = "INSERT INTO users(username, password, email) VALUES(?,?,?)";
try (Connection conn = DataSourceUtil.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, u.getUsername());
ps.setString(2, u.getPassword());
ps.setString(3, u.getEmail());
ps.executeUpdate();
} catch (SQLException e) { throw new RuntimeException(e); }
}
public User findById(int id) {
String sql = "SELECT id, username, email FROM users WHERE id=?";
try (Connection conn = DataSourceUtil.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setInt(1, id);
try (ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
User u = new User();
u.setId(rs.getInt("id"));
u.setUsername(rs.getString("username"));
u.setEmail(rs.getString("email"));
return u;
}
}
} catch (SQLException e) { throw new RuntimeException(e); }
return null;
}
public List<User> findAll() {
String sql = "SELECT id, username, email FROM users";
List<User> list = new ArrayList<>();
try (Connection conn = DataSourceUtil.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
User u = new User();
u.setId(rs.getInt("id"));
u.setUsername(rs.getString("username"));
u.setEmail(rs.getString("email"));
list.add(u);
}
} catch (SQLException e) { throw new RuntimeException(e); }
return list;
}
public void updateEmail(int id, String newEmail) {
String sql = "UPDATE users SET email=? WHERE id=?";
try (Connection conn = DataSourceUtil.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, newEmail);
ps.setInt(2, id);
ps.executeUpdate();
} catch (SQLException e) { throw new RuntimeException(e); }
}
public void deleteById(int id) {
String sql = "DELETE FROM users WHERE id=?";
try (Connection conn = DataSourceUtil.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setInt(1, id);
ps.executeUpdate();
} catch (SQLException e) { throw new RuntimeException(e); }
}
}
AutoCloseable,異常時也能確實釋放。close() 後再用:已關閉的物件操作會拋 SQLException。ds.getConnection() 後必在 finally/try-with 歸還,否則洩漏導致池耗盡。setXxx,拼接 SQL 者封專案。addBatch/executeBatch:大量寫入效能提升 10x+。conn.setAutoCommit(false) → 操作 → conn.commit() / conn.rollback(),最後 conn.setAutoCommit(true)。JDBC 核心就三件事:**載入驅動、獲取連線、執行 SQL**。掌握 DriverManager 基礎流程、連接池配置、PreparedStatement 參數化、try-with-resources 鐵律,即能寫出正確、高效、安全的資料庫存取代碼。生產環境**務必上連接池 (HikariCP/Druid)**,並配合監控指標 (活躍連線、等待時間、洩漏檢測) 觀測池健康度。