首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

JDBC 連接 MySQL 完整教程:從環境配置到 CRUD 實戰

     編輯:Java 綜合教學

JDBC 核心概念

JDBC(Java Database Connectivity)是 Java 存取關聯式資料庫的標準 API,定義了統一介面,屏蔽底層驅動差異。核心四大物件:

  • Driver:資料庫廠商實現的驅動程式(如 com.mysql.cj.jdbc.Driver)
  • Connection:資料庫連線會話,管理事務
  • Statement / PreparedStatement:執行靜態/參數化 SQL
  • ResultSet:結果集游標,逐行讀取資料

環境準備(MySQL 8.0+ 為例)

1. 新增 Maven 依賴

<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId> <!-- 8.0+ 套件名變更 -->
    <version>8.0.33</version>
</dependency>

或 Gradle:implementation 'com.mysql:mysql-connector-j:8.0.33'。舊版 mysql-connector-java 已停止維護。

2. MySQL 伺服器配置

-- 建立資料庫
CREATE DATABASE IF NOT EXISTS jdbc_demo CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 建立測試表
USE jdbc_demo;
CREATE TABLE IF NOT EXISTS student (
    sno CHAR(7) PRIMARY KEY COMMENT '學號',
    sname VARCHAR(20) NOT NULL COMMENT '姓名',
    sex CHAR(2) COMMENT '性別',
    bdate DATE COMMENT '出生日期',
    height DECIMAL(5,2) DEFAULT 0 COMMENT '身高'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 插入測試資料
INSERT INTO student VALUES 
('0104421', '周遠行', '男', '1990-01-15', 175.50),
('0208123', '王義平', '女', '1991-03-22', 162.00),
('0309120', '何問起', '男', '1992-07-08', 180.00);

3. 連線 URL 參數詳解

jdbc:mysql://localhost:3306/jdbc_demo?
    useSSL=false&                    # 開發環境關閉 SSL
    serverTimezone=Asia/Taipei&      # 時區設定,避免時間偏移
    allowPublicKeyRetrieval=true&    # 允許公開金鑰獲取(MySQL 8 預設 caching_sha2_password)
    characterEncoding=utf-8&         # 字元編碼
    useUnicode=true&                 # 使用 Unicode
    autoReconnect=true&              # 自動重連
    failOverReadOnly=false           # 讀寫分離配置

標準 JDBC 程式碼範本(Try-with-Resources 自動關閉資源)

public class JdbcDemo {
    private static final String URL = "jdbc:mysql://localhost:3306/jdbc_demo?useSSL=false&serverTimezone=Asia/Taipei";
    private static final String USER = "root";
    private static final String PASSWORD = "your_password";

    public static void main(String[] args) {
        String sql = "SELECT sno, sname, sex, bdate, height FROM student";

        // 1. 獲取連線  2. 建立 Statement  3. 執行查詢  4. 處理結果集
        // Try-with-resources 確保連線、Statement、ResultSet 自動關閉(JDK 7+)
        try (Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery(sql)) {

            System.out.println("連線成功!查詢結果:");
            System.out.printf("%-10s %-10s %-4s %-12s %s%n", "學號", "姓名", "性別", "出生日期", "身高");
            System.out.println("--------------------------------------------------");

            while (rs.next()) { // 游標向下移動
                String sno = rs.getString("sno");
                String sname = rs.getString("sname");
                String sex = rs.getString("sex");
                Date bdate = rs.getDate("bdate"); // 直接獲取 java.sql.Date
                BigDecimal height = rs.getBigDecimal("height"); // 精確數值型別

                System.out.printf("%-10s %-10s %-4s %-12s %s%n", sno, sname, sex, bdate, height);
            }
        } catch (SQLException e) {
            System.err.println("資料庫操作異常:" + e.getMessage());
            e.printStackTrace();
        } // 自動關閉 rs, stmt, conn
    }
}

關鍵進階技巧

1. PreparedStatement:防 SQL 注入、效能優化

String insertSql = "INSERT INTO student (sno, sname, sex, bdate, height) VALUES (?, ?, ?, ?, ?)";
try (Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
     PreparedStatement pstmt = conn.prepareStatement(insertSql)) {

    pstmt.setString(1, "0401001");
    pstmt.setString(2, "新學生");
    pstmt.setString(3, "男");
    pstmt.setDate(4, Date.valueOf("2000-01-01")); // LocalDate -> sql.Date
    pstmt.setBigDecimal(5, new BigDecimal("170.50"));

    int affected = pstmt.executeUpdate();
    System.out.println("插入 " + affected + " 筆資料");
}

? 佔位符由驅動程式處理逸出,徹底防注入;SQL 預編譯可重複執行計畫,批次操作效能更優。

2. 批次處理:大量資料高效寫入

conn.setAutoCommit(false); // 關閉自動提交,手動控制事務
try (PreparedStatement pstmt = conn.prepareStatement(insertSql)) {
    for (int i = 0; i < 10000; i++) {
        pstmt.setString(1, String.format("%07d", i));
        pstmt.setString(2, "學生" + i);
        pstmt.setString(3, i % 2 == 0 ? "男" : "女");
        pstmt.setDate(4, Date.valueOf(LocalDate.now().minusDays(i)));
        pstmt.setBigDecimal(5, new BigDecimal(ThreadLocalRandom.current().nextDouble(150, 190)));
        pstmt.addBatch(); // 累積批次
        
        if (i % 1000 == 0) {
            pstmt.executeBatch(); // 每 1000 筆執行一次
            conn.commit();
        }
    }
    pstmt.executeBatch(); // 執行剩餘
    conn.commit();
} catch (SQLException e) {
    conn.rollback(); // 回滾
    throw e;
} finally {
    conn.setAutoCommit(true);
}

3. 事務管理:ACID 保證

Connection conn = null;
try {
    conn = DriverManager.getConnection(URL, USER, PASSWORD);
    conn.setAutoCommit(false); // 開啟事務
    
    // 業務邏輯:轉帳扣款 + 存入
    updateBalance(conn, fromAccount, -amount);
    updateBalance(conn, toAccount, +amount);
    recordTransaction(conn, fromAccount, toAccount, amount);
    
    conn.commit(); // 全部成功提交
} catch (Exception e) {
    if (conn != null) conn.rollback(); // 任一失敗回滾
    throw new RuntimeException("轉帳失敗", e);
} finally {
    if (conn != null) {
        conn.setAutoCommit(true);
        conn.close();
    }
}

4. 連線池:生產環境必備

頻繁建立/關閉物理連線開銷極大。主流連線池:

  • HikariCP:Spring Boot 2.x 預設,效能最強、配置最簡
  • Druid:阿里開源,監控功能強大,中文文檔完善
# Spring Boot application.yml (HikariCP)
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/jdbc_demo?useSSL=false&serverTimezone=Asia/Taipei
    username: root
    password: your_password
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      connection-timeout: 30000
      idle-timeout: 600000
      max-lifetime: 1800000

常見坑與解決方案

問題原因解決
ClassNotFoundException驅動 JAR 未在 ClasspathMaven/Gradle 正確引入依賴
Communications link failureIP/Port 錯誤、防火牆、MySQL bind-address檢查 3306 開放、MySQL 配置 bind-address=0.0.0.0
Public Key Retrieval is not allowedMySQL 8 預設 caching_sha2_passwordURL 加 allowPublicKeyRetrieval=true 或改用 mysql_native_password
時區錯誤伺服器/客戶端時區不一致URL 加 serverTimezone=Asia/Taipei
中文亂碼字元編碼不匹配URL 加 characterEncoding=utf-8&useUnicode=true,資料庫表 utf8mb4
資源洩漏未關閉 Connection/Statement/ResultSet統一使用 Try-with-Resources 或連線池

總結

JDBC 是 Java 資料存取的基石,掌握 DriverManager、Connection、PreparedStatement、ResultSet 核心 API、事務控制、批次處理與連線池配置,即可構建健壯的資料存取層。實際專案中強烈建議使用 MyBatis 或 JPA/Hibernate 等 ORM 框架進一步提升開發效率,但理解 JDBC 底層原理對於除錯、效能調優、解決框架無法覆蓋的邊界場景至關重要。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved