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

Java DB (Derby) 嵌入式/客戶端/網路模式 JDBC 應用完整實戰:從零構建最簡應用到多模式部署

     編輯:Java 相關知識

Java DB 簡介與定位

Java DB 是 Sun 整合 Apache Derby 的關係資料庫,JDK 6 內建支援。特點:純 Java、零配置嵌入式、標準 JDBC/SQL、支援網路伺服器模式、開源 Apache 授權。適用於桌面應用、開發測試、輕量級伺服器、嵌入式裝置。

最簡應用程式完整原始碼 SimpleApp.java

import java.sql.*;
import java.util.Properties;

public class SimpleApp {
    // 模式配置
    public String framework = "embedded";  // embedded | derbyclient | jccjdbc
    public String driver = "org.apache.derby.jdbc.EmbeddedDriver";
    public String protocol = "jdbc:derby:";

    public static void main(String[] args) {
        new SimpleApp().go(args);
    }

    void go(String[] args) {
        parseArguments(args);
        System.out.println("SimpleApp starting in " + framework + " mode.");

        try {
            // 載入驅動:嵌入式模式同時啟動 Derby 引擎
            Class.forName(driver).newInstance();
            System.out.println("Loaded the appropriate driver.");

            Properties props = new Properties();
            props.put("user", "user1");
            props.put("password", "user1");

            // create=true 自動建立資料庫
            Connection conn = DriverManager.getConnection(protocol + "derbyDB;create=true", props);
            System.out.println("Connected to and created database derbyDB");

            conn.setAutoCommit(false);  // 手動事務控制
            Statement s = conn.createStatement();

            // 建表、增刪改查
            s.execute("CREATE TABLE derbyDB(num INT, addr VARCHAR(40))");
            System.out.println("Created table derbyDB");

            s.execute("INSERT INTO derbyDB VALUES (1956, 'Webster St.')");
            System.out.println("Inserted 1956 Webster");

            s.execute("INSERT INTO derbyDB VALUES (1910, 'Union St.')");
            System.out.println("Inserted 1910 Union");

            s.execute("UPDATE derbyDB SET num=180, addr='Grand Ave.' WHERE num=1956");
            System.out.println("Updated 1956 Webster to 180 Grand");

            s.execute("UPDATE derbyDB SET num=300, addr='Lakeshore Ave.' WHERE num=180");
            System.out.println("Updated 180 Grand to 300 Lakeshore");

            // 查詢驗證
            ResultSet rs = s.executeQuery("SELECT num, addr FROM derbyDB ORDER BY num");
            if (!rs.next() || rs.getInt(1) != 300) throw new Exception("Wrong row 1");
            if (!rs.next() || rs.getInt(1) != 1910) throw new Exception("Wrong row 2");
            if (rs.next()) throw new Exception("Extra rows");
            System.out.println("Verified the rows");

            s.execute("DROP TABLE derbyDB");
            System.out.println("Dropped table derbyDB");

            rs.close(); s.close();
            System.out.println("Closed result set and statement");

            conn.commit(); conn.close();
            System.out.println("Committed transaction and closed connection");

            // 嵌入式模式需顯式關閉引擎
            if (framework.equals("embedded")) {
                boolean gotSQLExc = false;
                try { DriverManager.getConnection("jdbc:derby:;shutdown=true"); }
                catch (SQLException se) { gotSQLExc = true; }  // 正常關閉會拋出 XJ015
                System.out.println(gotSQLExc ? "Database shut down normally" 
                                             : "Database did not shut down normally");
            }

        } catch (Throwable e) {
            System.out.println("Exception thrown:");
            if (e instanceof SQLException) printSQLError((SQLException) e);
            else e.printStackTrace();
        }
        System.out.println("SimpleApp finished");
    }

    static void printSQLError(SQLException e) {
        while (e != null) {
            System.out.println(e.toString());
            e = e.getNextException();
        }
    }

    private void parseArguments(String[] args) {
        for (String arg : args) {
            if (arg.equalsIgnoreCase("jccjdbcclient")) {
                framework = "jccjdbc";
                driver = "com.ibm.db2.jcc.DB2Driver";
                protocol = "jdbc:derby:net://localhost:1527/";
            } else if (arg.equalsIgnoreCase("derbyclient")) {
                framework = "derbyclient";
                driver = "org.apache.derby.jdbc.ClientDriver";
                protocol = "jdbc:derby://localhost:1527/";
            }
        }
    }
}

三種運行模式完整部署指南

模式一:嵌入式模式 (桌面應用整合)

# 目錄結構
C:\Java\
├── SimpleApp.java
├── run.bat
└── jar\
    └── derby.jar  (從 JDK 6 lib 或 Derby 發布包獲取)

# run.bat
set CLASSPATH=C:\Java\jar\derby.jar;%CLASSPATH%

# 編譯執行
C:\Java> run.bat
C:\Java> javac SimpleApp.java
C:\Java> java SimpleApp

產生檔案:derbyDB/ (資料庫目錄)、derby.log (引擎日誌)。不可手動修改資料庫目錄檔案。

模式二:Derby 網路伺服器 + 客戶端模式

# 1. 啟動網路伺服器 (新視窗)
# 需 derby.jar + derbynet.jar
set CLASSPATH=C:\Java\jar\derby.jar;C:\Java\jar\derbynet.jar;%CLASSPATH%
java org.apache.derby.drda.NetworkServerControl start
# 輸出: "Server ready to accept connections on port 1527"

# 2. 客戶端模式運行應用 (另一視窗)
# 需 derbyclient.jar
set CLASSPATH=C:\Java\jar\derbyclient.jar;%CLASSPATH%
java SimpleApp derbyclient

模式三:IBM DB2 JDBC Universal Driver (歷史相容)

# 需從 IBM 下載 db2jcc.jar, db2jcc_license_c.jar
set CLASSPATH=C:\Java\jar\db2jcc.jar;C:\Java\jar\db2jcc_license_c.jar;%CLASSPATH%
java SimpleApp jccjdbcclient

注意:Derby 10.1+ 內建網路客戶端驅動 (derbyclient.jar) 為推薦選擇,DB2 驅動僅為遷移相容保留。

關鍵技術細節深度解析

項目嵌入式模式客戶端/網路模式
JDBC URL 格式jdbc:derby:dbName;create=truejdbc:derby://host:1527/dbName;create=true
驅動類別org.apache.derby.jdbc.EmbeddedDriverorg.apache.derby.jdbc.ClientDriver
所需 JARderby.jarderbyclient.jar (含網路協議)
引擎進程JVM 內嵌啟動獨立 NetworkServerControl 進程
並發支援單 JVM 多執行緒 (同一資料庫)多 JVM/跨機器並發
關閉方式jdbc:derby:;shutdown=true僅關閉連接,伺服器持續運行
部署場景桌面應用、單元測試、輕量微服務開發/測試/生產共享資料庫

Derby 資料庫目錄結構解析

derbyDB/
├── seg0/           # 資料段 (表資料、索引)
│   ├── c0.dat      # 容器檔案
│   └── ...
├── log/            # 事務日誌 (WAL)
│   ├── log.ctrl
│   └── log.dat
├── service.properties  # 內部配置 (頁面大小、建立版本等)
└── tmp/            # 臨時檔案 (排序、哈希連接溢寫)

進階配置與生產化建議

  1. 系統目錄分離:System.setProperty("derby.system.home", "C:/DBdata") 統一管理多資料庫
  2. 頁面大小優化:建立時指定 ;pageSize=8192 (大物件/索引密集場景)
  3. 網路伺服器安全:derby.drda.host=0.0.0.0 (監聽所有介面)、derby.drda.sslMode=peerAuthentication (SSL)、derby.authentication.provider=BUILTIN (內建認證)
  4. 連線池整合:HikariCP / DBCP2 配置 jdbc:derby://... URL,嵌入式模式不可共享連線池
  5. 備份策略:線上備份 CALL SYSCS_UTIL.SYSCS_BACKUP_DATABASE('C:/backup')、離線備份直接複製目錄
  6. 版本升級:SYSCS_UTIL.SYSCS_UPGRADE_DATABASE() 自動遷移元資料

常見問題排查

錯誤原因解決
ClassNotFoundException: EmbeddedDriverCLASSPATH 缺少 derby.jar檢查 run.bat CLASSPATH 設定
Connection refused: connect網路伺服器未啟動/埠號錯誤/防火牆啟動 NetworkServerControl、telnet 1527
Database 'derbyDB' not foundURL 路徑錯誤/未指定 create=true確認協議前綴、主機名、資料庫名
XJ015: Derby exception during shutdown正常關閉異常 (嵌入式模式特有)捕獲忽略,視為正常關閉
中文亂碼字符集不匹配URL 加 ;territory=zh_CN、確認檔案編碼 UTF-8

總結

Java DB (Derby) 以「零安裝、純 Java、標準 SQL、多模式靈活切換」成為 Java 開發者手邊最高效的資料庫工具。本文從最簡 SimpleApp 切入,完整覆蓋嵌入式/網路客戶端/DB2 驅動三種模式的部署、配置、驗證與進階優化。掌握此技能,可在單元測試、原型驗證、桌面應用、輕量微服務、CI/CD 流水線中即時擁有功能完整的關係資料庫,無需安裝重型資料庫伺服器。

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