2013-05-18 26 views
0

我在互聯網上看到了通用dao的使用方法。 你一定要喜歡它:通用DAO - 「永遠不要完全通用!」

public interface GenericDao <T, PK extends Serializable> {} 

public class GenericDaoHibernateImpl <T, PK extends Serializable> 
implements GenericDao<T, PK> 

一個新班出現了嗎?沒問題:

public interface NewClassDao extends GenericDao<NewClass, Long> 

而且我們都設定了。

現在, 是多麼糟糕,如果我走「全通用」和這樣做:(!對象與鑄造)

public interface FullGenericDao 

public class FullGenericDaoHibernateImpl 

現在我只能用一個DAO

一新班再次出現? 沒有問題:

NewClassApperedAgain newClassAppeared = (NewClassApperedAgain) FullGenericDao.getItemById(20, NewClassApperedAgain.class); 

兩個問題浮現在腦海:

1)它甚至有可能去「全通用」,實際上建立這樣一個DAO?我的意思是我不明白爲什麼不傳遞dao的className的每個方法,只是做鑄造需求? save(object,className); delete(object,className);

2)這種做法有哪些缺點(我確定有)?

謝謝!

回答

1

DAO對象包含與持久層連接的域模型特定邏輯。

你可以去完全通用,但你必須要面對這樣的問題:

  • 我應該在哪裏放(例如構建WHERE子句中)與搜索連接邏輯?
    • User findUserByOrganizationId(Serializable organizationId)
  • 我應該把一些特定的地圖功能(例如聚合查詢)?
    • Map<Organization, Integer> findUserCountPerOrganization()

我敢肯定還有其他建築/邏輯問題。此外,泛型將在運行期間被擦除,因此您已經介紹了在每個方法簽名中包含域對象Class<?>的必要性。

TL; DR有可能「完全通用」,但您需要將非共享持久性邏輯移至更高級別。在一些AbstractDaoImpl中執行共享的通用邏輯,然後對其進行子類化更好。你最終可能會得到空的實現(通用超類可能只有你所需要的),但是你可以有將來的領域模型特定的方法。