摘要:針對軟件開發中的持久對象與關系數據庫的存儲矛盾,O/R Mapping提供了溝通對象與關系數據庫的橋梁。論文主要在分析對象/關系映射機制的基礎上,引入了目前比較流行對象/關系映射框架:Hibernate,并分析與研究了這個的框架結構和運行機制,最后通過一個實例說明如何利用Hibernate進行對象的持久化操作。
關鍵字:持久對象;關系數據庫;對象/關系映射;Hibernate
中圖分類號:TP393文獻標識碼:A文章編號:1009-3044(2009)33-9294-03
Research and Implementation of Object/Relational Mapping under Java Environment
HU Min, WANG Huan
(Fault of Computer Science and Information, Hefei University of Technology, Hefei 230009, China)
Abstract: Aimed at the storing contradiction that existed between the persistence object and the relational database, Object/Relational Mapping provides a bridge between them. Based on the analysis of object/relational mapping's mechanism, this thesis describes a new and popular object/relation mapping frame: Hibernate, analyses and researches its framework and runnable mechanism. Finally, through an example, this thesis showed how to persist the object using Hibernate.
Key words: persistence object; relational database; O/R mapping; hibernate
隨著軟件開發技術的發展,面向對象分析、設計、開發正逐步成為主流軟件工程技術,然而在數據庫領域,面向對象數據庫產品卻未真正成熟,關系數據庫產品依然是開發的必然選擇。但是對象模型和關系模型有著完全不同的概念和理論,對象模型基于軟件工程的一些原理,例如抽象、封裝、繼承、聚合和多態,而關系數據模型則基于數學原理,特別是集合論的原理。兩種不同的理論基礎導致各自有不同的優缺點。如何將面向對象(OO)技術的優越性與成熟的關系數據庫技術有機地結合起來,這就催生了對象/關系映射(O/R Mapping)技術的產生。
1 O/R Mapping框架概述
使用面向對象的語言訪問關系數據庫最簡單,也是最糟糕的辦法,就是在業務邏輯層中利用大量的SQL硬編碼語句來實現對數據庫中數據的存取。這種模式的優點在于開發的迅速敏捷。但是基于這種模式開發的系統,其維護性和可擴展性差。
一種改進的方法是:在業務類與底層數據庫之間增加數據訪問類,封裝與數據庫相關的各種操作,這樣業務類便脫離了SQL語句,系統的整體結構也更為清晰。這也是當前軟件開發過程中的主流方法,但是這種方法仍然不能使面向對象的開發者完全擺脫數據庫的束縛。
針對上面兩種方法,應用程序開發人員都不能以面向對象的方法來對對象數據進行操作,為此提出了在業務邏輯層和關系數據庫之間增加一個數據持久層,負責實現對象和關系數據庫之間的映射,如圖1所示。業務邏輯層直接獲取或存貯的就是清晰的對象,中間的轉換過程就交給O/R Mapping框架處理了。
2 O/R Mapping機制
O/R Mapping是將對象的狀態映射到數據庫上,以便提供透明的持久化操作。根據對象與關系數據庫的特性,O/R Mapping主要通過以下幾個方面實現:
2.1 對象標識符到主鍵的映射
將類映射成關系數據庫的表時,通常將對象標識符(一般是對象的某個屬性)映射成數據庫表的主鍵即可。
2.2 類屬性到數據表列的映射
在一般情況下,對象的屬性映射到關系數據庫單個字段上;而對于本身就是對象的屬性,一般要映射到多個字段上。
2.3 類到數據表的映射
類到數據表的映射主要討論如何用數據表來表達類之間的繼承關系??梢圆捎玫挠成洳呗灾饕幸韵?種:
1) 整個類層次結構使用一個數據實體:將整個類層次映射到一張數據表中意味著從基類到其所有子孫類的所有屬性都存儲到一張數據表中。
2) 每個具體類使用一個數據實體:使用這種方法,各個子類所特有屬性,聯合從父類中繼承的公共屬性,構成表的結構。父類不映射為數據庫中的實體表,只作為子類公共屬性的載體。
3) 每個類使用一個數據實體:使用這種方法,為每個類創建一張表。增加一個子類時,只需要增加一個表存儲只屬于這個子類的屬性。與前兩者比較,對象與數據庫的耦合程度是最低的。它也能夠很好地支持多態性。這種方法的缺點在于生成子類的實例時,繼承層次多的子類的屬性值還原困難。
2.4 關系映射
類間關系映射為鍵值,這是映射的關鍵,主要是體現類關系中的關聯和聚合,在業務邏輯中以編碼的方式實現其他的關系。
以上所說的O/R Mapping映射機制在實際應用中要根據特定的系統需求,做出適當的取舍。
圍繞對象/關系的映射和持久數據的訪問,在Java領域中發展起來了一些ORM框架,有Hibernate,JDO和Ibatis等,下文將著重分析Hibernate框架。
3 Hibernate
3.1 Hibernate介紹
Hibernate是一個開源的對象關系映射框架,它對JDBC進行了輕量級的對象封裝,使得Java程序員可以隨心所欲地使用對象編程思想來操縱數據庫。整個系統主要有三層:應用層(Application)、基于Hibernate的數據持久層(Persistent layer)、數據庫層(Database)。在應用層主要是對對象進行操作;在數據庫層主要針對的是關系型數據表。中間的Hibernate層的O/R Mapping在對象范例和關系范例中建立映射關系,將應用層中對對象的操作直接作用于關系數據庫中的表,使程序員不用再去關心數據庫的操作問題。
3.2 Hibernate運行機制
理解Hibernate的運行機制對應用程序的編寫很是重要,如圖2就是Hibernate運行機制。
從圖2中可以明顯地看出Hibernate應用首先通過Configuration()方法調用Mapping Documents進行編譯,然后從編譯了的映射文檔集合中創建一個SessionFactory,這個SessionFactory為管理類的持久化提供了一種機制,即Session接口。Session類在持久化數據存儲和應用程序之間提供了一個接口,Session接口封裝了一個JDBC連接,它可以是用戶管理或者是由Hibernate來管理,并且趨向于由單一程序線程使用,然后關閉和丟棄。
4 Hibernate框架的應用
下面以我們常見的高校學生選課管理信息系統(SCMIS)來說明如何利用Hibernate進行數據持久化。
以該系統中選課管理為例,在該例包含二個實體對象學生(Student)、課程(Course)其中學生實體和課程實體是多對多的關系,通過Student__Course關聯表進行關聯。
4.1 配置文件的設置
在選課管理信息系統中相關的配置文件有hibernate.cfg.xml和每個持久化類對應的XML文件。在hibernate.cfg.xml配置文件中,包括配置hibernate連接MS SQL Serser數據庫的驅動信息和映射(mapping)到持久化類的配置信息。在持久化類對應的配置文件中包含了持久化類的聲明,以及類中各個屬性到數據庫表各個字段的映射關系。其屬性可以作為一般值存在也可以是指向其他實體的關聯,其在關系型數據庫中體現為數據表的外鍵。
限于篇幅原,在此僅寫出學生信息表對應的配置文件Student.hbm.xml內容如下:
…………….
4.2 定義持久化類
首先必須編寫2個實體類,分別為每個類的數據成員編寫getXXX(),setXXX()方法,其中XXX表示類的數據成員。其中Student類與Course類是多對多的關系,即每個學生可以選擇多門課程,而每門課程可以被多個學生選中。因此需要在Student類中添加一個Set類作為容器,來存放與本身相對應的Course對象。
public class Student
{/**屬性,和students表中的字段對應**/
private Integer id;
…………..
/**和其它類之間的映射關系**/
Private Set courses;
Public void setId (Integer id)
{this.id = id;}
Public Integer getId () {return id ;}
………………
/**操作和其它對象之間的關系**/
Public void setCourses(Set co)
{this.courses=co;}
Public Set getCourses ()
{return this.courses ;}
}
4.3 聲名管理Session的類(HibernateUtil.java)
該類用于管理session的生成和關閉。在Hibernate中,該session幫助實現和數據庫之間的交互。
Public class HibernateUtil {
Private static final SessionFactory sessionFactory;
Static {
try
{SessionFactory = new Configuration ( ) . Configure ( ) . buildSessionFactory ();}
catch (Throwable ex) {. . . }}
Public static final ThreadLocal session = new ThreadLocal () ;
Public static Session currentSession() {
Session s = (Session) session. get ();
if (s = = 1) {
s = sessionFactory. OpenSession ();
session. set (s) ;}
return s ;}
Public static void closeSession () {
Session s = (Session) session. get () ;
if (s! = 1)
s. close () ;
session. set (1) ;
}}
4.4 業務層代碼
在業務層中,我們就可以使用持久層中的HibernateUtil輔助類生成Session,來完成對對象的持久化,即對對象的保存、更新、刪除、加載、查詢等操作。 如下面就是新建個學生對象,持久化到數據庫中。
Session session=HibernateUtil.currentSession();
Student student=new Student();
Student.setName (“Li Ming”);
……………………
Transaction tx=session.beginTransaction();
session.save (student);
tx.commit;
session. close;
至此持久層就完成了學生對象的持久化操作,從用戶角度來看,只有對象存在,所操作的也只有對象,即應用程序開發人員能夠以統一的、面向對象的方法進行對象數據存取,而不必關心底層關系數據庫中數據存取的實現,從而提高了開發效率。
5 總結
O/R Mapping的出現有效地填補了關系數據庫理論與面向對象理論之間的鴻溝,為基于數據的種種應用的開發提供了一種穩定、高效、擴展性極佳的解決方案。作為一個優秀的持久層框架實現,Hibernate可以有效地進行數據庫數據到業務對象的O/R映射,使得程序員專心地實現業務邏輯,而不用分心于繁瑣的數據庫方面的邏輯,從而提高開發成本和效率。
參考文獻:
[1] Hibernate.Object/relational mapping and object persistence For java[EB/OL].http://hibernate.bluemars.net/.
[2] Ambler S W.Mapping Objects to Relational Databases:O/R Mapping In Detail[EB/OL].http://www.agiledata.org/essays/mappingObjects.html.
[3] 田珂,謝世波,方馬.J2EE 數據持久層的解決方案[J].計算機工程,2003,29(22):93-95.
[4] 何錚,陳志剛.對象/關系映射框架的研究與應用[J].計算機工程與應用,2003,26(6):188-191.
[5] 徐茹枝,丁昊志,單波.對象關系映射框架的研究與設計[J].華北電力大學學報,2006,33(4):69-72.
[6] 夏聽,曹曉鋼,唐勇.深入淺出HIBERNATE[M].北京:電子工業出版社,2005.
[7] 孫衛琴.精通HIBERNATE:Java對象持久化技術詳解[M].北京:電子工業出版社,2005.