hibernate 工作原理及作用

轉載自 http://www.cnblogs.com/dashi/p/3597969.html#commentform

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/xx/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操作數據
        提交事務
        關閉資源

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章