Hibernate實(shí)現(xiàn)ORM:簡(jiǎn)介及背景
ORM(Object/Relation Mapping)是一種為了解決面向?qū)ο笈c關(guān)系數(shù)據(jù)庫(kù)存在的互不匹配的現(xiàn)象的技術(shù)。 簡(jiǎn)單的說(shuō),ORM是通過(guò)使用描述對(duì)象和數(shù)據(jù)庫(kù)之間映射的元數(shù)據(jù),將Java程序中的對(duì)象自動(dòng)持久化到關(guān)系數(shù)據(jù)庫(kù)中。本質(zhì)上就是將數(shù)據(jù)從一種形式轉(zhuǎn)換到另外一種形式。 雖然同時(shí)暗示者額外的執(zhí)行開(kāi)銷;但是如果ORM作為一種中間件實(shí)現(xiàn),則會(huì)有很多機(jī)會(huì)做優(yōu)化,而這些在手寫(xiě)的持久層并不存在。 更重要的是用于控制轉(zhuǎn)換的元數(shù)據(jù)需要提供和管理;但是同樣,這些花費(fèi)要比維護(hù)手寫(xiě)的方案要少;而且就算是遵守ODMG (Object Data Management Group )規(guī)范的對(duì)象數(shù)據(jù)庫(kù)依然需要類級(jí)別的元數(shù)據(jù)(Meta Data)。
ORM是隨著面向?qū)ο蟮能浖_(kāi)發(fā)方法發(fā)展而產(chǎn)生的。面向?qū)ο蟮拈_(kāi)發(fā)方法是當(dāng)今企業(yè)級(jí)應(yīng)用開(kāi)發(fā)環(huán)境中的主流開(kāi)發(fā)方法,關(guān)系數(shù)據(jù)庫(kù)是企業(yè)級(jí)應(yīng)用環(huán)境中永久存放數(shù)據(jù)的主流數(shù)據(jù)存儲(chǔ)系統(tǒng)。對(duì)象和關(guān)系數(shù)據(jù)是業(yè)務(wù)實(shí)體的兩種表現(xiàn)形式,業(yè)務(wù)實(shí)體在內(nèi)存中表現(xiàn)為對(duì)象,在數(shù)據(jù)庫(kù)中表現(xiàn)為關(guān)系數(shù)據(jù)。內(nèi)存中的對(duì)象之間存在關(guān)聯(lián)和繼承關(guān)系,而在數(shù)據(jù)庫(kù)中,關(guān)系數(shù)據(jù)無(wú)法直接表達(dá)多對(duì)多關(guān)聯(lián)和繼承關(guān)系。因此, ORM系統(tǒng)一般以中間件的形式存在,主要實(shí)現(xiàn)程序?qū)ο蟮疥P(guān)系數(shù)據(jù)庫(kù)數(shù)據(jù)的映射。
使用ORM的元數(shù)據(jù)描述對(duì)象與數(shù)據(jù)庫(kù)間的映射,可以提高系統(tǒng)的開(kāi)發(fā)效率和系統(tǒng)性能,具有可維護(hù)性和廠家獨(dú)立性。Hibernate作為ORM框架的典型代表具有成熟、流行、功能強(qiáng)大的優(yōu)點(diǎn)。并逐漸發(fā)展成Java 持久層事實(shí)上的標(biāo)準(zhǔn)。
在OOD(Object-Oriented Design)中我們用對(duì)象來(lái)描述真實(shí)世界,但在關(guān)系數(shù)據(jù)庫(kù)還是數(shù)據(jù)的常用永久存儲(chǔ)技術(shù)背景下,我們需要一種有效技術(shù)來(lái)完成對(duì)象到關(guān)系數(shù)據(jù)的轉(zhuǎn)化(即對(duì)象的持久化)。而對(duì)象之間有許多關(guān)系數(shù)據(jù)無(wú)法表達(dá)的概念,如關(guān)聯(lián)和繼承等。如果直接通過(guò)JDBC來(lái)開(kāi)發(fā)自己的持久化層很有可能影響項(xiàng)目的進(jìn)度和持久層的可靠性,并嚴(yán)重影響代碼的可維護(hù)性。
Hibernate是一種運(yùn)用DAO(Data Access Object)設(shè)計(jì)模式來(lái)實(shí)現(xiàn)對(duì)象和關(guān)系數(shù)據(jù)庫(kù)之間映射(O/R Mapping)的開(kāi)源框架。它對(duì)JDBC進(jìn)行了輕量級(jí)的對(duì)象封裝,使得Java程序員可以完全使用面向?qū)ο蟮木幊趟季S來(lái)操作關(guān)系數(shù)據(jù)庫(kù),是持久層的一項(xiàng)實(shí)現(xiàn)技術(shù)。相比于其它持久層實(shí)現(xiàn)技術(shù)如JDBC、EJB(Entity Beans)、JDO(Java Data Object)等,Hibernate易于掌握,更加符合編程人員的面向?qū)ο笏季S,Hibernate擁有自己的一種查詢語(yǔ)言(HQL),它是完全面向?qū)ο蟮摹?/P>
Hibernate通過(guò)創(chuàng)建與數(shù)據(jù)庫(kù)中的表對(duì)應(yīng)的持久化對(duì)象,然后再通過(guò)影射文件將持久化對(duì)象中的屬性與數(shù)據(jù)庫(kù)表中的字段對(duì)應(yīng)起來(lái)。為Java 程序員提供了面向?qū)ο蟮腁PI和接口來(lái)操縱數(shù)據(jù)庫(kù),從而避免了在業(yè)務(wù)邏輯中嵌入大量的JDBC訪問(wèn)和事物控制代碼。Hibernate運(yùn)行時(shí)的結(jié)構(gòu)如下圖。
其中,SessionFactory保存了對(duì)當(dāng)前數(shù)據(jù)庫(kù)配置的所有映射關(guān)系,它是將某個(gè)數(shù)據(jù)庫(kù)的映射關(guān)系經(jīng)過(guò)編譯之后全部保存在內(nèi)存中的。它還是生成Session的工廠,它在進(jìn)行實(shí)例化的過(guò)程中將會(huì)用到ConnectionProvider。一個(gè)SessionFactory對(duì)應(yīng)一個(gè)數(shù)據(jù)庫(kù)連接,當(dāng)數(shù)據(jù)庫(kù)連接改變時(shí)需要修改SessionFactory 。Session是進(jìn)行持久化操作的基礎(chǔ),所有的持久化操作都是在Session的基礎(chǔ)上進(jìn)行的。它相當(dāng)與JDBC中的Connection。它是Hibernate的持久化管理器的核心,提供了一系列的持久化操作方法。另外,它還持有一個(gè)針對(duì)持久化對(duì)象的一級(jí)緩存,在遍歷持久化對(duì)象或者根據(jù)持久化標(biāo)識(shí)查找對(duì)象的時(shí)候會(huì)用到。Transaction在功能上和數(shù)據(jù)庫(kù)中的事務(wù)完全一樣,通過(guò)它實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)中事務(wù)的控制。Transaction對(duì)象是Session對(duì)象產(chǎn)生的,所以他的生命周期比Session短。一個(gè)Session的生命周期中可以有多個(gè)Transaction對(duì)象。ConnectionProvider的主要作用是生成與數(shù)據(jù)庫(kù)建立了連接的JDBC對(duì)象,同時(shí)他還作為數(shù)據(jù)庫(kù)連接的緩沖池。通過(guò)ConnectionProvider實(shí)現(xiàn)了應(yīng)用程序和底層的DataSource和DriverManager的隔離。TransactionFactory:是生成Transaction對(duì)象的工廠,通過(guò)TransactionFactory實(shí)現(xiàn)了事務(wù)的封裝,使其具體的實(shí)現(xiàn)方法與應(yīng)用程序無(wú)關(guān)。
Hibernate作為持久層的主流框架,不僅可以應(yīng)用在桌面應(yīng)用程序開(kāi)發(fā),也可以用在WEB應(yīng)用程序的開(kāi)發(fā)。從前面的分析可以看出,Hibernate使用數(shù)據(jù)庫(kù)和配置信息來(lái)為應(yīng)用程序提供持久化服務(wù)(以及持久的對(duì)象)。系統(tǒng)使用的Hibernate的是一個(gè)全面的體系結(jié)構(gòu),將應(yīng)用層從底層的JDBC(Java Data Base Connectivity)/JTA(Java Transaction API)/JNDI(Java Naming and Directory Interface)中抽象出來(lái),而讓Hibernate來(lái)處理這些細(xì)節(jié)。