作為一門新興語言,Java 定義了標準運行環境,用戶自定義類在其中執行,其實例代表真實世界的數據——無論存儲於數據庫、文件系統,還是大型事務處理系統中。然而,數據訪問技術因數據源類型不同而異,程序員被迫掌握 Java 語言與特定數據源的訪問語言(如 SQL),雙重學習成本極大地增加了開發負擔。
將對象狀態及引用圖寫入輸出流,雖能保證對象關係完整重構,但不支持事務、查詢、多用戶共享,僅適用於最簡單應用或無數據庫支持的嵌入式系統。
要求開發者顯式處理字段並映射到關係表。開發者需同時面對 Java 對象模型與 SQL 關係模型,映射複雜導致多數人放棄對象建模,退回到過程式編程,無法享受面向對象優勢。
雖支持分布式對象計算,但架構複雜、資源消耗大。JDO 設計更靈活,可作為 EJB 底層存儲實現,若不需分布式特性,JDO 是輕量級替代方案。典型用法是讓 Session Bean 直接訪問 JDO 對象,避免 Entity Bean 開銷。
JDO 規範了運行環境與可持久化類之間的約定,支持多種數據源。開發者只需設計 Java 對象模型,由 JDO 負責存儲,僅處理單一信息模型。JDO 建立在 JDBC 之上,提供更簡單的存儲接口,而非取代 JDBC。相比 EJB CMP,JDO 無需學習龐大體系,建模限制更少,可運行於受控或非受控環境,部署靈活性極高。
以虛構公司 Media Mania 為例,其全美門店出租銷售娛樂音像產品,終端機提供影片與演員信息。核心領域模型包含三個實體:
一個電影可含多個角色,一個演員可在不同電影飾演不同角色,甚至同部電影飾演多角。
JDO 要求持久化類必須提供無參構造器(可為 private)。屬性可聲明為 private,無需強制 getter/setter,支持標準 Java 類型(String、Date、int 等)及集合關係。以下為 Movie 類完整實現:
package com.mediamania.prototype;
import java.util.Set;
import java.util.HashSet;
import java.util.Collections;
import java.util.Date;
import java.util.Calendar;
import java.text.SimpleDateFormat;
import java.text.ParsePosition;
public class Movie {
private static SimpleDateFormat yearFmt = new SimpleDateFormat("yyyy");
public static final String[] MPAAratings = {"G", "PG", "PG-13", "R", "NC-17", "NR"};
private String title;
private Date releaseDate;
private int runningTime;
private String rating;
private String webSite;
private String genres;
private Set cast; // element type: Role
private Movie() {} // JDO 要求的無參構造器
public Movie(String title, Date release, int duration, String rating, String genres) {
this.title = title;
releaseDate = release;
runningTime = duration;
this.rating = rating;
this.genres = genres;
cast = new HashSet();
}
// 業務方法非 JDO 強制,僅為編程便利
public String getTitle() { return title; }
public Date getReleaseDate() { return releaseDate; }
public String getRating() { return rating; }
public int getRunningTime() { return runningTime; }
public void setWebSite(String site) { webSite = site; }
public String getWebSite() { return webSite; }
public String getGenres() { return genres; }
public void addRole(Role role) { cast.add(role); }
public Set getCast() { return Collections.unmodifiableSet(cast); }
public static Date parseReleaseDate(String val) {
Date date = null;
try { date = yearFmt.parse(val); } catch (java.text.ParseException exc) {}
return date;
}
public String formatReleaseDate() { return yearFmt.format(releaseDate); }
}
關鍵點解析:
cast 使用 Set<Role> 表示多對多關係,JDO 自動管理關聯MPAAratings、yearFmt 不會被持久化private 防止外部誤用,符合 JDO 可移植性要求JDO 以「透明持久化」為核心,讓開發者回歸面向對象設計本質。通過標準化 API 屏蔽底層數據源差異,結合輕量級運行時,成為介於 JDBC 底層操作與 EJB 重型框架之間的最佳平衡點。對於中小型應用、嵌入式場景或需快速迭代的項目,JDO 提供了極具吸引力的生產力提升方案。