2011-08-09 47 views
4

我目前正在研究這個討論來的項目,我想問問他人他們對此有什麼看法。 (根據維基百科):「在計算機軟件中,數據訪問對象(DAO)是一種爲某種類型的數據庫或持久性機制提供抽象接口的對象,提供了一些特定的操作而不暴露細節的數據庫。「。ORM和DAO - 設計問題

但是,使用ORM這顯然是一個ORM(例如Hibernate)的工作。它恰好爲某些(幾乎任何)類型的數據庫提供了一個抽象接口。

回顧幾個最後的項目讓我們看看DAO層。第一步是使用save(),findById(),findAll()方法的通用hibernate dao。這對我來說只是代理hibernate會話方法。

更進一步我看到這樣的接口,像這裏提出的:Generic DAO pattern in Hibernate,DAO完全緊密地將hibernate的方式做到持久性(合併,標準查詢)。這個DAO不會與Hibernate一起用於其他持久機制。

所以最後的問題是一個問題:對於這種常見的DAO設計,什麼新的帶來了DAO模式?如果我想切換數據庫引擎,我將它切換到休眠級別。那麼,這對於在ORM應用程序中使用DAO模式是否有任何好處?

讓我們收集了一些經驗:

  1. 有多少次你看到的DAO類層次結構緊密結合的休眠(或其他ORM)和你想想從什麼好處?
  2. 你有多少項目以你從DAO層獲益的方式改變了持久性機制(即你需要實現其他DAO層,因爲你的作業不能通過切換db方言在ORM級上完成)?
  3. 有多少個項目你剛剛開發了大型的DAO結構(每個領域對象的接口+類)並且從來沒有真正使用過這個(即,你從未改變過基本DAO層次結構的實現)?
  4. 那麼,您認爲沒有DAO層的應用程序,只使用ORM會話提供的抽象?

請與經驗分享。

回答

2

恕我直言,當使用ORM時,DAO模式並不是真的關於切換數據庫引擎的能力。這是關於

  • 分離職責:業務邏輯進入服務層,持久轉到DAO層
  • 能夠通過嘲諷DAO層
  • 能夠測試持久性測試服務層邏輯,因爲它不是埋在業務邏輯之內

我通常不希望每個域對象都有一個DAO,而是每個功能用例都有一個DAO。事實上,我發現大多數查詢在一個足夠複雜的應用程序中並沒有鏈接到特定的域對象,而是與用例或一組用例相關聯。但是YMMV,並且結合這兩種方法有時是有用的。

因此,要回答你的具體問題:

  1. 幾乎總是。使用Hibernate或JPA使用DAO與使用普通JDBC使用DAO不同,絕大多數時間都不使用DAO。通常,數據庫的選擇在項目開始之前就已經完成,並且永遠不會改變。
  2. 我傾向於只在需要時開發DAO,而不是因爲存在域對象。但是有一個「通用DAO」基類有時很方便
  3. 我認爲它們很難測試,通常結構不是很好,最終一次又一次地重複實現相同的查詢/加載,因爲它們不是孤立的一個可重複使用的DAO
+0

感謝您的回覆。然後,我還有另外一個問題: 1.你不能在服務層上模擬和測試,在默認實現中直接使用Session抽象嗎? 2.「DAO per usecase」是什麼意思?這對我來說是新的,因爲我也使用這種模式,但在服務層 我知道這種方法的另一個問題是收集某處訪問數據的方法 - 複雜的,可重複的查詢。這可能是默認在DAO層完成的,但通常這是重複的服務層,它們只是這些DAO的代理(從我看不到太多好處)。 –

+0

1.不是,因爲會話方法太粗糙,而且不夠具體。模擬(並驗證)dao.findFoosByField(String)比session.createQuery(String)更容易,然後是query.setMaxResults(),然後是query.list()。 2.例如,我可能有一個用於授權管理的DAO,它將處理用戶,角色,配置文件的持久性,而不是一個用戶DAO,另一個用於角色,另一個用於配置文件。 –

+0

好的,我明白了。我使用DB羣體進行測試而不是嘲笑,所以嘲笑的DAO並沒有真正幫助我。我在這裏看到的另一個與DAO的東西是限制/排序的問題。在結果中,需要大量的這些參數需要的方法,而這一切都已經暴露出了一個非常方便的界面。我真的很接近轉向不同的解決方案。 –