首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> DB2 資料庫 >> DB2 教學

JDBC 核心概念與實戰範例完整指南

     編輯:DB2 教學

JDBC 核心概念與實戰範例完整指南

Java Database Connectivity (JDBC) 是 Java 存取資料庫的標準 API,提供了一組統一的介面讓開發者能以純 Java 程式碼操作各類關聯式資料庫。無論是 MySQL、Oracle、PostgreSQL 還是 SQL Server,只要有對應的 JDBC 驅動程式,即可使用相同的程式設計模式進行連線、查詢、更新與事務控制。

一、JDBC 是什麼?

JDBC 代表 Java Database Connectivity,是 Sun 公司(現 Oracle)制定的一套標準介面,屬於 java.sql 與 javax.sql 套件。其核心任務包含:

  • 建立資料庫連線
  • 建立 SQL 或 MySQL 陳述式
  • 在資料庫中執行查詢或更新操作
  • 檢視與修改記錄

二、使用 JDBC 的必要條件

在撰寫 JDBC 程式前,需確認以下資訊:

  • 目標資料庫主機位址(IP 或主機名)
  • 資料庫服務監聽的連接埠號(MySQL 預設 3306)
  • 登入資料庫的使用者名稱
  • 對應的密碼
  • 目標資料庫名稱

三、JDBC 技術原理:介面與實作分離

不同資料庫廠商的通訊協定、儲存格式各異,若開發者需為每種資料庫撰寫專屬程式碼,成本極高。JDBC 採用「介面標準化、實作由廠商提供」的設計:

  • Sun 定義標準介面(Connection、Statement、ResultSet 等)
  • 各資料庫廠商提供實作這些介面的 JDBC 驅動程式(JAR 檔)
  • 開發者僅針對標準介面撰寫程式碼,切換資料庫只需換驅動 JAR 與連線 URL

四、JDBC 核心 API 概覽

介面/類別關鍵方法說明
Driverconnect(url, props)驅動程式介面,建立連線
ConnectioncreateStatement()
prepareStatement(sql)
prepareCall(sql)
setAutoCommit(boolean)
commit()/rollback()
資料庫連線物件,管理事務
StatementexecuteQuery(sql)
executeUpdate(sql)
執行靜態 SQL 陳述式
PreparedStatementsetInt(idx, val)
setString(idx, val)
executeQuery()
executeUpdate()
預編譯 SQL,支援參數綁定,防 SQL 注入
CallableStatementexecuteQuery()呼叫預存程序
ResultSetnext()
getInt(col)
getString(col)
getObject(col)
查詢結果集,游標式逐列讀取

五、建立 JDBC 應用程式的標準步驟

  1. 導入套件:import java.sql.*;
  2. 註冊驅動程式:Class.forName("com.mysql.cj.jdbc.Driver");(JDBC 4.0+ 可略過,自動載入)
  3. 取得連線:Connection conn = DriverManager.getConnection(url, user, pass);
  4. 建立 Statement:Statement stmt = conn.createStatement(); 或 PreparedStatement
  5. 執行 SQL:查詢用 executeQuery(),增刪改用 executeUpdate()
  6. 處理結果:透過 ResultSet.next() 迴圈搭配 getXxx() 取值
  7. 釋放資源:依序關閉 ResultSet、Statement、Connection(建議用 try-with-resources)

六、完整實戰範例:從基礎到工具類封裝

1. 基礎範例:建表、插入、查詢

package com.example.jdbc;
import java.sql.*;

public class JdbcDemo {
    private static final String URL  = "jdbc:mysql://localhost:3306/school?useSSL=false&serverTimezone=UTC";
    private static final String USER = "root";
    private static final String PASS = "your_password";

    public static void main(String[] args) {
        String ddl  = "CREATE TABLE IF NOT EXISTS student (sid INT PRIMARY KEY, sname VARCHAR(20), age INT)";
        String insert = "INSERT INTO student VALUES (?, ?, ?)";
        String query  = "SELECT sid, sname, age FROM student";

        try (Connection conn = DriverManager.getConnection(URL, USER, PASS);
             Statement stmt = conn.createStatement()) {

            stmt.executeUpdate(ddl);               // 建表
            try (PreparedStatement ps = conn.prepareStatement(insert)) {
                ps.setInt(1, 100); ps.setString(2, "小文"); ps.setInt(3, 18); ps.executeUpdate();
                ps.setInt(1, 101); ps.setString(2, "大林"); ps.setInt(3, 25); ps.executeUpdate();
            }
            try (ResultSet rs = stmt.executeQuery(query)) {
                while (rs.next()) {
                    System.out.printf("sid: %d  sname: %s  age: %d%n",
                            rs.getInt("sid"), rs.getString("sname"), rs.getInt("age"));
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

2. 進階封裝:資料庫工具類

將重複的連線建立、資源關閉邏輯抽取為工具類,並改用 PreparedStatement 防注入、提升效能:

package com.example.util;
import java.sql.*;

public final class DBUtil {
    private static final String DRIVER = "com.mysql.cj.jdbc.Driver";
    private static final String URL    = "jdbc:mysql://localhost:3306/school?useSSL=false&serverTimezone=UTC";
    private static final String USER   = "root";
    private static final String PASS   = "your_password";

    static { try { Class.forName(DRIVER); } catch (ClassNotFoundException e) { throw new ExceptionInInitializerError(e); } }

    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(URL, USER, PASS);
    }

    public static void close(AutoCloseable... resources) {
        for (AutoCloseable r : resources) {
            if (r != null) try { r.close(); } catch (Exception ignored) {}
        }
    }
}

3. 業務操作類:CRUD 封裝

package com.example.dao;
import com.example.util.DBUtil;
import java.sql.*;

public class StudentDao {
    public void createTable() {
        String sql = "CREATE TABLE IF NOT EXISTS student (sid INT PRIMARY KEY, sname VARCHAR(20), age INT)";
        try (Connection conn = DBUtil.getConnection();
             PreparedStatement ps = conn.prepareStatement(sql)) {
            ps.executeUpdate();
        } catch (SQLException e) { e.printStackTrace(); }
    }

    public void insert(int id, String name, int age) {
        String sql = "INSERT INTO student VALUES (?, ?, ?)";
        try (Connection conn = DBUtil.getConnection();
             PreparedStatement ps = conn.prepareStatement(sql)) {
            ps.setInt(1, id); ps.setString(2, name); ps.setInt(3, age);
            ps.executeUpdate();
        } catch (SQLException e) { e.printStackTrace(); }
    }

    public void findById(int id) {
        String sql = "SELECT sid, sname, age FROM student WHERE sid = ?";
        try (Connection conn = DBUtil.getConnection();
             PreparedStatement ps = conn.prepareStatement(sql);
             ResultSet rs = ps.executeQuery()) {
            ps.setInt(1, id);
            while (rs.next()) {
                System.out.printf("sid: %d  sname: %s  age: %d%n",
                        rs.getInt("sid"), rs.getString("sname"), rs.getInt("age"));
            }
        } catch (SQLException e) { e.printStackTrace(); }
    }
}

七、Statement vs PreparedStatement 關鍵差異

比較項目StatementPreparedStatement
SQL 形式靜態字串拼接預編譯,使用 ? 佔位符
效能每次解析、編譯、優化預編譯一次,多次執行僅傳參數,資料庫端可快取執行計畫
安全性易遭 SQL 注入攻擊參數化查詢,自動處理跳脫字元,防注入
建議僅適合極簡單、無參數的一次性查詢生產環境首選
SQL 注入範例
Statement 拼接:"SELECT * FROM users WHERE name='" + input + "'"
惡意輸入:' OR '1'='1 → 繞過驗證。
PreparedStatement 會將參數視為純資料,不會被解析為 SQL 片段。

八、JDBC 核心類別速查表

  • DriverManager:getConnection(url, user, pass) 取得連線
  • Connection:createStatement()、prepareStatement(sql)、setAutoCommit(false)、commit()、rollback()
  • Statement:executeQuery(sql) 回傳 ResultSet,executeUpdate(sql) 回傳影響列數
  • ResultSet:next() 移動游標,getString(col)、getInt(col)、getObject(col) 取值

總結:JDBC 雖屬基礎 API,但掌握其核心流程、資源管理與 PreparedStatement 最佳實踐,是所有 Java 持久層框架的基石。實務上建議搭配連線池與 Spring JDBC Template 等高階封裝,進一步簡化程式碼並提升穩定度。

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