摘要
在Java技術(shù)中有許多方法可以對數(shù)據(jù)進(jìn)行持久化,持久層也是Java應(yīng)用程序中最重要的部分之一。本文在分析了3種持久層主流解決方案的基礎(chǔ)上,介紹了
O-R映射開源項(xiàng)目Hibernate,并介紹了在Web應(yīng)用開發(fā)中怎樣配置Hibernate的環(huán)境,并使用它建立一個應(yīng)用。 關(guān)鍵字 hibernate,數(shù)據(jù)持久化,JDBC, EJB,JDO 數(shù)據(jù)持久層簡介 J2EE的三層結(jié)構(gòu)是指表示層(Presentation),業(yè)務(wù)邏輯層(Business Logic)以及基礎(chǔ)架構(gòu)層(Infrastructure),這樣的劃分非常經(jīng)典,但是在實(shí)際的項(xiàng)目開發(fā)法中,開發(fā)者通常對三層結(jié)構(gòu)進(jìn)行擴(kuò)展來滿足一些 項(xiàng)目的具體要求,一個最常用的擴(kuò)展就是將三層體系擴(kuò)展為五層體系,即表示層(Presentation),控制/中介層 (Controller/Mediator)、領(lǐng)域?qū)?Domain),數(shù)據(jù)持久層(Data Persistence)和數(shù)據(jù)源層(Data Source)。它其實(shí)是在三層架構(gòu)中增加了兩個中間層??刂?中介層位于表示層和領(lǐng)域?qū)又g,數(shù)據(jù)持久層位于領(lǐng)域?qū)雍突A(chǔ)架構(gòu)層之間。由于對象范例和關(guān) 系范例這兩大領(lǐng)域之間存在“阻抗不匹配”,所以把數(shù)據(jù)持久層單獨(dú)作為J2EE體系的一個層提出來的原因就是能夠在對象-關(guān)系數(shù)據(jù)庫之間提供一個成功的企業(yè) 級映射解決方案,盡最大可能彌補(bǔ)這兩種范例之間的差異。 三種持久層主流解決方案 1、JDBC 許多開發(fā)者用JDBC進(jìn)行數(shù)據(jù)庫程序的開發(fā)。此中方式很多情況下都使用DAO模式,采用SQL進(jìn)行查詢。雖然用此方式可以使應(yīng)用程序代碼與具體的數(shù)據(jù)庫 廠商和數(shù)據(jù)庫位置無關(guān),不過JDBC是低級別的數(shù)據(jù)庫訪問方式,JDBC并不支持面向?qū)ο蟮臄?shù)據(jù)庫表示。JDBC數(shù)據(jù)庫表示完全圍繞關(guān)系數(shù)據(jù)庫模型。在大 型應(yīng)用程序的DAO中書寫這樣的代碼,維護(hù)量是非常大的。 2、EJB 在J2EE的規(guī)范中,為EJB定義了兩種 持久化的解決方案:一種是BMP,另一種是CMP。其中CMP不需要將SQL語句加入到代碼中。目前,在采用J2EE的應(yīng)用中,EJB CMP方式得到了廣泛應(yīng)用。更加引人注意的是,隨著EJB規(guī)范的發(fā)展,CMP也包含了一些高級關(guān)系的內(nèi)容。但是,CMP的使用比較復(fù)雜,對很多開發(fā)人員來 說比較難以掌握。而且,不是在所有的情況下都適合在系統(tǒng)中采用EJB,而且想要非常清楚的了解EJB規(guī)范也是非常費(fèi)時的。在用EJB編碼前,先要讓專家理 解API,然后需要了解每一個容器部署時所要關(guān)注的技術(shù)。此外,許多情況下商用容器的性能和支持也不是很好。 3、JDO JDO是一個存儲java對象的規(guī)范,JDO規(guī)范1.0的提出可以使你將精力集中在設(shè)計Java對象模型,然后在企業(yè)應(yīng)用軟件架構(gòu)的不同層面中存儲傳統(tǒng) 的Java對象(Plain Old Java Objects,簡稱POJOs),采用JDOQL語言進(jìn)行SQL操作。一些公司(包括sun)企圖根據(jù)JDO規(guī)范進(jìn)行設(shè)計并實(shí)現(xiàn)JDO產(chǎn)品,然而他們都 不能很好的進(jìn)行實(shí)現(xiàn),并且性能優(yōu)化上比較差。 數(shù)據(jù)持久層新的解決方案Hibernate 1、Hibernate介紹 Hibernate是一個開放源代碼的對象關(guān)系映射框架,它對JDBC進(jìn)行了輕量級的對象封裝,使Java程序員可以隨心所欲的使用對象編程思維來操縱 數(shù)據(jù)庫。它不僅提供了從Java類到數(shù)據(jù)表之間的映射,也提供了數(shù)據(jù)查詢和恢復(fù)機(jī)制。相對于使用JDBC和SQL來手工操作數(shù)據(jù)庫, Hibernate可以大大減少操作數(shù)據(jù)庫的工作量。 另外Hibernate可以利用代理模式來簡化載入類的過程,這將大大減少利用Hibernate QL從數(shù)據(jù)庫提取數(shù)據(jù)的代碼的編寫量,從而節(jié)約開發(fā)時間和開發(fā)成本Hibernate可以和多種Web服務(wù)器或者應(yīng)用服務(wù)器良好集成,如今已經(jīng)支持幾乎所 有的流行的數(shù)據(jù)庫服務(wù)器。 2、Hibernate原理 Hibernate技術(shù)本質(zhì)上是一個提供數(shù)據(jù)庫服務(wù)的中間件。它的架構(gòu)如圖1所示:
圖1顯示了hibernate的工作原理,它是利用數(shù)據(jù)庫以及其他一些配置文件如hibernate.properties,XML Mapping等來為應(yīng)用程序提供數(shù)據(jù)持久化服務(wù)的。 Hibernate具有很大的靈活性,但同時它的體系結(jié)構(gòu)比較復(fù)雜,提供了好幾種不同的運(yùn)行方式。在輕型體系中,應(yīng)用程序提供JDBC連接,并且自行管 理事務(wù),這種方式使用了Hibernate的一個最小子集;在全面解決體系中,對于應(yīng)用程序來說,所有底層的JDBC/JTA API都被抽象了,Hibernate會替你照管所有的細(xì)節(jié)。 使用Hibernate建立一個應(yīng)用 1、配置Hibernate 在src 目錄下創(chuàng)建名為hibernate.cfg.xml 的配置文件,并且將它的路徑添加到應(yīng)用的類路徑中就可以完成Hibernate 的配置。該配置文件由Hibernate 用來連接到數(shù)據(jù)庫、生成模式和獲得其它特定數(shù)據(jù)庫信息的屬性組成。要將底層數(shù)據(jù)庫內(nèi)的變動反射到整個應(yīng)用,只需要修改該文件內(nèi)的屬性值。該配置文件的內(nèi)容 如下:
2、創(chuàng)建映射文檔 映射文檔是用來定義持久數(shù)據(jù)和在需要時保存關(guān)于對象的持久域、關(guān)聯(lián)、子類和代理的XML文檔。對于每個持久對象和以 名字class_name.hbm.xml保存的文件來說,都要創(chuàng)建一個映射文檔。在class_name.hbm.xml中class_name就是對 象的類名,下面是Event.hbm.xml的內(nèi)容。
映射文檔在應(yīng)用啟動時編譯,它可為Hibernate 提供關(guān)于持久對象的相應(yīng)類、它們的結(jié)構(gòu)、它們應(yīng)該映射到哪個數(shù)據(jù)庫表格、以及如何映射的信息。Hibernate 也使用這些映射文檔,分別利用內(nèi)建設(shè)備SchemaExport和CodeGenerator來生成相應(yīng)的數(shù)據(jù)庫模式和stub Java類。 3、生成用于持久對象的stub Java類 在創(chuàng)建了映射文檔之后這個任務(wù)就變得簡單的多。stub類的創(chuàng)建使用Hibernate的內(nèi)建設(shè)備 CodeGenerator ,執(zhí)行一個簡單的命令就可以完成。,命令的語法如下: java -cp classpath net.sf.hibernate.tool.hbm2java.CodeGenerator options mapping_files 它為classpath、options、和mapping_files參數(shù)提供了恰當(dāng)?shù)闹怠O旅媸峭ㄟ^映射文檔Event.hbm.xml生成的stub java 類的部分代碼。
4、生成數(shù)據(jù)庫模式 要使用Hibernate的 SchemaExport 來生成數(shù)據(jù)庫模式,在提交了用于參數(shù)的恰當(dāng)值之后執(zhí)行下列命令: java -cp classpath net.sf.hibernate.tool.hbm2ddl.SchemaExport options mapping_files 此命令為classpath、options、和mapping_files 參數(shù)提供了恰當(dāng)?shù)闹怠D2顯示了由映射文檔生成的模式的外形。
5、初始化并運(yùn)行Hibernate的代碼 要初始化和運(yùn)行hibernate,需要采取以下步驟: ·在恰當(dāng)?shù)念愔校跏蓟徒M裝想要的持久對象 ; ·在應(yīng)用啟動時使用net.sf.hibernate.cfg.Configuration 對象獲取net.sf.hibernate.SessionFactory 對象 ; ·調(diào)用SessionFactory 對象上的openSession() 方法來打開net.sf.hibernate.Session ; ·保存想要的對象,關(guān)閉Session。 下面的代碼顯示了如何對上述的步驟進(jìn)行實(shí)現(xiàn):
總結(jié) Hibernate是一個功能強(qiáng)大,可以有效地進(jìn)行數(shù)據(jù)庫數(shù)據(jù)到業(yè)務(wù)對象的O/R映射方案。Hibernate推動了基于普通Java對象模型,用于映射底層數(shù)據(jù)結(jié)構(gòu)的持久對象的開發(fā)。通過將持久層的生成自動擴(kuò)展到一個更大的范圍,Hibernate 使開發(fā)人員專心實(shí)現(xiàn)業(yè)務(wù)邏輯而不用分心于繁瑣的數(shù)據(jù)庫方面的邏輯,同時提供了更加合理的模塊劃分的方法。 |
|