天天看點

Hibernate初解

文章轉自:http://www.lijinsm.cn

JAVA Hibernate工作原理及為什麼要用

hibernate 簡介:

hibernate是一個開放源代碼的持久層架構,它是對象關聯關系映射的架構,對JDBC做了輕量級的封裝,使我們java程式員可以使用面向對象的思想來操縱關系型的資料庫。

hibernate核心接口:

session:負責被持久化對象CRUD操作

sessionFactory:負責初始化hibernate,建立session對象

configuration:負責配置并啟動hibernate,建立SessionFactory

Transaction:負責事物相關的操作

Query和Criteria接口:負責執行各種資料庫查詢

hibernate工作原理:

1.通過Configuration config = new Configuration().configure();//讀取并解析hibernate.cfg.xml配置檔案

2.由hibernate.cfg.xml中的<mapping resource="com/User.hbm.xml"/>讀取并解析映射資訊

3.通過SessionFactory sf = config.buildSessionFactory();//建立SessionFactory

4.Session session = sf.openSession();//打開Sesssion

5.Transaction tx = session.beginTransaction();//建立并啟動事務Transation

6.persistent operate操作資料,持久化操作

7.tx.commit();//送出事務

8.關閉Session

9.關閉SesstionFactory

為什麼要用hibernate:

1. 對JDBC通路資料庫的代碼做了封裝,大大簡化了資料通路層繁瑣的重複性代碼。

2. Hibernate是一個基于JDBC的主流持久化架構,是一個優秀的ORM實作。他很大程度的簡化DAO層的編碼工作

3. hibernate使用Java反射機制,而不是位元組碼增強程式來實作透明性。

4. hibernate的性能非常好,因為它是個輕量級架構。映射的靈活性很出色。它支援各種關系資料庫,從一對一到多對多的各種複雜關系。

Hibernate是如何延遲加載?get與load的差別

1. 對于Hibernate get方法,Hibernate會确認一下該id對應的資料是否存在,首先在session緩存中查找,然後在二級緩存中查找,還沒有就查詢資料庫,資料 庫中沒有就傳回null。這個相對比較簡單,也沒有太大的争議。主要要說明的一點就是在這個版本(bibernate3.2以上)中get方法也會查找二級緩存!

2. Hibernate load方法加載實體對象的時候,根據映射檔案上類級别的lazy屬性的配置(預設為true),分情況讨論:

(1)若為true,則首先在Session緩存中查找,看看該id對應的對象是否存在,不存在則使用延遲加載,傳回實體的代理類對象(該代理類為實體類的子類,由CGLIB動态生成)。等到具體使用該對象(除擷取OID以外)的時候,再查詢二級緩存和資料庫,若仍沒發現符合條件的記錄,則會抛出一個ObjectNotFoundException。

(2)若為false,就跟Hibernateget方法查找順序一樣,隻是最終若沒發現符合條件的記錄,則會抛出一個ObjectNotFoundException。

這裡get和load有兩個重要差別:

如果未能發現符合條件的記錄,Hibernate get方法傳回null,而load方法會抛出一個ObjectNotFoundException。

load方法可傳回沒有加載實體資料的代 理類執行個體,而get方法永遠傳回有實體資料的對象。(對于load和get方法傳回類型:好多書中都說:“get方法永遠隻傳回實體類”,實際上并不正 确,get方法如果在session緩存中找到了該id對應的對象,如果剛好該對象前面是被代理過的,如被load方法使用過,或者被其他關聯對象延遲加 載過,那麼傳回的還是原先的代理對象,而不是實體類對象,如果該代理對象還沒有加載實體資料(就是id以外的其他屬性資料),那麼它會查詢二級緩存或者數 據庫來加載資料,但是傳回的還是代理對象,隻不過已經加載了實體資料。)

總之對于get和load的根本差別,一句話,hibernate對于 load方法認為該資料在資料庫中一定存在,可以放心的使用代理來延遲加載,如果在使用過程中發現了問題,隻能抛異常;而對于get方 法,hibernate一定要擷取到真實的資料,否則傳回null。

Hibernate中怎樣實作類之間的關系?(如:一對多、多對多的關系)

類與類之間的關系主要展現在表與表之間的關系進行操作,它們都市對對象進行操作,我們程式中把所有的表與類都映射在一起,它們通過配置檔案中的many-to-one、one-to-many、many-to-many、

說下Hibernate的緩存機制:

Hibernate緩存的作用:

    Hibernate是一個持久層架構,經常通路實體資料庫,為了降低應用程式對實體資料源通路的頻次,進而提高應用程式的運作性能。緩存内的資料是對實體資料源中的資料的複制,應用程式在運作時從緩存讀寫資料,在特定的時刻或事件會同步緩存和實體資料源的資料

Hibernate緩存分類:

Hibernate緩存包括兩大類:Hibernate一級緩存和Hibernate二級緩存

Hibernate一級緩存又稱為“Session的緩存”,它是内置的,意思就是說,隻要你使用hibernate就必須使用session緩存。由于Session對象的生命周期通常對應一個資料庫事務或者一個應用事務,是以它的緩存是事務範圍的緩存。在第一級緩存中,持久化類的每個執行個體都具有唯一的OID。

Hibernate二級緩存又稱為“SessionFactory的緩存”,由于SessionFactory對象的生命周期和應用程式的整個過程對應,是以Hibernate二級緩存是程序範圍或者叢集範圍的緩存,有可能出現并發問題,是以需要采用适當的并 發通路政策,該政策為被緩存的資料提供了事務隔離級别。第二級緩存是可選的,是一個可配置的插件,預設情況下工廠SessionFactory不會啟用這個插件。

什麼樣的資料适合存放到第二級緩存中?   

1 很少被修改的資料   

2 不是很重要的資料,允許出現偶爾并發的資料   

3 不會被并發通路的資料   

4 常量資料   

不适合存放到第二級緩存的資料?   

1經常被修改的資料   

2 .絕對不允許出現并發通路的資料,如财務資料,絕對不允許出現并發   

3 與其他應用共享的資料。

Hibernate查找對象如何應用緩存?

當Hibernate根據ID通路資料對象的時候,首先從Session一級緩存中查;查不到,如果配置了二級緩存,那麼從二級緩存中查;如果都查不到,再查詢資料庫,把結果按照ID放入到緩存删除、更新、增加資料的時候,同時更新緩存

Hibernate管理緩存執行個體

無論何時,我們在管理Hibernate緩存(Managing the caches)時,當你給save()、update()或saveOrUpdate()方法傳遞一個對象時,或使用load()、 get()、list()、iterate() 或scroll()方法獲得一個對象時, 該對象都将被加入到Session的内部緩存中。 當随後flush()方法被調用時,對象的狀态會和資料庫取得同步。 如果你不希望此同步操作發生,或者你正處理大量對象、需要對有效管理記憶體時,你可以調用evict() 方法,從一級緩存中去掉這些對象及其集合。

 Hibernate的查詢方式

Sql、Criteria,object comptosition

Hql:

1、 屬性查詢

2、 參數查詢、命名參數查詢

3、 關聯查詢

4、 分頁查詢

5、 統計函數

 如何優化Hibernate?

1.使用雙向一對多關聯,不使用單向一對多

2.靈活使用單向一對多關聯

3.不用一對一,用多對一取代

4.配置對象緩存,不使用集合緩存

5.一對多集合使用Bag,多對多集合使用Set

6. 繼承類使用顯式多态

7. 表字段要少,表關聯不要怕多,有二級緩存撐腰

hibernate的開發步驟:

開發步驟

    1)搭建好環境

        引入hibernate最小的jar包

        準備Hibernate.cfg.xml啟動配置檔案

    2)寫實體類(pojo)

    3)為實體類寫映射檔案"User.hbm.xml"

        在hibernate.cfg.xml添加映射的實體

    4)建立庫表

    5)寫測試類

        獲得Configuration

        建立SessionFactory

        打開Session

        開啟事務

        使用session操作資料

        送出事務

        關閉資源