2016-11-26 71 views
2

當涉及到訪問數據庫的應用程序(通過Hibernate)時,我一直在試圖改善問題的分離。訪問數據庫時關注問題的最佳實踐

在我一直在使用下面的方法的應用程序之一:

  • 創建具有數據庫的無連接/意識和業務邏輯。他們只與GeneralDAO(和其他服務)通信;
  • GeneralDAO負責CRUD /查找操作以及涉及更復雜數據庫查詢的方法。

我用這種方法看到的問題是:

  • GeneralDAO慢慢地變成上帝的對象,當你的應用程序的增長,並需要大量的特定數據庫的查詢。
  • 有時更具體的服務只能成爲GeneralDAO的代理,因爲該方法很簡單,只需要數據庫查詢。見例1

例1:服務就是

bookService的管理在圖書館應用相關的書籍東西代理。讓我們考慮兩種方法:

  • archiveBook(書)
  • findByIsbn(字符串ISBN)

archiveBook(Book)可能有相當多的商業邏輯有關 - 我們可以想像這涉及到呼叫:

distributionService.unbox(Book); 
archivalBook.archive(Book); 
librarianService.informNewBook(Book); 

但是findByIsbn(String isbn)更簡單:它只需要對數據庫執行SQL調用。因此,在這種情況下,我看到兩個選項:

  1. 重定向調用的對象,可以將數據庫說話來執行查詢。例如generalDAO.findByIsbn(String isbn),它使用數據庫通信層(在Hibernate中它會使用sessionFactory或EntityManager)來執行查詢。
  2. 作出這樣的數據庫層提供給bookService的,使得它執行查詢本身

問題/意見(第一號標識上面的選項):

1.1。擁有2個完全相同簽名的方法並不奇怪,即使這樣做是爲了使BookService獨立於數據庫層(和ORM)嗎?

1.2。你如何建議避免上帝的反模式?你會建議根據這些方法做什麼把GeneralDAO分成幾個DAO?在這種情況下,我們是不是冒着需要向某些服務注入大量DAO的風險,導致服務中注入了太多對象?

2.1您對這種選擇有什麼看法?它不是通過讓BookService知道兩個不同抽象級別的對象(DAO和sessionFactory/EntityManager)來打破「關注點分離」嗎?

3.1。你會建議任何其他方法/模式/最佳實踐嗎?

謝謝!

+0

現在,我確信我們應該從DAO中刪除任何數據庫業務知識。 DAO應該完成它所要做的事情,並且它會對數據庫運行查詢。它很容易配置它們自己做Crud sql,但任何查詢beyong應該由業務層使用知道如何構建查詢的對象來處理。這樣你的daos中就沒有business-sql。在我的工作中,我有很多這樣的人,他們很痛苦,更不用說業務層,大部分時間,只是將控制權交給DAO,而不是自己做的工作。 – Dalton

回答

1

1.2。你如何建議避免上帝的反模式?你會建議打破GeneralDAO到幾個DAO取決於什麼 方法?在這種情況下,會不會我們需要冒險注入大量 的DAO到一些服務,導致有太多的對象 注入到它服務?

一般來說,DAO類應處理特定的實體。如你所說:
如果你的實體之一,需要許多類型的查詢,您可以再利用共同關心它們分組(閱讀,寫作,選擇上agregates,等...例如)將其劃分爲兩個或兩個以上的DAO。
如果你有太多的查詢和太多的DAO,也許,你應該檢查你是否用幾種方法編寫幾乎相同的查詢。在這種情況下,使用規範或Criteria API來允許客戶端通過參數自定義查詢。如果查詢真的不同,你有各種處理。所以,使用多個DAO似乎是一個合適的解決方案。它避免了增加神物的複雜性和興起。

1.1。有兩種方法具有完全相同的簽名並不奇怪,即使這樣做是爲了使BookService獨立於數據庫層(和ORM)嗎?

當您在邏輯圖層中劃分應用程序時,正如您注意到的,在某些操作中,某些圖層僅執行對下圖層的委託調用。
所以在這些情況下,擁有相同的方法名稱是相當普遍的。我會走得更遠:如果它只是代表團呼叫,那麼擁有相同名稱是一個好習慣。爲什麼我們在傳達的行爲中創造了一個變體,如果它們都滿足相同的需求?

2.1您對這種方法有什麼看法?它不是通過讓BookService知道兩個不同抽象層次(DAO和 sessionFactory/EntityManager)上的對象 來打破「關注點分離」嗎?

BookService依賴於DAO,但不應該依賴構成DAO實現一部分的sessionFactory/EntityManager。
BookService調用使用sessionFactory/EntityManager的DAO。
如有必要,BookService可以使用@Transactional註釋來指定其本身或其方法的事務細節。

3.1。你會建議任何其他方法/模式/最佳實踐嗎?

  • 當你使用Spring,試圖依靠自旋微觀JPA庫(少鍋爐板處理在通常情況下,可擴展的類)
  • 使用規範或標準模式時,你有一些疑問的幾個變種。
+0

謝謝大衛。這裏有一些有趣的想法。還要感謝您使用Spring JPA存儲庫。我最近才意識到這一點,並且正在試圖找出在使用hibernate和sessionfactory(SF)的應用程序中需要進行的更改。仍然需要弄清楚Spring數據是否可以替代或補充Hibernate,以及如果我應該先從SF升級到entityManager(和JPA查詢),然後再集成Spring Data。 – mmalmeida