傳統方案:
物件資料庫:直接儲存物件,零映射。早期產品配置複雜、非原生語言綁定、市場佔有率低。
嵌入式資料庫 (SQLite 等):仍基於 SQL,阻抗失配依存。
.yap)public class Player {
protected String name; int squadNumber; float battingAverage; Team team;
// 建構子、getter/setter、toString() 略
}
public class Pitcher extends Player {
private int wins;
// 建構子、getter/setter、toString() 略
}
public class Team {
private String name, city; int won, lost;
private List<Player> players = new ArrayList<>();
// getter/setter、addPlayer()、toString() 略
}
Player p1 = new Player("Barry Bonds", 25, 0.362f);
Player p7 = new Pitcher("Kirk Rueter", 46, 0.131f, 9);
// ... 建立更多球員與投手
Team t1 = new Team("Giants", "San Francisco", 91, 71);
t1.addPlayer(p1); p1.setTeam(t1);
// ... 建立雙向關聯
ObjectContainer db = Db4o.openFile("baseball.yap");
db.set(t1); // 遞迴儲存整個物件圖 (Team → Players → Team)
// 查詢特定球員
Player probe = new Player("Barry Bonds", 0, 0f);
ObjectSet result = db.get(probe);
// 查詢所有球員 (空原型)
Player emptyProbe = new Player(null, 0, 0f);
ObjectSet all = db.get(emptyProbe); // 回傳 8 筆,含 Pitcher 子類與額外 wins 欄位
自動處理繼承:查詢父類自動包含子類實例,所有欄位完整保留——關係資料庫需額外表/連接才能達成。
// 更新
Player probe = new Player("Shawn Green", 0, 0f);
Player p = (Player) db.get(probe).next();
p.setBattingAverage(0.299f);
db.set(p); // 重新儲存
// 刪除
Player probe = new Player("Ray Durham", 0, 0f);
Player p = (Player) db.get(probe).next();
db.delete(p);
// 查詢打擊率 > 0.3
Query q = db.query();
q.constrain(Player.class);
q.descend("battingAverage").constrain(new Float(0.3f)).greater();
ObjectSet result = q.execute(); // 2 筆
// 導航關聯:取得球員所屬球隊
while (result.hasNext()) {
Player p = (Player) result.next();
System.out.println(p + " -> " + p.getTeam());
}
// 輸出:Adrian Beltre -> Dodgers, Barry Bonds -> Giants
// 排序
q.descend("battingAverage").orderAscending();
// 多條件 AND:打擊率 > 0.13 AND 勝投數 > 5
Constraint c1 = q.descend("battingAverage").constrain(new Float(0.13f)).greater();
q.descend("wins").constrain(new Integer(5)).greater().and(c1);
// 跨類導航:打擊率 > 0.3 AND 所屬球隊勝場 > 92
Constraint c2 = q.descend("battingAverage").constrain(new Float(0.3f)).greater();
q.descend("team").descend("won").constrain(new Integer(92)).greater().and(c2);
查詢圖導航:沿著物件關聯路徑 (team.won) 施加條件,直觀對應領域模型,無需考慮表連接策略。
| 維度 | db4o | 關係資料庫 + ORM |
|---|---|---|
| 映射配置 | 零 | XML/註解 |
| 繼承處理 | 自動透明 | 多種策略需權衡 |
| 關聯導航 | 記憶體中一致,零成本 | 需 JOIN 或延遲載入 |
| 查詢語言 | SODA (物件導向) | SQL/HQL/JPQL |
| 部署體積 | 250 KB + 單一檔案 | 完整資料庫伺服器 |
| 適用場景 | 嵌入式、桌面、中小型企業、教學 | 大型企業級、高併發、複雜報表 |
db4o 以極簡部署、零映射、原生物件查詢重新定義輕量級持久化。無論商業嵌入式系統 (BMW 車載、PDA 公用事業、醫療影像) 或教學環境,都是極具吸引力的選擇。理解物件資料庫範式,能拓寬架構選型視野,在適合場景下大幅降低開發與維護成本。