Hibernate性能優化策略(一)

在Hibernate系列文章的第一篇中就提到了使用Hibernate會有一個性能問題,但萬事不是絕對的,總會有辦法,下面的幾個方法雖不能徹底解決性能的問題,但基本上也能滿足大多數的需求。
抓取策略
單端代理
a) 保持默認,同fetch="select",如:<many-to-onename="classes" column="classesid"fetch="select"/>,fetch="select",另外發送一條select語句加載當前對象的關聯對象或集合。
b) 設置fetch="join",如:<many-to-onename="classes" column="classesid"fetch="join"/>,hibernate會通過一個select語句連接(內聯/外聯:取決於外鍵是否爲空)抓取其關聯對象或集合,lazy失效,fetch爲select或join不影響hql查詢,它影響的是load,get方法。
<many-to-one>可能會出現N+1問題,如:查詢100個學生顯示到列表中:首先會發出查詢學生的sql語句,然後會發出根據班級id查詢班級的sql語句,這樣就會導致N+1問題,也就是發出了N+1條語句,會嚴重影響性能,所以我們可以採用預先抓取的策略,如:selects from Student s join fetch s.classes。
集合代理
a) 保持默認,同fetch="select",如:<setname="students" order-by="id" inverse="true"cascade="all" fetch="select">,fetch="select",另外發送一條select語句加載當前對象的關聯對象或集合。
b) 設置fetch="join",如:<setname="students" order-by="id" inverse="true"cascade="all" fetch="join">,hibernate會通過一個select語句連接(內聯/外聯)抓取其關聯對象或集合,fetch="join",那麼lazy失效,fetch="join",隻影響get和load,對hql沒有影響。
c) 設置fetch="subselect",如:<setname="students" order-by="id" inverse="true"cascade="all" fetch="subselect">,另外發送一條select語句抓取在前面查詢到的所有實體的關聯集合,fetch="subselect",會影響hql查詢。
批量抓取
batch-size屬性,可以批量加載實體類,參見參見Classes.hbm.xml中的配置: <classname="com.bjpowernode.hibernate.Classes"table="t_classes" batch-size="10">,batch-size屬性就是爲了減少發出的sql語句量。
Lazy加載機制
Lazy是延遲加載,只有真正使用該對象時,纔會創建,對於Hibernate來說,只有真正使用時纔會發出sql,這樣可以提高一些性能。Hibernate的lazyloading採用了一個HibernateSession來管理session,他的邏輯是每進行一次數據庫操作,就開新的session,操作完成後立即關閉該session,這樣做的好處是可以嚴格關閉session,但不適合跨方法的事務。
Class標籤上的Lazy
< class>標籤上,可以取值:true/false,它隻影響普通屬性。查id不發sql,因爲傳的就是主鍵,查別的屬性會發sql,HibernateLazy有效期必須是session在open時纔可以,解決方式是使用openSessionInview(後面的Spring會有講解)。
集合標籤上的Lazy
< set>/<list>標籤上,可以取值:true/false/extra。<class>標籤上的lazy不會影響集合上的lazy特性,把class標籤上的lazy設置成false時,再load類時會把普通屬性都查出來,但是集合不查。
get集合時不會發sql,迭代會發sql,查個數的時候會把整個集合查出來,這樣對效率有影響,lazy在集合上用extra獲取size的時候會發出count語句,對效率有所提升。
單端關聯上的Lazy
< many-to-one>/<one-to-one>單端關聯標籤上,可以取值:false/proxy/noproxy。<class>標籤上的lazy不會影響單端關聯對象的lazy策略。單端關聯上的lazy和集合一樣,在get時返回代理不發查詢語句,使用時發出sql。在單端關聯上lazy=false,在訪問普通屬性時發出兩條sql,查詢屬性以及對應的關聯對象。
發佈了14 篇原創文章 · 獲贊 6 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章