關系數(shù)據(jù)庫映射(行為模式之工作單元)
[問題域]
正常情況下,如果使用Data Mapper解決了Domain對象和數(shù)據(jù)庫分離的目的,使用時,如果每當一個Domain對象創(chuàng)建、修改或刪除時,最簡單的方式就是立即對數(shù)據(jù)庫進行更新操作,但是這樣會對數(shù)據(jù)庫產(chǎn)生大量的調(diào)用動作。如果不這樣做,就必須記錄下Domain對象的各種修改動作,以保證最后提交時,對數(shù)據(jù)庫進行相應的更新,保持Domain對象和數(shù)據(jù)庫的一致性。
[解決方案]
找一個處所保存Domain對象的各種變化,最后提交時,就知道應該要做什么修改,并最終寫入數(shù)據(jù)庫。而這個處所可以稱之為工作單元(Unit of work),使用這種方式被命令為工作單元模式(參考[Martin Fowler企業(yè)架構模式])。
工作單元模式(Unit of work)
根據(jù)以上描述可知,工作單元模式包括兩個主要方面:
1. 記錄操作過的各種Domain對象
2. 同步到數(shù)據(jù)庫中

我們先來看看如何記錄操作過的各種Domain對象。
1.由調(diào)用者注冊。比如:調(diào)用者創(chuàng)建一個Domain對象時,同時通知工作單元,執(zhí)行了更新操作。
缺點:有程序開發(fā)者主動控制,人是最靠不住的。
有點:可以主動決定是否注冊,(也就是決定把Domain更改是否寫入數(shù)據(jù)庫)
2.由Domain對象注冊。比如:Domain對象中的Create方法中比如加入通知工作單元的代碼,工作單元可以作為參數(shù)傳入,或者固定的地方可以獲取(如ThreadLocal保存)。
缺點:也是需要由人在各個Domain對象的各種操作中加入固定通知工作單元代碼。
優(yōu)點:當然具有一致性,同時就可以采用AOP的思想統(tǒng)一操作(比如Proxy,Minxin等)
3.工作單元控制器。總的思路是,工作單元控制所有的讀操作,讀取對象的時候,對它進行注冊為Clean的,并產(chǎn)生一個拷貝,提交時,對比一下哪些字段進行了改變,然后再更新。對于不想拷貝的對象則需要主動進行注冊。(TOPLink使用此方式)
缺點:不需要拷貝的對象需要主動注冊,否則一律拷貝一個。
優(yōu)點:對Domain對象的改變只進行了有選擇的更新。
接下來討論工作單元同步到數(shù)據(jù)庫的問題:
1.更新順序
如果數(shù)據(jù)庫允許,只在事務提交時檢查引用完整性,而不是每次SQL都檢查,則隨便怎么用都可以。如果數(shù)據(jù)庫不允許,則在工作單元中則根據(jù)元數(shù)據(jù)(metadata)指定的順序執(zhí)行更新數(shù)據(jù)庫的操作。
2.批量更新
如果有一些列的更新,刪除或新增操作,則可以在工作單元中,作為一個單條語句發(fā)送請求。
[結論]
工作單元最大的好處就是把各種復雜的操作保存在一個固定的地方。這種模式可以應用于所謂有類似需求的地方。
參考資料:
Patterns of Enterprise Application Architecture (author:Martin Fowler)