Hibernate工作原理
??????現(xiàn)在我們知道了一個(gè)概念Hibernate Session,只有處于Session管理下的POJO才具有持久化操作能力。當(dāng)應(yīng)用程序?qū)τ谔幱?span style="color:#3333ff;">Session管理下的POJO實(shí)例執(zhí)行操作時(shí),Hibernate將這種面向?qū)ο蟮牟僮鬓D(zhuǎn)換成了持久化操作能力。
HIbernate簡(jiǎn)要的體系結(jié)構(gòu)如下圖所示:
??????? 通過(guò)上圖能夠發(fā)現(xiàn)HIbernate需要一個(gè)hibernate.properties文件,該文件用于配置Hibernate和數(shù)據(jù)庫(kù)連接的信息。還需要一個(gè)XML文件,該映射文件確定了持久化類(lèi)和數(shù)據(jù)表、數(shù)據(jù)列之間的想對(duì)應(yīng)關(guān)系。
除了使用hibernate.properties文件,還可以采用另一種形式的配置文件: *.cfg.xml文件。在實(shí)際應(yīng)用中,采用XML配置文件的方式更加廣泛,兩種配置文件的實(shí)質(zhì)是一樣的。
??????? Hibernate的持久化解決方案將用戶從赤裸裸的JDBC訪問(wèn)中釋放出來(lái),用戶無(wú)需關(guān)注底層的JDBC操作,而是以面向?qū)ο蟮姆绞竭M(jìn)行持久層操作。底層數(shù)據(jù)連接的獲得、數(shù)據(jù)訪問(wèn)的實(shí)現(xiàn)、事務(wù)控制都無(wú)需用戶關(guān)心。這是一種“全面解決”的體系結(jié)構(gòu)方案,將應(yīng)用層從底層的JDBC/JTA API中抽象出來(lái)。通過(guò)配置文件來(lái)管理底層的JDBC連接,讓Hibernate解決持久化訪問(wèn)的實(shí)現(xiàn)。這種“全面解決”方案的體系結(jié)構(gòu)圖如圖所示:
??????? 針對(duì)以上的Hibernate全面解決方案架構(gòu)圖:
????? (1)SessionFactory:這是Hibernate的關(guān)鍵對(duì)象,它是單個(gè)數(shù)據(jù)庫(kù)映射關(guān)系經(jīng)過(guò)編譯后的內(nèi)存鏡像,它也是線程安全的。它是生成Session的工廠,本身要應(yīng)用到ConnectionProvider,該對(duì)象可以在進(jìn)程和集群的級(jí)別上,為那些事務(wù)之間可以重用的數(shù)據(jù)提供可選的二級(jí)緩存。
????? (2)Session:它是應(yīng)用程序和持久存儲(chǔ)層之間交互操作的一個(gè)單線程對(duì)象。它也是Hibernate持久化操作的關(guān)鍵對(duì)象,所有的持久化對(duì)象必須在Session的管理下才能夠進(jìn)行持久化操作。此對(duì)象的生存周期很短,其隱藏了JDBC連接,也是Transaction 的工廠。Session對(duì)象有一個(gè)一級(jí)緩存,現(xiàn)實(shí)執(zhí)行Flush之前,所有的持久化操作的數(shù)據(jù)都在緩存中Session對(duì)象處。
??????(3)持久化對(duì)象:系統(tǒng)創(chuàng)建的POJO實(shí)例一旦與特定Session關(guān)聯(lián),并對(duì)應(yīng)數(shù)據(jù)表的指定記錄,那該對(duì)象就處于持久化狀態(tài),這一系列的對(duì)象都被稱為持久化對(duì)象。程序中對(duì)持久化對(duì)象的修改,都將自動(dòng)轉(zhuǎn)換為持久層的修改。持久化對(duì)象完全可以是普通的Java Beans/POJO,唯一的特殊性是它們正與Session關(guān)聯(lián)著。
????? (4)瞬態(tài)對(duì)象和脫管對(duì)象:系統(tǒng)進(jìn)行new關(guān)鍵字進(jìn)行創(chuàng)建的Java 實(shí)例,沒(méi)有Session 相關(guān)聯(lián),此時(shí)處于瞬態(tài)。瞬態(tài)實(shí)例可能是在被應(yīng)用程序?qū)嵗?#xff0c;尚未進(jìn)行持久化的對(duì)象。如果一個(gè)曾今持久化過(guò)的實(shí)例,但因?yàn)镾ession的關(guān)閉而轉(zhuǎn)換為脫管狀態(tài)。
????? (5)事務(wù)(Transaction):代表一次原子操作,它具有數(shù)據(jù)庫(kù)事務(wù)的概念。但它通過(guò)抽象,將應(yīng)用程序從底層的具體的JDBC、JTA和CORBA事務(wù)中隔離開(kāi)。在某些情況下,一個(gè)Session 之內(nèi)可能包含多個(gè)Transaction對(duì)象。雖然事務(wù)操作是可選的,但是所有的持久化操作都應(yīng)該在事務(wù)管理下進(jìn)行,即使是只讀操作。
????? (6)連接提供者(ConnectionProvider):它是生成JDBC的連接的工廠,同時(shí)具備連接池的作用。他通過(guò)抽象將底層的DataSource和DriverManager隔離開(kāi)。這個(gè)對(duì)象無(wú)需應(yīng)用程序直接訪問(wèn),僅在應(yīng)用程序需要擴(kuò)展時(shí)使用。
????? (7)事務(wù)工廠(TransactionFactory):他是生成Transaction對(duì)象實(shí)例的工廠。該對(duì)象也無(wú)需應(yīng)用程序的直接訪問(wèn)。
? Hibernate進(jìn)行持久化操作離不開(kāi)SessionFactory對(duì)象,這個(gè)對(duì)象是整個(gè)數(shù)據(jù)庫(kù)映射關(guān)系經(jīng)過(guò)編譯后的內(nèi)存鏡像,該對(duì)象的openSession()方法可打開(kāi)Session對(duì)象。SessionFactory對(duì)想是由Configuration對(duì)象產(chǎn)生。
每個(gè)Hibernate配置文件對(duì)應(yīng)一個(gè)configuration對(duì)象。在極端情況下,不使用任何配置文件,也可以創(chuàng)建Configuration對(duì)象。
?
一. 創(chuàng)建Configuration對(duì)象
??????? org.hibernate.cfg.Configuration實(shí)例代表一個(gè)應(yīng)用程序到SQL數(shù)據(jù)庫(kù)的映射配置,Configuration提供了一個(gè)buildSessionFactory()方法,該方法可以產(chǎn)生一個(gè)不可變的SessionFactory對(duì)象。
??????? 你可以直接實(shí)例化Configuration來(lái)獲取一個(gè)實(shí)例,并為它指定一個(gè)Hibernate映射文件,如果映射文件在類(lèi)加載路徑中,則可以使用addResource()方法來(lái)添加映射定義文件。那么現(xiàn)在的問(wèn)題就是如何創(chuàng)建Configuration對(duì)象呢?
隨著Hibernate 所使用的配置文件的不同,創(chuàng)建Configuration對(duì)象的方式也不相同。通常有幾種配置Hibernate的方式:
第一種是使用hibernate.properties文件作為配置文件。
第二種是使用hibernate.cfg.xml文件作為配置文件。
第三種是不使用任何的配置文件,以編碼方式來(lái)創(chuàng)建Configuration對(duì)象。
請(qǐng)注意:Configuration對(duì)象的唯一作用就是創(chuàng)建SessionFactory實(shí)例,所以它才被設(shè)計(jì)成為啟動(dòng)期間對(duì)象,而一旦SessionFactory對(duì)象創(chuàng)建完成,它就被丟棄了。
?
1. 使用hibernateproperties作為配置文件
??????? 對(duì)于hibernate.properties作為配置文件的方式,比較適合于初學(xué)者。因?yàn)槌鯇W(xué)者往往很難記住該配置文件的格式,以及需要配置哪些屬性。在Hibernate發(fā)布包的etc路徑下,提供了一個(gè)hibernate.properties文件,該文件列出了Hibernate 的所有屬性。每個(gè)配置段都給出了大致的注釋,用戶只要取消所需配置段的注釋,就可以快速配置Hibernate和數(shù)據(jù)庫(kù)的鏈接此處給出使用hibernate.properties文件創(chuàng)建Configuration對(duì)象的方法。
//實(shí)例化configuration對(duì)象 Configuration cfg = new Configuration() //多次調(diào)用addResource()方法,添加映射文件 .addResource("Item.hbm.xml") .addResource("Bid.hbm.xml");??????? 查看hibernate.properties文件發(fā)現(xiàn),該文件沒(méi)有提供Hibernate映射文件的方式。因此使用hibernate.properties文件來(lái)作為配置文件時(shí),必須使用Configuration的.addResource()方法,使用該方法來(lái)添加映射文件。
注意:正如上面的代碼所示,使用hibernate.properties文件配置Hibernate的屬性固然簡(jiǎn)單,但是因?yàn)橐謩?dòng)添加映射文件,當(dāng)映射文件極其多時(shí),這是一件非常催人淚下的事情。這也就是在實(shí)際開(kāi)發(fā)中,不常使用hibernate.properties文件作為配置文件的原因。
??????? 當(dāng)然還有另一種添加配置文件的策略,因?yàn)橛成湮募统志没?lèi)是一一對(duì)應(yīng)的,可以通過(guò)Configuration對(duì)象來(lái)添加持久化類(lèi),讓Hibernate自己來(lái)搜索映射文件。
//實(shí)例化configuration對(duì)象 Configuration cfg = new Configuration) //多次調(diào)用addClass()方法,直接添加持久化類(lèi) .addClass(ppp.Item.class) .addClass(ppp.BId.class);?
2. 使用hibernate.cfg.xml作為配置文件
???????? 前面已經(jīng)看到使用hibernate.properties作為配置文件的情形。因?yàn)閔ibernate.cfg.xml中已經(jīng)添加了hibernate的映射文件,采用這種配置文件創(chuàng)建configuration對(duì)象實(shí)例由以下代碼實(shí)現(xiàn):
//實(shí)例化configuration對(duì)象 Configuration cfg = new Configuration() //configure()方法將會(huì)負(fù)責(zé)加載hibernate.cfg.xml文件 .configure()??????? 需要注意的是:在通過(guò)new關(guān)鍵字創(chuàng)建Configuration對(duì)象之后,不要忘記調(diào)用configure()方法。
?
二. hibernate.properties和hiberntae.cfg.xml文件
??????? 如果使用etc路徑下的hibernate.properties文件作為配置文件的模板,修改此模板文件作為Hibernate配置文件,這種方式的確是快速進(jìn)入Hibernate開(kāi)發(fā)的方法。但是對(duì)于實(shí)際開(kāi)發(fā),通常會(huì)使用hibernate.cfg.xml文件作為配置文件。
深入對(duì)比hibernate.properties和hibernate.cfg.xml文件后看如下的hibernate.properties的一個(gè)配置屬性:
//指定數(shù)據(jù)庫(kù)的方言 hibernate.dialect org.hibernate.dialect.MySQLDialect上面的一行代碼是典型的Properties文件的的格式,前面的key為hibernate.dialect?, 后面的value是為org.hibernate.dialect.MySQLDialect。
接下來(lái)我們?cè)賮?lái)查看hibernate.cfg.xml文件中的相對(duì)應(yīng)的配置代碼:
<property name = "dialect">org.hibernate.dialect.MySQLDialect</property>同樣指定了Hibernate的Dialect 屬性是org.hibernate.dialect.MySQLDialect 。對(duì)比兩種格式的文件,可以發(fā)現(xiàn)雖然格式不同但其實(shí)質(zhì)完全一樣。
總結(jié)
以上是生活随笔為你收集整理的Hibernate工作原理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Subversion客户端认证凭证缓存总
- 下一篇: 如何安装,卸载eclipse中的ADT,