package com.runoob.test;
import java.sql.*;
public class MySQLDemo {
// JDBC 驅動與 URL
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost:3306/RUNOOB";
// 數據庫憑證
static final String USER = "root";
static final String PASS = "123456";
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try {
// 1. 註冊驅動 (JDBC 4.0+ 可省略,自動 SPI 發現)
Class.forName(JDBC_DRIVER);
// 2. 獲取連接
System.out.println("連接數據庫...");
conn = DriverManager.getConnection(DB_URL, USER, PASS);
// 3. 創建 Statement
System.out.println("實例化 Statement...");
stmt = conn.createStatement();
// 4. 執行查詢
String sql = "SELECT id, name, url FROM websites";
ResultSet rs = stmt.executeQuery(sql);
// 5. 處理結果集
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
String url = rs.getString("url");
System.out.printf("ID: %d, 站點: %s, URL: %s%n", id, name, url);
}
// 6. 關鍵:逆序關閉資源
rs.close();
stmt.close();
conn.close();
} catch (SQLException se) {
se.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 雙重保險:finally 中再次關閉
try { if (stmt != null) stmt.close(); } catch (SQLException se2) {}
try { if (conn != null) conn.close(); } catch (SQLException se) { se.printStackTrace(); }
}
System.out.println("Goodbye!");
}
}
關鍵最佳實踐
- 資源關閉順序:ResultSet → Statement → Connection(逆序創建順序)。
- finally 塊雙重關閉:防止異常導致資源洩露。
- JDBC 4.0+:可省略
Class.forName(),驅動自動加載。
- 預編譯語句:生產環境請使用
PreparedStatement 防 SQL 注入。
- 連接池:實際項目必須使用 HikariCP、Druid 等連接池。
MySQL 8.0+ 注意
- 驅動類:
com.mysql.cj.jdbc.Driver
- URL 建議添加:
?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true