JDBC 連接 MySQL 完整範例:DriverManager、Connection、PreparedStatement
Java 透過 JDBC API 連接 MySQL 的標準範例,涵蓋驅動載入、連線建立、參數化查詢、資源關閉與 Maven 依賴管理。
Maven 依賴 (MySQL Connector/J 8.0+)
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.33</version>
</dependency>
舊版 (5.1.x):`mysql:mysql-connector-java:5.1.49`,驅動類 `com.mysql.jdbc.Driver`
完整程式碼範例
import java.sql.*;
public class MySQLJdbcDemo {
// 連線配置 (建議外部化至配置檔)
private static final String URL = "jdbc:mysql://127.0.0.1:3306/test?useSSL=false&serverTimezone=UTC&characterEncoding=utf8";
private static final String USER = "root";
private static final String PASS = "0000";
public static void main(String[] args) {
// 1. 載入驅動 (JDBC 4.0+ SPI 自動載入,可省略)
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
throw new RuntimeException("MySQL 驅動未找到", e);
}
// 2. 建立連線 (try-with-resources 自動關閉)
try (Connection conn = DriverManager.getConnection(URL, USER, PASS)) {
System.out.println("資料庫連線成功!");
// 3. 參數化插入 (防止 SQL Injection)
String insertSql = "INSERT INTO stu (id, name) VALUES (?, ?)";
try (PreparedStatement ps = conn.prepareStatement(insertSql)) {
ps.setInt(1, 12);
ps.setString(2, "Shara");
int rows = ps.executeUpdate();
System.out.println("插入行數: " + rows);
}
// 4. 查詢示範
String querySql = "SELECT id, name FROM stu WHERE id = ?";
try (PreparedStatement ps = conn.prepareStatement(querySql)) {
ps.setInt(1, 12);
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
System.out.printf("ID: %d, Name: %s%n", rs.getInt("id"), rs.getString("name"));
}
}
}
} catch (SQLException e) {
System.err.println("資料庫操作失敗: " + e.getMessage());
e.printStackTrace();
}
}
}
關鍵最佳實務
| 實務 | 說明 | 範例 |
| 連線池 | 生產環境必須使用 (HikariCP/Druid) | `HikariDataSource` 配置 |
| 參數化查詢 | 防 SQL Injection、提升計畫重用 | `PreparedStatement` + `setXxx` |
| try-with-resources | 自動關閉 Connection/Statement/ResultSet | Java 7+ 語法 |
| 時區設定 | 避免時區不一致導致時間偏移 | `serverTimezone=UTC` 或 `Asia/Taipei` |
| SSL 設定 | 內網可關閉,外網建議開啟 | `useSSL=false` / `useSSL=true` |
| 字元集 | 統一 utf8mb4 | `characterEncoding=utf8` (驅動自動對應 utf8mb4) |
連線池配置範例
# application.properties (Spring Boot)
spring.datasource.url=jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=Asia/Taipei
spring.datasource.username=root
spring.datasource.password=0000
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.idle-timeout=300000
spring.datasource.hikari.connection-timeout=20000
常見錯誤排查
| 錯誤 | 原因 | 解決 |
| ClassNotFoundException: com.mysql.cj.jdbc.Driver | 缺少 connector-j 依賴 | 加入 Maven 依賴、檢查打包是否包含 |
| Communications link failure | IP/Port/防火牆/bind-address | 檢查 3306 通達性、my.cnf bind-address=0.0.0.0 |
| Public Key Retrieval is not allowed | 8.0 新認證需公開金鑰 | URL 加 `allowPublicKeyRetrieval=true` 或用 `mysql_native_password` |
| Server returns invalid timezone | 時區 ID 不識別 | 設定 `serverTimezone=UTC` 或具體時區 `Asia/Taipei` |
| Zero date value prohibited | 資料含 '0000-00-00'、驅動預設拒絕 | URL 加 `zeroDateTimeBehavior=CONVERT_TO_NULL` 或清理資料 |
驅動類對照
| 版本 | Maven Artifact | Driver Class | URL 前綴 |
| 8.0+ | com.mysql:mysql-connector-j | com.mysql.cj.jdbc.Driver | jdbc:mysql:// |
| 5.1.x | mysql:mysql-connector-java | com.mysql.jdbc.Driver | jdbc:mysql:// |