2012-02-29 63 views
1

我有一個關於我的Java應用中的幾個設計問題。 該軟件是使用MySQL數據庫來存儲不同類型的對象(客戶,員工,文檔)的桌面應用程序。每位員工都有一組客戶,每位客戶都包含許多文檔。整個結構通過休眠來延遲加載。Java桌面,應用程序設計 - MVC與Hibernate

我目前使用這四個層以建立我的申請

  • 模型 - 包含數據例如對象客戶,員工,...
  • 觀點 - 對於每個動作視圖(添加用戶,創建文檔,...)
  • 控制器 - 每個視圖都有其自己的控制器,控制一個或多個業務對象
  • 業務對象 - 封裝對模型的操作(添加客戶= customerBO,將文檔添加= documentBO,...)

因此,當用戶現在想要一個新的文檔添加到邏輯客戶,客戶視圖的控制者打開一個新的 - 我們稱之爲 - 「文檔窗口」,它有自己的控制器。 由於每個文檔都必須屬於一個客戶,所以我將該客戶作爲參數傳遞給客戶。但是,如果我用這種方式我必須確保當前Hibernate的Session被打開,以客戶爲對象重新連接到會話使用延遲加載。

所以我現在的問題:是否有一個更優雅的方式來做到這一點?也許通過一個存儲當前活躍客戶的會話級別?或者我的結構中有一個錯誤,我沒有看到?

回答

0

這可能是一個數據傳輸對象或值對象一個良好的使用。簡而言之,在UI代碼中爲客戶使用只讀,非休眠,分離表示,而不是Hibernate創建的表示。此Customer對象將是您的UI需要的來自後端的全功能Customer對象的最小投影。事實上,你可能不需要比名稱和ID更多(當然,取決於你的用戶界面)。

在過去,我已經出臺了「服務」界面,只能在這些值對象,或DTO的方面(這些條件不真正互換,但我想是靈活的,這是一個重要的概念:-))。

當保存東西就代表客戶做,請撥打服務組件service#attachDocument(customer.getCustomerId()),或什麼的。該組件將與Hibernate進行交互以檢索客戶並調用customer.addDocument(documentId)(或適用於您的模型的任何內容)。

0

所有的情況並不少見到這樣做的第一:

DocumentService { 
    public Document addDocument(int customerId) { 
     Customer customer = session.getById(Customer.class, customerId); 
     Document document = new Document(); 
     customer.getDocuments().add(document); 
     session.update(customer); 
     return document; 
    } 
} 

所以在末尾添加文檔可能看起來像一個perforamnce點球點前閱讀客戶,但要走的路,如果你不不想傳遞完整的Customer對象。

通常我會使用類似於CustomerInfo對象的東西,它只存儲一些相關信息,如id,名稱,地址等等。通常情況下,不會經常更改的所有內容,如果用戶看到陳舊的數據並不重要。 (如果關鍵的話,經常使用通知事件/消息來更新相關的信息對象)。

現在您可以將這些CustomerInfo傳遞給許多常用的服務方法。如果從數據庫加載Customer對象,我通常會更新客戶信息對象以儘可能保持其同步。

這裏只有一個規則。由於客戶信息可能包含陳舊的數據(某些其他用戶已經更改了它,所以您需要驗證其有效性)。您可以引入@Version或者比較相關屬性(如果它們已經更改)(您使用樂觀日誌記錄又名長用戶交易和兩個或多個短數據庫事務)。

所以在使用重新安裝到底是什麼錯。

如果你有一個本地嵌入式數據庫和使用Hibernate的應用程序是唯一的用戶(單個用戶安裝) ,您可能需要考慮使用單一會話方法,將會話的每次訪問同步或彙集到一起,以避免併發事務/訪問數據庫。

這樣確保只有一個Object表示每個'數據庫對象/行'。這使得很容易假設每個對象和每個Info都與數據庫同步。只有會話丟失的情況下,您必須通過將應用程序使用的所有實體重新附加到新會話來恢復,以避免出現兩個實體對象表示同一個數據庫行的情況,這在休眠中不允許。

摘要

  • 使用連接是沒有錯的。
  • 在應用程序中傳遞實體實例並沒有錯。記住:Hibernate通常會發出一個select來刷新對象,並驗證它代表當前會話/事務看到的當前數據庫狀態(使用@Version降低成本)。
  • 您可以使用CustomerInfo/DocumentInfo對象來避免沿着實體實例傳遞以減少內存佔用並避免重新加載。
  • 如果性能問題,您可以直接使用id創建文檔,然後使用您從插入(SQL)語句中添加的id創建DocumentInfo。這樣您就不必重新加載用戶或創建文檔對象。這只是爲了減少內存佔用並提高性能,但接縫不屬於您的擔憂。

我的建議是,堅持重新附加,只要你沒有內存消耗問題。