国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Hibernate的檢索策略

2019-11-14 23:54:53
字體:
來源:轉載
供稿:網友
Hibernate的檢索策略

hibernate 的中的session依照load()和get()按照參數的制定OID(ObjctID)去加載一個持久化對象。另外Query.list()方法則按照HQL語句去加載持久化的對象。

以上的幾個方式都可以實現hibernate的持久化對象的加載。如果有不懂hibernate對象的"臨時狀態"、"游離態"、"持久態"、"刪除狀態"的小伙伴,自己先去了解下。

對于hibernate的以上的幾種檢索策略,我們先來了解下他們幾種的工作細節。

首先是session的load()方法,我們以Customer和Orders的例子來簡單說明下。Customers與Orders的關系是一對多的關系。我們這邊假定已經配置了這兩個對象hbm.xml的一對多單向關聯關系。

一、session的load(Customers.class,new Long(1))的方式返回的是一個Customer持久化對象的引用。這時候Customer還沒有初始化。因此時不會出現sql查詢語句的執行。要等到真正使用到Customer的時候才會進行初始化。也就是執行查詢語句。這時候如果在Custmoers 中配置了

1<set2name="orders"3insever="ture"4lazy="true"

5 fetch= "select"

6 <one-to-manyclass=....>7 >

lazyd的默認屬性是true,也就是說采用懶加載。

1、如果lazy設置為false的話,則會在初始化Customers對象的時候就會去將Customers所有Orders對象進行查詢,這也叫立即檢索。這里有個地方得值得注意的是,如果上面的set標簽中配置了fecth屬性為join,這時候load在真正執行查詢的時候,關聯對象的時候使用的的是迫切左外連接查詢,這樣的話,就算是顯式的設置lazy的屬性,也無意義。至于為什么,我想熟悉sql查詢的都知道原因了。當然fecth屬性還有其他的一些選項例如select,subselect,fetch默認為select。

2、如果采用懶加載,也就是lazy設置為true的話,則在初始化Customers只會對customers對象進行查詢操作。而在真正使用Orders屬性時才對Customers關聯的Orders對象進行查詢操作。這里得說明下:例如 在對Order order = customer.iterator().next()迭代的時返回是Orders的代理實例。這時的Order還沒有進行實例化,所以沒有進行sql查詢。只有在對其屬性或方法調用的時候,例如獲取訂單號:Order.getOrderNo()的時候才對其進行實例化。

lazy還有其他選項 extra增強 ,例如獲取一個訂單集合的size/contains等方法時,這時不會去初始化該orders,而是會向數據庫發送一條sql去查詢獲取值,只有真正要用到集合元素值時才去實例化查詢數據庫。這種比較聰明的方式與lazy設置為true的區別就是在選擇懶加載的時機上extra更加“懶惰”,更加延遲。

二、session.get(Customers.class,new Long(1))。get采用的是立即檢索的策略,這里Customers一定會立馬初始化。

1、如果在對Orders的配置中,set中設置了lazy為true的話,則與load類似。等到真正使用Orders的屬性的時候才會去做sql關聯查詢。

2、 如果 lazy設置為false,則在get()方法執行的時候也會立馬初始化Orders的所有關聯對象。這種方式與上面load的第一種方式唯一的區別在與,load初始化比get的初始化Customers的時機更晚,更延遲。

這里注意的是,如果如果上面的set標簽中配置了fecth屬性為join,關聯對象的時候使用的的是迫切左外連接查詢。不管lazy是否設置為true,采用的也是立即加載。

三、query接口中的list()方法。 seesion.createQuery(sql).list(),執行該方法后,程序會里面向數據庫發送sql去執行查詢操作。

1、如果在對Orders的配置中,set中設置了lazy為true的話,等到真正使用Orders的屬性的時候才會去做sql關聯查詢。

2、如果 lazy設置為false的話,則會立馬初始化Orders的所有關聯對象。這個類似于get()方式。

這里有個地方需要注意下,在query.list()的時候,它會fetch的join策略的,所以就算是顯式的設置了fetch為join,也不會采用迫切左外聯接查詢。

總結下load,get,query.list三種方式的區別:

1.load在對類級別的對象加載是有“延遲”作用的,而get和query.list采用的是立即檢索的策略。

2.在關聯一對多關聯關系的加載時,load與get和query.list 采用的都是同樣的策略,前提是在many一方的懶加載方式也是一致。

3.在get和load方式加載時,對fetch的策略是一致的。 而query.list是對fetch的join的策略是忽略的。

對于一對多的單向關聯關系的懶加載策略做了大致的分析。其實雙向也很好理解。

假設在Orders.hbm.xml文件中的<many-to-one> 中配置了以下配置:

1<many-to-one

2insever="true"3lazy="6/>

這里前提是在Customers.hbm.xml文件中的set的inserver設置為false或者不顯式設置。默認為false。

1、這時在對orders對象進行加載的時候,如果customer采用的lazy是proxy方式,則采用代理懶加載方式。也就說,只有當orders獲取它的custormer屬性的時候,才去加載與之關聯的customer對象。如果order的lazy采用的也是懶加載方式的話,則在獲取customer時不會獲取orders對象。

舉個例子:在get(orders.class,new Long(1))的方法獲取Orders的時候,會立馬加載Orders對象,當獲取Orders.getCustomer().getName()的時候,才會去加載Customer對象,而如果再去獲取該Customer對象下的Orders的時候,才去加載Orders。也就是說會去執行3次的sql,而每次執行一條sql語句。

而如果Orders采用lazy為false的話,則與上面不用。則會在立馬加載Orders,而后會在加載Customers的同時一起加載Orders對象。也就說這里也會執行3條sql,但是分為2次執行,第一次一條查詢orders,第二次兩條,執行查詢Customer和Orders的查詢。

2、如果customer采用的lazy是no-proxy方式,則證明采用非代理懶加載,這個與上面的區別在于這種方式是,在對Orders加載完后,只有一旦獲取customer屬性時返回的就是Customers的實例,而不是代理實例。這樣就會立馬對Customers進行實例化。其他的與proxy的一致。也就是說區別在于對Customers對象的延遲加載時機的策略不同。

3、lazy的選項還可以是false,也就說。在對Orders進行加載的時候,會立馬對Customers進行立刻檢索。也就說會里面發出3條sql語句。2次查詢order,一次查詢customer。

關于hibernate的懶加載,這里講的只涉及到了一對多的關聯關系代碼不多,但懂的人應該可以理解。還有一對多,一對一,多對多。。hibernate都有自己的策略,而且都很靈活。后續會給大家補上。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 甘孜县| 肥西县| 永泰县| 进贤县| 桦川县| 长岛县| 肇庆市| 蒲城县| 鸡西市| 江华| 台安县| 华蓥市| 察雅县| 夏邑县| 双城市| 波密县| 泗阳县| 马关县| 曲周县| 桐梓县| 蓬莱市| 屏边| 承德市| 沧源| 微博| 莫力| 静宁县| 清镇市| 电白县| 革吉县| 双流县| 沂南县| 偏关县| 保德县| 古蔺县| 前郭尔| 兴隆县| 乐昌市| 上林县| 美姑县| 上林县|