企業資訊系統的核心資產是資料。無論系統規模大小,資料的建立、檢索、更新、刪除(CRUD)都必須在長期穩定、可擴展、可維護的架構下執行。J2EE 提供了兩種主要資料管理策略:Java 物件序列化與JDBC。雖然兩者各有適用場景,但在企業級系統中,JDBC 幾乎是毫無懸念的首選。本文將深入剖析兩者優劣,揭示 JDBC 勝出的關鍵原因。
序列化將物件圖(含繼承、關聯、聚合關係)扁平化為位元組流寫入持久存儲。實作極簡:類別僅需實作 java.io.Serializable 標記介面,選擇性覆寫 writeObject()/readObject() 自訂儲存邏輯。
public class MySerializableObject extends MySuperClass implements Serializable {
private String property1, property2;
// getter/setter...
private void writeObject(ObjectOutputStream out) throws IOException {
out.writeObject(getProperty1());
out.writeObject(getProperty2());
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
setProperty1((String)in.readObject());
setProperty2((String)in.readObject());
}
}
transient 或自訂序列化邏輯writeUnshared()/readUnshared() 支援獨立序列化(類似低成本克隆)| 缺陷 | 影響 |
|---|---|
| 位元組流僅 Java 可讀 | 異構系統無法共享資料,企業整合受阻 |
| 檢索需完整反序列化 | 大量 I/O 開銷,效能低落 |
| 缺乏查詢語言 | 無法按條件檢索部分資料 |
| 無內建安全機制 | 資料保護薄弱 |
| 無交易控制 | 併發存取需額外 API 支援 |
JDBC 提供統一 API 以 Java 程式語言操作資料庫,將 SQL 指令整合進通用程式環境。其豐富的例程集合讓介面極度簡單直觀。
Class.forName(driver); Connection conn = DriverManager.getConnection(url);Statement:連線上的通道,發送一或多條 SQLPreparedStatement:預編譯 SQL,參數化查詢,重複執行無需重複編譯優化,效能顯著提升executeUpdate()executeQuery() 回傳 ResultSet,支援游標導航、可捲動/可更新模式// PreparedStatement 範例
PreparedStatement ps = con.prepareStatement(
"UPDATE Sells SET price = ? WHERE bar = ? AND beer = ?");
ps.setFloat(1, 2.5f); ps.setString(2, "Bar"); ps.setString(3, "Beer");
ps.executeUpdate();
// 查詢與 ResultSet 處理
ResultSet rs = stmt.executeQuery("SELECT * FROM Sells");
while (rs.next()) {
System.out.println(rs.getString("bar") + " sells " + rs.getString("beer")
+ " for " + rs.getFloat("price") + " Dollars.");
}
con.setAutoCommit(false); // 關閉自動提交
try {
// 多條 SQL 操作...
con.commit(); // 顯式提交
} catch (Exception e) {
con.rollback(); // 回滾
}
支援隔離等級設定(TRANSACTION_READ_COMMITTED 等),結合 Java 異常處理提供資料完整性保障。
提供 SQLException(致命)與 SQLWarning(非致命)兩層錯誤模型,可從 Connection、Statement、ResultSet 取得警告鏈。
Statement stmt = conn.createStatement();
stmt.addBatch("DELETE FROM Users");
stmt.addBatch("INSERT INTO Users VALUES('rod', 37, 'circle')");
stmt.addBatch("INSERT INTO Users VALUES('jane', 33, 'triangle')");
int[] counts = stmt.executeBatch(); // 一次網路往返執行多條 SQL
大幅減少網路往返,提升大量資料操作效能與程式碼可讀性。
CallableStatement cs = con.prepareCall("{call SHOW_ACCOUNT(?)}");
cs.setInt(1, myAccountNumber);
ResultSet rs = cs.executeQuery(); // 直接複用資料庫端編譯邏輯
支援 IN/OUT/INOUT 參數,將業務邏輯下推資料庫層,效能更優。
| 維度 | Java 序列化 | JDBC |
|---|---|---|
| 儲存介質 | 檔案系統 | EAI/資料庫(DBMS 管理) |
| 資料結構 | 物件圖 | 關聯式/階層式/網狀(邏輯視圖為表) |
| 資料定義 | 可序列化類別 | 資料表結構、域級關聯 |
| 資料檢索 | 反序列化 + 存取子 | SQL 子語言 + JDBC API |
| 安全性 | 依賴 OS 檔案權限 | DBMS 完整認證授權體系 |
| 交易控制 | 無(需 JTA/JTS) | 內建提交/回滾/隔離等級 |
| 併發控制 | 無(需 synchronized) | 多層隔離等級可選 |
Java 序列化適合:JVM 間傳遞 Java 專用格式資料(如 RMI 傳值)。
JDBC適合:企業級系統——異構環境、共享資料、需查詢/交易/安全/併發控制的場景。
為在企業環境高效使用 JDBC,架構師應:
JDBC 作為 JVM 與 DBMS 間的膠水,提供了存取異構資料源的統一介面,是 Java 平台企業級資料持久化的基石選擇。