摘要 在Java技術中有許多方法可以對數據進行持久化,持久層也是Java應用程序中最重要的部分之一。本文在分析了3種持久層主流解決方案的基礎上,介紹了O-R映射開源項目Hibernate,并介紹了在Web應用開發中怎樣配置Hibernate的環境,并使用它建立一個應用。
關鍵字 hibernate,數據持久化,JDBC, EJB,JDO
數據持久層簡介
J2EE的三層結構是指表示層(Presentation),業務邏輯層(Business Logic)以及基礎架構層(Infrastructure),這樣的劃分非常經典,但是在實際的項目開發法中,開發者通常對三層結構進行擴展來滿足一些項目的具體要求,一個最常用的擴展就是將三層體系擴展為五層體系,即表示層(Presentation),控制/中介層(Controller/Mediator)、領域層(Domain),數據持久層(Data Persistence)和數據源層(Data Source)。它其實是在三層架構中增加了兩個中間層?刂/中介層位于表示層和領域層之間,數據持久層位于領域層和基礎架構層之間。由于對象范例和關系范例這兩大領域之間存在“阻抗不匹配”,所以把數據持久層單獨作為J2EE體系的一個層提出來的原因就是能夠在對象-關系數據庫之間提供一個成功的企業級映射解決方案,盡最大可能彌補這兩種范例之間的差異。
三種持久層主流解決方案
1、JDBC
許多開發者用JDBC進行數據庫程序的開發。此中方式很多情況下都使用DAO模式,采用SQL進行查詢。雖然用此方式可以使應用程序代碼與具體的數據庫廠商和數據庫位置無關,不過JDBC是低級別的數據庫訪問方式,JDBC并不支持面向對象的數據庫表示。JDBC數據庫表示完全圍繞關系數據庫模型。在大型應用程序的DAO中書寫這樣的代碼,維護量是非常大的。
2、EJB
在J2EE的規范中,為EJB定義了兩種持久化的解決方案:一種是BMP,另一種是CMP。其中CMP不需要將SQL語句加入到代碼中。目前,在采用J2EE的應用中,EJB CMP方式得到了廣泛應用。更加引人注意的是,隨著EJB規范的發展,CMP也包含了一些高級關系的內容。但是,CMP的使用比較復雜,對很多開發人員來說比較難以掌握。而且,不是在所有的情況下都適合在系統中采用EJB,而且想要非常清楚的了解EJB規范也是非常費時的。在用EJB編碼前,先要讓專家理解API,然后需要了解每一個容器部署時所要關注的技術。此外,許多情況下商用容器的性能和支持也不是很好。
3、JDO
JDO是一個存儲java對象的規范,JDO規范1.0的提出可以使你將精力集中在設計Java對象模型,然后在企業應用軟件架構的不同層面中存儲傳統的Java對象(Plain Old Java Objects,簡稱POJOs),采用JDOQL語言進行SQL操作。一些公司(包括sun)企圖根據JDO規范進行設計并實現JDO產品,然而他們都不能很好的進行實現,并且性能優化上比較差。
數據持久層新的解決方案Hibernate
1、Hibernate介紹
Hibernate是一個開放源代碼的對象關系映射框架,它對JDBC進行了輕量級的對象封裝,使Java程序員可以隨心所欲的使用對象編程思維來操縱數據庫。它不僅提供了從Java類到數據表之間的映射,也提供了數據查詢和恢復機制。相對于使用JDBC和SQL來手工操作數據庫, Hibernate可以大大減少操作數據庫的工作量。 另外Hibernate可以利用代理模式來簡化載入類的過程,這將大大減少利用Hibernate QL從數據庫提取數據的代碼的編寫量,從而節約開發時間和開發成本Hibernate可以和多種Web服務器或者應用服務器良好集成,如今已經支持幾乎所有的流行的數據庫服務器。
2、Hibernate原理
Hibernate技術本質上是一個提供數據庫服務的中間件。它的架構如圖1所示:
圖1
圖1顯示了hibernate的工作原理,它是利用數據庫以及其他一些配置文件如hibernate.properties,XML Mapping等來為應用程序提供數據持久化服務的。
Hibernate具有很大的靈活性,但同時它的體系結構比較復雜,提供了好幾種不同的運行方式。在輕型體系中,應用程序提供JDBC連接,并且自行管理事務,這種方式使用了Hibernate的一個最小子集;在全面解決體系中,對于應用程序來說,所有底層的JDBC/JTA API都被抽象了,Hibernate會替你照管所有的細節。
使用Hibernate建立一個應用
1、配置Hibernate
在src 目錄下創建名為hibernate.cfg.xml 的配置文件,并且將它的路徑添加到應用的類路徑中就可以完成Hibernate 的配置。該配置文件由Hibernate 用來連接到數據庫、生成模式和獲得其它特定數據庫信息的屬性組成。要將底層數據庫內的變動反射到整個應用,只需要修改該文件內的屬性值。該配置文件的內容如下:
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">
<hibernate-configuration>
<session-factory>
。紁roperty name="hibernate.connection.driver_class">COM.ibm.db2.jdbc.app.DB2Driver</property>
。紁roperty name="hibernate.connection.url">jdbc:db2:cipDB</property>
。紁roperty name="hibernate.connection.username">admin</property>
。紁roperty name="hibernate.connection.password">rubipass</property>
。紁roperty name="dialect">cirrus.hibernate.sql.DB2Dialect</property>
。糾apping resource="com/ubipass/cip/data/Event.hbm.xml"/>
</session-factory>
</hibernate-configuration>
映射文檔是用來定義持久數據和在需要時保存關于對象的持久域、關聯、子類和代理的XML文檔。對于每個持久對象和以名字class_name.hbm.xml保存的文件來說,都要創建一個映射文檔。在class_name.hbm.xml中class_name就是對象的類名,下面是Event.hbm.xml的內容。
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
。糲lass name="com.ubipass.cip.Event" table="EVENTS">
。糹d name="id" column="uid" type="long">
。糶enerator class="increment"/>
。/id>
。紁roperty name="date" column="event_date" type="timestamp"/>
。紁roperty name="title" column="event_title" type="string"/>
。/class>
</hibernate-mapping>
映射文檔在應用啟動時編譯,它可為Hibernate 提供關于持久對象的相應類、它們的結構、它們應該映射到哪個數據庫表格、以及如何映射的信息。Hibernate 也使用這些映射文檔,分別利用內建設備SchemaExport和CodeGenerator來生成相應的數據庫模式和stub Java類。
3、生成用于持久對象的stub Java類
在創建了映射文檔之后這個任務就變得簡單的多。stub類的創建使用Hibernate的內建設備 CodeGenerator ,執行一個簡單的命令就可以完成。,命令的語法如下:
java -cp classpath net.sf.hibernate.tool.hbm2java.CodeGenerator
options mapping_files
它為classpath、options、和mapping_files參數提供了恰當的值。下面是通過映射文檔Event.hbm.xml生成的stub java 類的部分代碼。
package com.ubipass.cip
public class Event {
private String title;
……
Event(){ }
public Long getId() {
return id;
}
private void setId(Long id) {
this.id = id;
}
……
}
4、生成數據庫模式
要使用Hibernate的 SchemaExport 來生成數據庫模式,在提交了用于參數的恰當值之后執行下列命令:
java -cp classpath net.sf.hibernate.tool.hbm2ddl.SchemaExport options mapping_files
此命令為classpath、options、和mapping_files 參數提供了恰當的值。圖2顯示了由映射文檔生成的模式的外形。
圖2
5、初始化并運行Hibernate的代碼
要初始化和運行hibernate,需要采取以下步驟:
- 在恰當的類中,初始化和組裝想要的持久對象 ;
- 在應用啟動時使用net.sf.hibernate.cfg.Configuration 對象獲取net.sf.hibernate.SessionFactory 對象 ;
- 調用SessionFactory 對象上的openSession() 方法來打開net.sf.hibernate.Session ;
- 保存想要的對象,關閉Session。
下面的代碼顯示了如何對上述的步驟進行實現:
// 初始化持久對象
Event ev = new Event();
ev.setDate("1/4/2004")
ev.setTitle("Hibernate startup");
try {
//開始Hibernate
Configuration cfg = new Configuration().addClass(Event.class);
SessionFactory sf = cfg.buildSessionFactory();
//打開 Session
Session sess = sf.openSession();
} catch (HibernateException e) {
e.printStackTrace();
}
//保存 Product 并關閉 Session
Transaction t = sess.beginTransaction();
sess.save(ev);
t.commit();
sess.close();
總結
Hibernate是一個功能強大,可以有效地進行數據庫數據到業務對象的O/R映射方案。Hibernate推動了基于普通Java對象模型,用于映射底層數據結構的持久對象的開發。通過將持久層的生成自動擴展到一個更大的范圍,Hibernate 使開發人員專心實現業務邏輯而不用分心于繁瑣的數據庫方面的邏輯,同時提供了更加合理的模塊劃分的方法。
文章來源于領測軟件測試網 http://www.kjueaiud.com/