struts和hibernate談J2EE架構資料表示

來源:互聯網
上載者:User
HibernateStruts資料結構BeanWeb

    本文說明了在J2EE架構中各層的資料表示方法,包括:1、Web層的資料表示是FormBean;2、業務層的資料表示是VO;3、持久層的資料表示是PO。Form Bean不能被傳遞到業務層;PO在特定的情況下,例如Hibernate中,他可以取代VO出現在業務層,但是不管PO還是VO都必須限制在業務層內使用,最多到達Web層的Control,絕不能被擴散到View去。

     

    在struts+hibernate這種結構中,是不應該把Hibernate產生的PO直接傳遞給JSP的,不管他是Iterator,還是List,這是一個設計錯誤。

    我來談談在J2EE架構中各層的資料表示方法:

    ◆Web層的資料表示是FormBean,資料來源於HTML Form POST

    ◆業務層的資料表示是VO

    ◆持久層的資料表示是PO,其資料來源於資料庫,持久層的資料表示例如CMP

    在一個規範的J2EE架構中,不同層的資料表示應該被限制在層內,而不應該擴散到其它層,這樣可以降低層間的耦合性,提高J2EE架構整體的可維護性和可擴充性。比如說Web層的邏輯進行了修改,那麼只需要修改FormBean的結構,而不需要觸動業務層和持久層的代碼修改。同樣的,當資料庫表進行了小的調整,那麼也只需要修改持久層資料表示,而不需要觸動業務層代碼和Web層代碼。

    不過由於Hibernate的強大功能,例如動態產生PO,PO的狀態管理可以脫離Session,使得在應用了Hibernate的J2EE架構中,PO完全可以充當VO,因此我們下面把PO和VO合并,統稱為PO。

    先來談談ActionFormBean和持久層的PO之間的重大區別:

    在簡單的應用中,ActionFormBean和PO幾乎是沒有區別,所以很多人乾脆就是用ActionFormBean來充當PO,於是ActionFormBean從JSP頁面到Servlet控制層再到業務層,然後穿過持久層,最後一直映射到資料庫表。真是一竿子捅到了底!

    但是在複雜的應用中,ActionFormBean和PO是分離的,他們也不可能一樣。ActionFormBean是和網頁裡面的Form表單一一對應的,Form裡面有什麼元素,Bean裡面就有什麼屬性。而PO和資料庫表對應,因此如果資料庫表不修改,那麼PO也不會修改,如果頁面的流程和資料庫表欄位對應關係不一致,那麼你又如何能夠使用ActionFormBean來取代PO呢?

    比如說吧,使用者註冊頁面要求註冊使用者的基本資料,因此HTML Form裡麵包含了基本資料屬性,於是你需要一個ActionFormBean來一一對應(注意:是一一對應),每個Bean屬性對應一個文字框或者選擇框什麼的。

    而使用者這個持久對象呢?他的屬性和ActionFormBean有什麼明顯不同呢?他會有一些ActionFormBean所沒有的集合屬性,比如說使用者的許可權屬性,使用者的組屬性,使用者的文章等等。另外還有可能的是在ActionFormBean裡面有3個屬性,分別是使用者的First Name, Middle Name, Last Name,而在我的User這個持久對象中就是一個Name對象屬性。

    假設我的註冊頁面原來只要你提供First Name,那麼ActionFormBean就這一個屬性,後來我要你提供全名,你要改ActionFormBean,加兩個屬性。但是這個時候PO是不應該修改滴,因為資料庫沒有改。

    那麼在一個完整的J2EE系統中應該如何進行合理的設計呢?

    JSP(View) ---> Action Form Bean (Module) ---> Action(Control)

    Action Form Bean是Web層的資料表示,它和HTML頁面Form對應,只要Web頁面的操作流程發生改變,它就要相應的進行修改,它不應該也不能被傳遞到業務層和持久層,否則一旦頁面修改,會一直牽連到業務層和持久層的大面積的代碼進行修改,對於軟體的可維護性和可擴充性而言,是一個災難,Actiont就是他的邊界,到此為止!

    Action(Web Control) ---> Business Bean ---> DAO ---> ORM --->DB

    而PO則是業務層和持久層的資料表示,它在業務層和持久層之間進行流動,他不應該也不能被傳遞到Web層的View中去,而ActionServlet就是他的邊界,到此為止!

    然後來看一看整個架構的流程:

    當使用者通過瀏覽器訪問網頁,提交了一個頁面。於是Action拿到了這個FormBean,他會把FormBean屬性讀出來,然後構造一個PO對象,再調用業務層的Bean類,完成了註冊操作,重新導向到成功頁面。而業務層Bean收到這個PO對象之後,調用DAO介面方法,進行持久對象的持久化操作。

    當使用者查詢某個會員的資訊的時候,他用全名進行查詢,於是Action得到一個UserNameFormBean包括了3個屬性,分別是first name, middle name, last name,然後Action把UserNameFormBean的3個屬性讀出來,構造Name對象,再調用業務Bean,把Name對象傳遞給業務Bean,進行查詢。

    業務Bean取得Name(注意:Name對象只是User的一個屬性)對象之後調用DAO介面,返回一個User的PO對象,注意這個User不同於在Web層使用的UserFormBean,他有很多集合屬性的。然後業務Bean把User對象返回給Action。

    Action拿到User之後,把User的基本屬性取出(集合屬性如果不需要就免了),構造UserFormBean,然後把UserFormBean request.setAttribute(...),然後重新導向到查詢結果頁面。

    查詢頁面拿到request對象裡面的ActionFormBean,自動調用tag顯示之。

    總結:

    Form Bean是Web層的資料表示,他不能被傳遞到業務層;PO是持久層的資料表示,在特定情況下,例如Hibernate中,他可以取代VO出現在業務層,但是不管PO還是VO都必須限制在業務層內使用,最多到達Web層的Control,絕不能被擴散到View去。

    Form Bean和PO之間的資料轉化是在Action中進行的。

    BTW(順便說一句):

    JDO1.x還不能像Hibernate功能這樣強大,PO不能脫離持久層,所以必須在業務層使用VO,因此必須在業務層進行大量的VO和PO的轉化操作,相對於Hibernate來說,編程比較煩瑣。

    當然了,理論是一回事,實際操作也不一定非要這樣幹,你可以自行取捨,在實際項目中靈活一點,增加一點bad smell,提高開發效率。只不過在大型項目中最好還是嚴絲合縫,不然的話,改版的時候會痛苦的很的。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.