J2EE項目中的數據持久層設計
劉艷霞 (唐山工業學校 唐山 063000)
數據持久層的設計目標是為整個項目提供一個高層、統一、安全和并發的數據持久機制。完成對各種數據進行持久化的編程工作,并為系統業務邏輯層提供服務。數據持久層提供了數據訪問方法,能夠使其它程序員避免手工編寫程序訪問數據持久層(Persistene layer),使其專注于業務邏輯的開發,并且能夠在不同項目中重用映射框架,大大簡化了數據增、刪、改、查等功能的開發過程,同時又不喪失多層結構的天然優勢,繼承延續J2EE特有的可伸縮性和可擴展性。
1 數據持久層及ORM映射框架
筆者從事的項目中的數據持久層,是基于J2EE體系結構,并采用了Hibernate作為持久映射框架。
Hibernate是一種新的ORM映射工具,是JDBC的輕量級的對象封裝。Hibernate可以用在JDBC可以使用的任何場合,例如Java應用程序的數據庫訪問代碼,DAO接口的實現類,甚至可以是BMP里面的訪問數據庫的代碼。Hibernate不僅提供了從Java類到數據表之間的映射,也提供了數據查詢和恢復機制。相對于使用JDBC和SQL來手工操作數據庫,使用Hibernate,可以大大減少操作數據庫的工作量。
Hibernate是一個和JDBC密切關聯的、獨立的對象持久層框架,可以搭配各種App Server、Web Server、EJB Container共同使用,Hibernate的兼容性僅同JDBC驅動、底層數據庫產品間有一定的關系,但是和使用它的Java程序、App Server沒有任何關系,也不存在兼容性問題。而且事實表明Hibernate可以和多種Web服務器或者應用服務器良好集成,如今已經支持幾乎所有的流行的數據庫服務器(達16種)。
在較為常用的數據持久方案中,Hibernate無疑是最優秀的,下面是對各種持久方案的比較。
¨ 流行的數據持久層架構:
Business Layer <-> Session Bean <-> Entity Bean <-> DB
¨ 為了解決性能障礙的替代架構:
Business Layer <-> DAO <-> JDBC <-> DB
¨ 使用Hibernate來提高上面架構的開發效率的架構:
Business Layer <-> DAO <-> Hibernate <-> DB
我們就上面3個架構來作如下分析。
(1)內存消耗:采用JDBC的架構無疑是最省內存的,Hibernate的架構次之,EB的架構最差。
(2)運行效率:如果JDBC的代碼寫的非常優化,那么JDBC架構運行效率最高,但是實際項目中,這一點幾乎做不到,這需要程序員非常精通JDBC,運用Batch語句,調整PreapredStatement的Batch Size和Fetch Size等參數,以及在必要的情況下采用結果集cache等等。而一般情況下程序員是做不到這一點的。因此Hibernate架構表現出最快的運行效率。EB的架構效率會差的很遠。
(3)開發效率:在有Eclipse、JBuilder等開發工具的支持下,對于簡單的項目,EB架構開發效率最高,JDBC次之,Hibernate最差。但是在大的項目,特別是持久層關系映射很復雜的情況下,Hibernate效率高的驚人,JDBC次之,而EB架構很可能會失敗。
2 數據持久層設計
復雜性是應用開發過程中最令人頭疼的一個問題。每當在一個應用中增加一個功能時,它的復雜性通常呈幾何級的增長。這種復雜性往往導致程序的開發無法再繼續下去。這也是現在為什么許多應用只有Beta版本而沒有正式版的原因。
專家將應用開發過程產生的復雜性分為兩類,即非本質的(accidental)和本質的(essential)。本質的復雜性是對于解決目標問題所必然產生的復雜性,非本質的復雜性是由于選擇了不適當的開發工具和設計工具而產生的復雜性。對于一個功能確定的程序來講,本質的復雜性是確定的,而非本質的復雜性則是沒有限制的。因此,一個應用的開發要想較順利地取得成功,就需要盡可能地減少非本質的復雜性。
設計模式使人們可以更加簡單方便地復用成功的設計和體系結構。將已證實的技術表述成設計模式,也會使新系統開發者更加容易理解其設計思路。
衡量一個系統優秀與否的關鍵因素,除了能夠滿足用戶需求外還有如下方面:首先是靈活性。靈活性意指這種結構或模式不依賴于任何實際應用,應該與操作系統、應用程序無關。提供獨立的結構,可以提供最大的重用。其次是可擴展性。隨著業務的擴展,新的業務不斷增加,業務邏輯自然增加,系統必然會進行修改或添加相應功能模塊。再次是可配置性。最后是安全性。
數據持久層的設計采納了多種設計模式,最大限度的降低了系統內部各模塊、子系統間的耦合性,使得系統相對易于擴展,并且能夠在進行改變時,保證持久層的業務邏輯層相對穩定,基本不需要因持久層的調整改變而進行邏輯層的變動。
筆者在項目中采用了如下設計模式。
2.1 整體架構——MVC模式(模型-視圖-控制器)
¨ 模型(Model):模型包含完成任務所需要的所有的行為和數據。在數據持久層中,模型即為值對象以及數據訪問對象。
¨ 視圖(View):數據持久層中,視圖就是持久層同其它層進行數據交換的值對象(Transfer Object)和視圖助手對象。
¨ 控制器(Controller):持久層所需的控制相對簡單,因此集成到了控制代理中。
持久層整體采用MVC模式,使得整個數據持久層的實現部分與項目的業務邏輯部分隔離開來,能夠實現對接口作大的修改而不需要對相應的模型進行修改。另外,持久層某子系統發生變化時,不會影響到其它子系統。有利于提高系統的穩定性、可維護性。
2.2 值對象模式(Value Object Pattern)
值對象用來封裝業務對象。相應的方法調用是設置(getter)和檢索(setter)值對象。它是任意的可串行化的Java對象,當客戶端Bean請求業務數據時,該Bean可以構造值對象,用屬性值來填充,并按照值把它傳遞給客戶端。
在筆者開發項目的數據持久層體系結構中,值對象主要應用在子系統間傳遞、交換數據(Transfer Object)和映射數據表兩個方面(Persistent Object)。
在各子系統間進行數據傳遞和數據交換時,使用值對象模式能夠最大化地降低系統間數據傳遞的開銷。在這種策略下傳遞的是對象而不再是一個個的有意義的數據,使得系統在進行擴充、修改時,各子系統間數據傳遞部分不會受到影響,因為各子系統僅需要關心是否有值對象被傳遞,而并不去關心傳遞的到底是什么數據。
在映射數據庫表時,值對象類及其子類所構成的樹形結構被用來映射一個數據庫表,該繼承樹通過XML配置文件對應數據庫中的單個表,這使得最底層的關系型的數據庫表結構能夠面向對象模型所隱藏,另外,由于面向對象設計方法中類的可繼承性,采用繼承樹對應一個表的策略使得該映射策略極易擴展,并且能夠將一個復雜的數據表轉化成若干簡單的值對象來表示,提高了系統的可維護性和可修改性。
2.3 數據訪問對象(DAO)
根據數據源不同,數據訪問也不同。根據存儲的類型(關系數據庫、面向對象數據庫等)和供應商不同,持久性存儲(比如數據庫)的訪問差別也很大。當業務組件或表示組件需要訪問某數據源時,它們可以使用合適的API來獲得連接性,以及操作該數據源。但是在這些組件中包含連接性和數據訪問代碼會引入這些組件及數據源實現之間的緊密耦合。組件中這類代碼依賴性使應用程序從某種數據源遷移到其它種類的數據源將變得非常麻煩和困難,當數據源變化時,組件也需要改變,以便于能夠處理新類型的數據源。
筆者開發項目的數據持久層使用數據訪問對象(DAO)來抽象和封裝所有對數據源的訪問。DAO管理著與數據源的連接以便于檢索和存儲數據,DAO實現了用來操作數據源的訪問機制,內部封裝了對Hibenernate數據操縱、事務處理、會話管理等API的封裝。外界依賴于DAO的業務組件為其客戶端使用DAO提供了更簡單的接口,DAO完全向客戶端隱藏了數據源實現細節。由于當低層數據源實現變化時,DAO向客戶端提供的接口不會變化,采用該設計模式允許DAO調整到不同的存儲模式,而不會影響其客戶端或業務組件,即使將來不再采用Hibernate作為關系映射框架,上層客戶端也不會受到任何影響。另外,DAO還充當組件和數據源之間的適配器的角色。
數據持久層通過調整抽象工廠(Abstract Factory)模式和工廠方法(Factory Method) 模式(這二個創建型模式的實現詳情參見GoF的<設計模式>),),使DAO模式達到了很高的靈活度。
當底層存儲隨著實現的變化而變化時,該策略可以通過使用抽象工廠模式實現。抽象工廠可以基于工廠方法實現而創建,并可使用工廠方法實現。該策略提供一個DAO的抽象工廠對象,其中該對象可以構造多種類型的具體的DAO工廠,每個工廠支持一種不同類型的持久性存儲實現。一旦你獲取某特定實現的具體DAO工廠,可以使用它來生成該實現中所支持和實現的DAO。
2.4 連接池、應用級緩存及享元模式(提升系統性能)
¨ 緩存(Cache)
對于數據庫來說,廠商的做法往往是在內存中開辟相應的區域來存儲可能被多次存取的 數據和可能被多次執行的語句,以使這些數據在下次被訪問時不必再次提交對DBMS的請求和那些語句在下次執行時不必再次編譯。
同樣,數據持久層采用緩存技術來保存已經從數據庫中檢索出來的部分常用數據。客戶端訪問持久層時,持久層將首先訪問緩存,如果能夠命中則直接從緩存中提取數據,否則再向數據庫發送提取數據的指令。這種設計能夠大幅度地提高數據訪問速度。
¨ 連接池(Connection Pool)
池是一個很普遍的概念,和緩沖存儲有機制相近的地方,都是縮減了訪問的環節,但它更注重于資源的共享。
對于訪問數據庫來說,建立連接的代價比較昂貴,因此,數據持久層建立了“連接池”以提高訪問的性能。數據持久層把連接當作對象,整個系統啟動后,連接池首先建立若干連接,訪問本來需要與數據庫連接的區域,都改為和池相連,池臨時分配連接供訪問使用,結果返回后,訪問將連接交還。這種設計消除了JDBC與數據源建立連接的延時,同時在應用級提供了對數據源的并發訪問。
¨ 享元模式(Flyweight)
面向對象語言的原則就是一切都是對象,但是如果真正使用起來,有時對象數可能顯得很龐大,比如,數據庫中的記錄,如果以每條記錄作為一個對象,提取幾千條記錄,對象數就是幾千,這無疑相當耗費內存。數據持久層依據享元模式設計了若干元類,封裝可以被共享的類。這種設計策略顯著降低了系統的內存消耗。
2.5 各種對象的創建模式—工廠方法(Factory Method)
工廠方法模式將創建實例的工作與使用實例的工作分開,也就是說,讓創建實例所需要的大量初始化工作從簡單的構造函數中分離出去。只需要調用一個統一的方法,即可根據需要創建出各種對象的實例,對象的創建方法不再用編碼到程序模塊中,而是統一編寫在工廠類中。這樣在系統進行擴充修改時,系統的變化僅存在于工廠類內部,而絕對不會對其他對象造成影響。
(收稿日期:2004-12-31 Email:chl@tsxd.sina.net)
posted on 2006-02-09 13:15
★yesjoy★ 閱讀(389)
評論(0) 編輯 收藏 所屬分類:
Hibernate學習