Hibernate(開放原始碼的對象關係映射架構)

來源:互聯網
上載者:User

標籤:讀取   ons   集合   type   圖片   適配   解析   緩衝   read   

Hibernate是一個開放原始碼的對象關係映射架構,它對JDBC進行了非常輕量級的對象封裝,它講POJO與資料庫表建立映射關係,是一個全自動的orm架構,Hibernate可以自動產生SQL語句,自動執行,使Java程式員可以隨心所欲的使用對象編程思維來操作資料庫。Hibernate可以應用再任何使用JDBC的場合,既可以在Java的用戶端程式使用,也可以在Servlet/JSP的WEB應用中使用,最具有革命意義的是:Hibernate可以在應用EJB的J2EE架構中取代CMP。完成資料持久化的重任。

核心介面和類

Hibernate的核心類和介面一共有6個,分別是:Session、 SessionFactory、Transaction、Query、Criteria和Configuration。這6個核心類和介面在任何開發中都有用到,通過這些介面,不僅可以持久化對象進行存取,還能夠進行事務控制。

Session : 介面負責執行被持久化對象的CRUD操作(CRUD的任務是完成與資料庫的交流,包含了很多常見的SQL語句。)但需要注意的是Session對象是非安全執行緒的。同時,Hibernate的session不同於JSP應用中的HttpSession。這裡當使用session這個術語時,其實指的是Hibernate中的Session,而以後將HttpSession對象成為使用者Session。
SessionFactory: SessionFactory介面負責初始化Hibernate。它充當資料存放區源的代理,並負責建立Session對象。這裡用到了原廠模式。需要注意的是SessionFactory並不是輕量級的。因為一般情況下,一個項目只需要一個SessionFactory就夠了。當需要操作多個資料庫時,可以為每個資料庫指定一個SessionFactory。
Transaction: Transaction 介面是一個可選的API,可以選擇不使用這個介面,取而代之的是Hibernate的設計者自己寫的底層交易處理代碼。Transaction介面是對實際事務實現的一個抽象,這些實現包括JDBC的事務、JTA中的UserTransaction、甚至可以是CORBA事務。之所以這樣設計是能讓開發人員能夠使用一個統一事務的操作介面,使得自己的項目可以在不同的環境和容器之間方便移植。
Query: Query介面讓你方便地對資料庫持久對象進行查詢,它可以有兩種表達方式:HQL語言或本機資料庫的SQL語句。Query經常被用來綁定查詢參數。限制查詢記錄數量,並最終執行查詢操作

Criteria: Criteria介面與Query介面非常類似,允許建立並執行物件導向的標準化查詢。值得注意的是Criteria介面也是輕量級的,它不能在Session之外使用。
Configuration: Configuration類的作用是對Hibernate進行配置,以及對它進行啟動。在hibernate的啟動過程中,Configuration類的實力首先定位映射文檔的位置,讀取這些配置,然後建立一個SessionFactory對象。雖然Configuration類在整個Hibernate項目中只扮演著一個很小的角色,但它是啟動Hibernate時所遇到的第一個對象。

主鍵介紹
Assigned
Assigned方式由使用者產生主索引值,並且要在save()之前指定否則會拋出異常
特點:主鍵的產生值完全由使用者決定,與底層資料庫無關。使用者需要維護主索引值,在調用session.save()之前要指定主索引值。
Hilo
Hilo使用高低位演算法產生主鍵,高低位演算法使用一個高位值和一個低位值,然後把演算法得到的兩個值拼接起來作為資料庫中的唯一主鍵。Hilo方式需要額外的資料庫表和欄位提供高位值來源。預設情況下使用的表是
hibernate_unique_key,預設欄位叫作next_hi。next_hi必須有一條記錄否則會出現錯誤。
特點:需要額外的資料庫表的支援,能保證同一個資料庫中主鍵的唯一性,但不能保證多個資料庫之間主鍵的唯一性。Hilo主鍵產生方式由Hibernate 維護,所以Hilo方式與底層資料庫無關,但不應該手動修改hi/lo演算法使用的表的值,否則會引起主鍵重複的異常。

Increment
Increment方式對主索引值採取自動成長的方式產生新的主索引值,但要求底層資料庫的主鍵類型為long,int等數值型。主鍵按數值順序遞增,增量為1。
/特點:由Hibernate本身維護,適用於所有的資料庫,不適合多進程並發更新資料庫,適合單一進程訪問資料庫。不能用於群集環境。/

Identity
Identity方式根據底層資料庫,來支援自動成長,不同的資料庫用不同的主鍵增長方式。

特點:與底層資料庫有關,要求資料庫支援Identity,如MySQl中是auto_increment, SQL Server 中是Identity,支援的資料庫有MySql、SQL Server、DB2、Sybase和HypersonicSQL。 Identity無需Hibernate和使用者的幹涉,使用較為方便,但不便於在不同的資料庫之間移植程式。

Sequence
Sequence需要底層資料庫支援Sequence方式,例如Oracle資料庫等

特點:需要底層資料庫的支援序列,支援序列的資料庫有DB2、PostgreSql、Oracle、SAPDb等在不同資料庫之間移植程式,特別從支援序列的資料庫移植到不支援序列的資料庫需要修改設定檔。

Native
Native主鍵產生方式會根據不同的底層資料庫自動選擇Identity、Sequence、Hilo主鍵產生方式

特點:根據不同的底層資料庫採用不同的主鍵產生方式。由於Hibernate會根據底層資料庫採用不同的映射方式,因此便於程式移植,項目中如果用到多個資料庫時,可以使用這種方式。

UUID
UUID使用128位UUID演算法產生主鍵,能夠保證網路環境下的主鍵唯一性,也就能夠保證在不同資料庫及不同伺服器下主鍵的唯一性。

特點:能夠保證資料庫中的主鍵唯一性,產生的主鍵佔用比較多的存貯空間

Foreign GUID
Foreign用於一對一關聯性中。GUID主鍵產生方式使用了一種特殊演算法,保證產生主鍵的唯一性,支援SQL Server和MySQL

包的作用

net.sf.hibernate.*  [1]

該包的類基本上都是介面類和異常類

net.sf.hibernate.cache.*

JCS的實作類別

net.sf.hibernate.cfg.*

設定檔讀取類

net.sf.hibernate.collection.*

Hibernate集合介面實作類別,例如List,Set,Bag等等,Hibernate之所以要自行編寫集合介面實作類別是為了支援lazy loading

net.sf.hibernate.connection.*

幾個資料庫連接池的Provider

net.sf.hibernate.dialect.*

支援多種資料庫特性,每個Dialect實作類別代表一種資料庫,描述了該資料庫支援的資料類型和其它特點,例如是否有AutoIncrement,是否有Sequence,是否有分頁sql等等

net.sf.hibernate. eg.*

Hibernate文檔中用到的例子
net.sf.hibernate.engine.*
這個包的類作用比較散
net.sf.hibernate.expression.*

HQL支援的運算式

net.sf.hibernate.hq.*

HQL實現

net.sf.hibernate. id.*

ID產生器

net.sf.hibernate.impl.*

最核心的包,一些重要介面的實作類別,如Session,SessionFactory,Query等

net.sf.hibernate.jca.*

JCA支援,把Session封裝為支援JCA的介面實作類別

net.sf.hibernate.jmx.*

JMX是用來編寫App Server的管理程式的,大概是JMX部分介面的實現,使得App Server可以通過JMX介面管理Hibernate

net.sf.hibernate.loader.*

也是很核心的包,主要是產生sql語句的

net.sf.hibernate.lob.*

Blob和Clob支援

net.sf.hibernate.mapping.*

hbm檔案的屬性實現

net.sf.hibernate.metadata.*

PO的Meta實現

net.sf.hibernate.odmg.*

ODMG是一個ORM標準,這個包是ODMG標準的實作類別

net.sf.hibernate.persister.*

核心包,實現持久對象和表之間的映射

net.sf.hibernate.proxy.*

Proxy和Lazy Loading支援

net.sf.hibernate. ps.*

該包是PreparedStatment Cache

net.sf.hibernate.sql.*

產生JDBC sql語句的包

net.sf.hibernate.test.*

測試類別,你可以用junit來測試Hibernate

net.sf.hibernate.tool.hbm2ddl.*
用hbm設定檔產生DDL

net.sf.hibernate.transaction.*

Hibernate Transaction實作類別

net.sf.hibernate.type.*

Hibernate中定義的持久對象的屬性的資料類型

net.sf.hibernate.util.*

一些工具類,作用比較散

net.sf.hibernate.xml.*

XML資料繫結

緩衝管理

Hibernate 中提供了兩級Cache(高速緩衝儲存空間),第一層級的緩衝是Session層級的緩衝,它是屬於事務範圍的緩衝。這一層級的緩衝由hibernate管理的,一般情況下無需進行幹預;第二層級的緩衝是SessionFactory層級的緩衝,它是屬於進程範圍或群集範圍的緩衝。這一層級的緩衝可以進行配置和更改,並且可以動態載入和卸載。 Hibernate還為查詢結果提供了一個查詢快取,它依賴於第二級緩衝。  第一級緩衝 第二級緩衝 存放資料的形式 相互關聯的持久化對象的散裝資料 緩衝的範圍 事務範圍,每個事務都有單獨的第一級緩衝進程範圍或叢集範圍,緩衝被同一個進程或叢集範圍內的所有事務共用 並發存取原則由於每個事務都擁有單獨的第一級緩衝,不會出現並發問題,無需提供並發存取原則由於多個事務會同時訪問第二級緩衝中相同資料,因此必須提供適當的並發存取原則,來保證特定的交易隔離等級資料到期策略沒有提供資料到期策略。處於一級緩衝中的對象永遠不會到期,除非應用程式顯式清空緩衝或者清除特定的對象必須提供資料到期策略,如基於記憶體的緩衝中的對象的最大數目,允許對象處於緩衝中的最長時間,以及允許對象處於緩衝中的最長空閑時間。緩衝的軟體實現 在Hibernate的Session的實現中包含了緩衝的實現由第三方提供,Hibernate僅提供了緩衝適配器(CacheProvider)。用於把特定的快取區外掛程式整合到Hibernate中。啟用緩衝的方式只要應用程式通過Session介面來執行儲存、更新、刪除、載入和查詢資料庫資料的操作,Hibernate就會啟用第一級緩衝,把資料庫中的資料以對象的形式拷貝到緩衝中,對於批次更新和大量刪除操作,如果不希望啟用第一級緩衝,可以繞過Hibernate API,直接通過JDBC API來執行指操作。使用者可以在單個類或類的單個集合的粒度上配置第二級緩衝。如果類的執行個體被經常讀但很少被修改,就可以考慮使用第二級緩衝。只有為某個類或集合配置了第二級緩衝,Hibernate在運行時才會把它的執行個體加入到第二級緩衝中。 使用者管理緩衝的方式第一級緩衝的物理介質為記憶體,由於記憶體容量有限,必須通過恰當的檢索策略和檢索方式來限制載入對象的數目。Session的evit()方法可以顯式清空緩衝中特定對象,但這種方法不值得推薦。 第二級緩衝的物理介質可以是記憶體和硬碟,因此第二級緩衝可以存放大量的資料,資料到期策略的maxElementsInMemory屬性值可以控制記憶體中的對象數目。管理第二級緩衝主要包括兩個方面:選擇需要使用第二級緩衝的持久類,設定合適的並發存取原則:選擇緩衝適配器,設定合適的資料到期策略。

一級緩衝
當應用程式調用Session的save()、update()、saveOrUpdate()、get()或load(),以及調用查詢介面的 list()、iterate()或filter()方法時,如果在Session緩衝中還不存在相應的對象,Hibernate就會把該對象加入到第一級緩衝中。當清理緩衝時,Hibernate會根據緩衝中對象的狀態變化來同步更新資料庫。 Session為應用程式提供了兩個管理緩衝的方法: evict(Object obj):從緩衝中清除參數指定的持久化對象。 clear():清空緩衝中所有持久化對象。

二級緩衝

3.1. Hibernate的二級緩衝策略的一般過程如下:

1) 條件查詢的時候,總是發出一條select * from table_name where …. (選擇所有欄位)這樣的SQL語句查詢資料庫,一次獲得所有的資料對象。

2) 把獲得的所有資料對象根據ID放入到第二級緩衝中。

3) 當Hibernate根據ID訪問資料對象的時候,首先從Session一級緩衝中查;查不到,如果配置了二級緩衝,那麼從二級緩衝中查;查不到,再查詢資料庫,把結果按照ID放入到緩衝。

4) 刪除、更新、增加資料的時候,同時更新緩衝。

Hibernate的二級緩衝策略,是針對於ID查詢的緩衝策略,對於條件查詢則毫無作用。為此,Hibernate提供了針對條件查詢的Query Cache。

3.2. 什麼樣的資料適合存放到第二級緩衝中? 1 很少被修改的資料 2 不是很重要的資料,允許出現偶爾並發的資料 3 不會被並發訪問的資料 4 參考資料,指的是供應用參考的常量資料,它的執行個體數目有限,它的執行個體會被許多其他類的執行個體引用,執行個體極少或者從來不會被修改

3.3. 不適合存放到第二級緩衝的資料? 1 經常被修改的資料 2 財務資料,絕對不允許出現並發 3 與其他應用共用的資料。

3.4. 常用的快取區外掛程式 Hibernater 的二級緩衝是一個外掛程式,下面是幾種常用的快取區外掛程式:
l EhCache:可作為進程範圍的緩衝,存放資料的物理介質可以是記憶體或硬碟,對Hibernate的查詢快取提供了支援。

l OSCache:可作為進程範圍的緩衝,存放資料的物理介質可以是記憶體或硬碟,提供了豐富的快取資料到期策略,對Hibernate的查詢快取提供了支援。

l SwarmCache:可作為群集範圍內的緩衝,但不支援Hibernate的查詢快取。

l JBossCache:可作為群集範圍內的緩衝,支援事務型並發存取原則,對Hibernate的查詢快取提供了支援。

在預設情況下,Hibernate使用EhCache進行JVM層級的緩衝。使用者可以通過設定Hibernate設定檔中的hibernate.cache.provider_class的屬性,指定其他的緩衝策略,該緩衝策略必須實現org.hibernate.cache.CacheProvider介面。

3.5. 配置二級緩衝的主要步驟:

1) 選擇需要使用二級緩衝的持久化類,設定它的具名快取的並發存取原則。這是最值得認真考慮的步驟。

2) 選擇合適的快取區外掛程式,然後編輯該外掛程式的設定檔。

消極式載入
Hibernate對象關係映射提供延遲的與非延遲的對象初始化。非消極式載入在讀取一個對象的時候會將與這個對象所有相關的其他對象一起讀取出來。這有時會導致成百的(如果不是成千的話)select語句在讀取對象的時候執行。這個問題有時出現在使用雙向關係的時候,經常會導致整個資料庫都在初始化的階段被讀出來了。當然,你可以不厭其煩地檢查每一個對象與其他對象的關係,並把那些最昂貴的刪除,但是到最後,我們可能會因此失去了本想在ORM工具中獲得的便利。

一個明顯的解決方案是使用Hibernate提供的消極式載入機制。這種初始化策略只在一個對象調用它的一對多或多對多關係時才將關聯性物件讀取出來。這個過程對開發人員來說是透明的,而且只進行了很少的資料庫操作請求,因此會得到比較明顯的效能提升。這項技術的一個缺陷是消極式載入技術要求一個Hibernate會話要在對象使用的時候一直開著。這會成為通過使用DAO模式將持久層抽象出來時的一個主要問題。為了將持久化機制完全地抽象出來,所有的資料庫邏輯,包括開啟或關閉會話,都不能在應用程式層出現。最常見的是,一些實現了簡單介面的DAO實作類別將資料庫邏輯完全封裝起來了。一種快速但是笨拙的解決方案是放棄DAO模式,將資料庫連接邏輯加到應用程式層中來。這可能對一些小的應用程式有效,但是在大的系統中,這是一個嚴重的設計缺陷,妨礙了系統的可擴充性。

Web層消極式載入

幸運的是,Spring架構為Hibernate消極式載入與DAO模式的整合提供了一
種方便的解決方案。以一個Web應用為例,Spring提供了OpenSessionInViewFilterOpenSessionInViewInterceptor。我們可以隨意選擇一個類來實現相同的功能。兩種方法唯一的不同就在於interceptor在Spring容器中運行並被配置在web應用的上下文中,而Filter在Spring之前運行並被配置在web.xml中。不管用哪個,他們都在請求將當前會話與當前(資料庫)線程綁定時開啟Hibernate會話。一旦已綁定到線程,這個開啟了的Hibernate會話可以在DAO實作類別中透明地使用。這個會話會為消極式載入資料庫中值對象的視圖保持開啟狀態。一旦這個邏輯視圖完成了,Hibernate會話會在Filter的doFilter方法或者Interceptor的postHandle方法中被關閉。
實現方法在web.xml中加入

<filter><filter-name>hibernateFilter</filter-name><filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class></filter><filter-mapping><filter-name>hibernateFilter</filter-name><url-pattern>*.do</url-pattern></filter-mapping>

效能最佳化

初用HIBERNATE的人也許都遇到過效能問題,實現同一功能,用HIBERNATE與用JDBC效能相差十幾倍很正常,如果不及早調整,很可能影響整個項目的進度。 大體上,對於HIBERNATE效能調優的主要考慮點如下:

.資料庫設計調整

.HQL最佳化

.API的正確使用(如根據不同的業務類型選用不同的集合及查詢API)

.主配置參數(日誌,查詢快取,fetch_size, batch_size等)

.對應檔最佳化(ID建置原則,二級緩衝,消極式載入,關聯最佳化)

.一級緩衝的管理

.針對二級緩衝,還有許多特有的策略

.事務控制策略。

資料庫設計

a) 降低關聯的複雜性

b) 盡量不使用聯合主鍵

c) ID的產生機制,不同的資料庫所提供的機制並不完全一樣

d) 適當的冗餘資料,不過分追求高範式

HQL最佳化
HQL如果拋開它同HIBERNATE本身一些緩衝機制的關聯,HQL的最佳化技巧同普通的SQL最佳化技巧一樣,可以很容易在網上找到一些經驗之談

主配置
a) 查詢快取,同下面講的緩衝不太一樣,它是針對HQL語句的緩衝,即完全一樣的語句再次執行時可以利用快取資料。但是,查詢快取在一個交易系統(資料變更頻繁,查詢條件相同的機率並不大)中可能會起反作用:它會白白耗費大量的系統資源但卻難以派上用場。

b) fetch_size,同JDBC的相關參數作用類似,參數並不是越大越好,而應根據業務特徵去設定

c) batch_size同上。

d) 生產系統中,切記要關掉SQL語句列印。

緩衝
a) 資料庫級緩衝:這級緩衝是最高效和安全的,但不同的資料庫可管理的層次並不一樣,比如,在Oracle中,可以在建表時指定將整個表置於緩衝當中。

b) SESSION緩衝:在一個HibernateSESSION有效,這級緩衝的可幹預性不強,大多於HIBERNATE自動管理,但它提供清除緩衝的方法,這在大批量增加/更新操作是有效。比如,同時增加十萬條記錄,按常規方式進行,很可能會發現OutofMemeroy的異常,這時可能需要手動清除這一級緩衝:Session.evict以及 Session.clear

c) 應用緩衝:在一個SESSIONFACTORY中有效,因此也是最佳化的重中之重,因此,各類策略也考慮的較多,在將資料放入這一級緩衝之前,需要考慮一些前提條件:

i. 資料不會被第三方修改(比如,是否有另一個應用也在修改這些資料?)

ii. 資料不會太大

iii. 資料不會頻繁更新(否則使用CACHE可能適得其反)

iv. 資料會被頻繁查詢

v. 資料不是關鍵資料(如涉及錢,安全等方面的問題)。

緩衝有幾種形式,可以在對應檔中配置:read-only(唯讀,適用於很少變更的待用資料/曆史資料),nonstrict-read- write,read-write(比較普遍的形式,效率一般),transactional(JTA中,且支援的緩衝產品較少)

d) 分布式緩衝:同c)的配置一樣,只是緩衝產品的選用不同,oscache, jboss cache,的大多數項目,對它們的用於叢集的使用(特別是關鍵交易系統)都持保守態度。在叢集環境中,只利用資料庫級的緩衝是最安全的。

hibernate工作原理:
1、通過Configuration().configure();讀取並解析hibernate.cfg.xml設定檔。
2、由hibernate.cfg.xml中的

Hibernate(開放原始碼的對象關係映射架構)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.