exolab 開源專案 Castor 是流行的 JDO(Java Data Objects)實作,專注於 O/R Mapping,大幅減輕物件與關聯式資料庫處理負擔。支援 Client 應用與 J2EE 兩種環境。
自行管理資料庫設定與交易。透過 XML 設定檔(如 database.xml)定義連線與 Mapping。
JDO jdo = new JDO();
jdo.setDatabaseName("mydb");
jdo.setConfiguration("database.xml");
jdo.setClassLoader(getClass().getClassLoader());
Database db = jdo.getDatabase();
db.begin();
// 業務邏輯...
db.commit();
db.close();
執行緒安全:JDO 物件非執行緒安全,建議每個交易建立新 JDO 物件,JDBC 連線僅在交易中開啟一次,效能更佳。
透過 JNDI 獲取預設資料源,交易由 UserTransaction 或容器管理(CMT)。
InitialContext ctx = new InitialContext();
Database db = (Database) ctx.lookup("java:comp/env/jdo/mydb");
UserTransaction ut = (UserTransaction) ctx.lookup("java:comp/UserTransaction");
ut.begin();
// 業務邏輯...
ut.commit();
db.close();
CMT 環境下無需手動 begin/commit,容器自動管理。
成為持久物件兩途徑:1) 非唯讀查詢產生 2) create()/update() 存入。提交或回滾後持久物件自動轉回暫態。同一物件在不同資料庫連線中可同時為持久/暫態。
類似 SQL 但使用物件名稱,不支援 JOIN 子句(Castor 自動處理關聯)。參數以 $1、$2 表示。
OQLQuery oql = db.getOQLQuery("SELECT p FROM Product p WHERE Group=$1");
oql.bind(groupId);
QueryResults results = oql.execute();
while (results.hasMore()) {
Product prod = (Product) results.next();
prod.markDown(0.25);
prod.setOnSale(true);
}
db.commit();
查詢可建立一次多次執行,參數每次需重新綁定。支援呼叫預存程序:CALL sp_something($) AS myapp.Product。
結合 Castor JDO 與 Castor XML,以 XML 作為輸入/輸出處理資料庫操作。範例:帳戶轉帳流程,持久物件操作 DB,暫態 Transfer 物件記錄流程並輸出 XML:
Transfer tran = new Transfer();
Account from = oql.execute().nextElement(); // 查詢來源帳戶
Account to = oql.execute().nextElement(); // 查詢目標帳戶
if (from.getBalance() >= amount) {
from.decBalance(amount);
to.incBalance(amount);
tran.setStatus(Transfer.COMPLETE);
tran.setAccount(from);
tran.setAmount(amount);
} else {
tran.setStatus(Transfer.OVERDRAFT);
}
Marshaller.marshal(tran, outputStream); // 生成 XML
輸出 XML 範例:
<?xml version="1.0"?>
<report>
<status>Completed</status>
<account id="1234-5678-90" balance="50" />
<transfer amount="49.99" />
</report>
可再透過 XSLT 轉為 HTML 顯示。