Hibernate工做原理

      如今咱們知道了一個概念Hibernate Session,只有處於Session管理下的POJO才具備持久化操做能力。當應用程序對於處於Session管理下的POJO實例執行操做時,Hibernate將這種面向對象的操做轉換成了持久化操做能力。html

HIbernate簡要的體系結構以下圖所示:java

        經過上圖可以發現HIbernate須要一個hibernate.properties文件,該文件用於配置Hibernate和數據庫鏈接的信息。還須要一個XML文件,該映射文件肯定了持久化類和數據表、數據列之間的想對應關係。數據庫

除了使用hibernate.properties文件,還能夠採用另外一種形式的配置文件: *.cfg.xml文件。在實際應用中,採用XML配置文件的方式更加普遍,兩種配置文件的實質是同樣的。緩存

        Hibernate的持久化解決方案將用戶從赤裸裸的JDBC訪問中釋放出來,用戶無需關注底層的JDBC操做,而是以面向對象的方式進行持久層操做。底層數據鏈接的得到、數據訪問的實現、事務控制都無需用戶關心。這是一種「全面解決」的體系結構方案,將應用層從底層的JDBC/JTA API中抽象出來。經過配置文件來管理底層的JDBC鏈接,讓Hibernate解決持久化訪問的實現。這種「全面解決」方案的體系結構圖如圖所示:安全

        針對以上的Hibernate全面解決方案架構圖:架構

      (1)SessionFactory這是Hibernate的關鍵對象,它是單個數據庫映射關係通過編譯後的內存鏡像,它也是線程安全的它是生成Session的工廠,自己要應用到ConnectionProvider,該對象能夠在進程和集羣的級別上,爲那些事務之間能夠重用的數據提供可選的二級緩存。ide

      (2)Session:它是應用程序和持久存儲層之間交互操做的一個單線程對象。它也是Hibernate持久化操做的關鍵對象,全部的持久化對象必須在Session的管理下才可以進行持久化操做。此對象的生存週期很短,其隱藏了JDBC鏈接,也是Transaction 的工廠。Session對象有一個一級緩存,現實執行Flush以前,全部的持久化操做的數據都在緩存中Session對象處。ui

      (3)持久化對象:系統建立的POJO實例一旦與特定Session關聯,並對應數據表的指定記錄,那該對象就處於持久化狀態,這一系列的對象都被稱爲持久化對象。程序中對持久化對象的修改,都將自動轉換爲持久層的修改。持久化對象徹底能夠是普通的Java Beans/POJO,惟一的特殊性是它們正與Session關聯着。編碼

      (4)瞬態對象和脫管對象:系統進行new關鍵字進行建立的Java 實例,沒有Session 相關聯,此時處於瞬態。瞬態實例多是在被應用程序實例化後,還沒有進行持久化的對象。若是一個曾今持久化過的實例,但由於Session的關閉而轉換爲脫管狀態。spa

      (5)事務(Transaction):表明一次原子操做,它具備數據庫事務的概念。但它經過抽象,將應用程序從底層的具體的JDBC、JTA和CORBA事務中隔離開。在某些狀況下,一個Session 以內可能包含多個Transaction對象。雖然事務操做是可選的,可是全部的持久化操做都應該在事務管理下進行,即便是隻讀操做。

      (6)鏈接提供者(ConnectionProvider):它是生成JDBC的鏈接的工廠,同時具有鏈接池的做用。他經過抽象將底層的DataSource和DriverManager隔離開。這個對象無需應用程序直接訪問,僅在應用程序須要擴展時使用。

      (7)事務工廠(TransactionFactory):他是生成Transaction對象實例的工廠。該對象也無需應用程序的直接訪問。

  Hibernate進行持久化操做離不開SessionFactory對象,這個對象是整個數據庫映射關係通過編譯後的內存鏡像,該對象的openSession()方法可打開Session對象。SessionFactory對想是由Configuration對象產生。

每一個Hibernate配置文件對應一個configuration對象。在極端狀況下,不使用任何配置文件,也能夠建立Configuration對象。

 

一. 建立Configuration對象

        org.hibernate.cfg.Configuration實例表明一個應用程序到SQL數據庫的映射配置,Configuration提供了一個buildSessionFactory()方法,該方法能夠產生一個不可變的SessionFactory對象。

        你能夠直接實例化Configuration來獲取一個實例,併爲它指定一個Hibernate映射文件,若是映射文件在類加載路徑中,則可使用addResource()方法來添加映射定義文件。那麼如今的問題就是如何建立Configuration對象呢?

隨着Hibernate 所使用的配置文件的不一樣,建立Configuration對象的方式也不相同。一般有幾種配置Hibernate的方式:

第一種是使用hibernate.properties文件做爲配置文件。

第二種是使用hibernate.cfg.xml文件做爲配置文件。

第三種是不使用任何的配置文件,以編碼方式來建立Configuration對象。

請注意:Configuration對象的惟一做用就是建立SessionFactory實例,因此它才被設計成爲啓動期間對象,而一旦SessionFactory對象建立完成,它就被丟棄了。

 

1. 使用hibernateproperties做爲配置文件

        對於hibernate.properties做爲配置文件的方式,比較適合於初學者。由於初學者每每很難記住該配置文件的格式,以及須要配置哪些屬性。在Hibernate發佈包的etc路徑下,提供了一個hibernate.properties文件,該文件列出了Hibernate 的全部屬性。每一個配置段都給出了大體的註釋,用戶只要取消所需配置段的註釋,就能夠快速配置Hibernate和數據庫的連接此處給出使用hibernate.properties文件建立Configuration對象的方法。

//實例化configuration對象
Configuration cfg = new Configuration()
//屢次調用addResource()方法,添加映射文件
.addResource("Item.hbm.xml")
.addResource("Bid.hbm.xml");

        查看hibernate.properties文件發現,該文件沒有提供Hibernate映射文件的方式。所以使用hibernate.properties文件來做爲配置文件時,必須使用Configuration的.addResource()方法,使用該方法來添加映射文件。

注意:正如上面的代碼所示,使用hibernate.properties文件配置Hibernate的屬性當然簡單,可是由於要手動添加映射文件,當映射文件極其多時,這是一件很是催人淚下的事情。這也就是在實際開發中,不常使用hibernate.properties文件做爲配置文件的緣由。

        固然還有另外一種添加配置文件的策略,由於映射文件和持久化類是一一對應的,能夠經過Configuration對象來添加持久化類,讓Hibernate本身來搜索映射文件。

//實例化configuration對象
Configuration cfg = new Configuration)
//屢次調用addClass()方法,直接添加持久化類
.addClass(ppp.Item.class)
.addClass(ppp.BId.class);

 

2. 使用hibernate.cfg.xml做爲配置文件

         前面已經看到使用hibernate.properties做爲配置文件的情形。由於hibernate.cfg.xml中已經添加了hibernate的映射文件,採用這種配置文件建立configuration對象實例由如下代碼實現:

//實例化configuration對象
Configuration cfg = new Configuration()
//configure()方法將會負責加載hibernate.cfg.xml文件
.configure()

        須要注意的是:在經過new關鍵字建立Configuration對象以後,不要忘記調用configure()方法。

 

二. hibernate.properties和hiberntae.cfg.xml文件

        若是使用etc路徑下的hibernate.properties文件做爲配置文件的模板,修改此模板文件做爲Hibernate配置文件,這種方式的確是快速進入Hibernate開發的方法。可是對於實際開發,一般會使用hibernate.cfg.xml文件做爲配置文件。

深刻對比hibernate.properties和hibernate.cfg.xml文件後看以下的hibernate.properties的一個配置屬性:

//指定數據庫的方言
hibernate.dialect org.hibernate.dialect.MySQLDialect

上面的一行代碼是典型的Properties文件的的格式,前面的key爲hibernate.dialect , 後面的value是爲org.hibernate.dialect.MySQLDialect。

接下來咱們再來查看hibernate.cfg.xml文件中的相對應的配置代碼:

<property name = "dialect">org.hibernate.dialect.MySQLDialect</property>

一樣指定了Hibernate的Dialect 屬性是org.hibernate.dialect.MySQLDialect 。對比兩種格式的文件,能夠發現雖然格式不一樣但其實質徹底同樣。

相關文章
相關標籤/搜索