2007-02-05 23:10:55
屬性
1  unsaved-value:對級聯(lián)對象進(jìn)行數(shù)據(jù)保存時,Hibernate將根據(jù)這個值來判斷對象是否需要保存;先從級聯(lián)對象中取出id,如果id和 unsave-value值相等,則認(rèn)為對象尚未保存,否則認(rèn)為對象已經(jīng)保存(這里的保存指的是insert,而不是update)
;在隱式保存的情況下,Hibernate用目標(biāo)對象的id值和此值比較,如果相等則insert,否則不insert
2  hbm.xml文件的class標(biāo)簽中有一個polymorphism="explicit"屬性,它的作用是:聲明一個顯式多態(tài)關(guān)系,聲明為顯式多態(tài)的類只有在代碼中(如:list object=createQuery("from TuserProfile").list();這里顯式指明了TuserProfile類)明確指定類名的時候才會返回此類實例;
  如果要返回對應(yīng)整個數(shù)據(jù)庫中所有庫表記錄的數(shù)據(jù)對象,可用: List obj=createQuery("from object").list();但不會返回在映射文件中具有polymorphism="explicit"定義的類的實例
3 inverse:用于在設(shè)置雙向一對多關(guān)系時設(shè)置維護(hù)兩個實體關(guān)系的一方,inverse=false的一方負(fù)責(zé)維護(hù)雙方關(guān)系;在one-to-many關(guān)系中,常將many一方設(shè)為false方
4 cascade:指的是當(dāng)主控方執(zhí)行操作時,關(guān)聯(lián)對象(被動方)是否同步執(zhí)行同一操作。例如對主控對象調(diào)用save-update或delete方法時, 是否同時對關(guān)聯(lián)對象(被動方)進(jìn)行sava-update或delete;設(shè)定為all則代表無論主控方執(zhí)行任何操作 (Insert/update/delete...)都對其關(guān)聯(lián)類時行同樣的操作
           ;根據(jù)此屬性的設(shè)置對相關(guān)聯(lián)的對象采取相應(yīng)的操作
   cascade="all-delete-orphan"處理方式:
   當(dāng)保存當(dāng)前對象時保存相關(guān)聯(lián)的對象,相當(dāng)于cascade="save-update"
   當(dāng)刪除當(dāng)前對象時刪除相關(guān)聯(lián)的對象,相當(dāng)于cascade="delete"
   當(dāng)雙方存在父子關(guān)系時,如果解除了子與父的關(guān)系則刪除和父方解除關(guān)系的子方記錄
 (當(dāng)關(guān)聯(lián)雙方存在父子關(guān)系時,就可以把父方的cascade設(shè)為all-delete-orphan)
 5 在<property>標(biāo)簽中的access屬性說明:
   形式<property name="name" column="name" access="field/property"/>
  access默認(rèn)為property,意思是:Hibernate不是直接訪問持久化類中的name屬性,而是訪問setName()和getName()方法;
  access="field",意思是:Hibernate不訪問setName()和getName()方法,而是直接訪問持久化類中的name屬性
6 hbm.xml文件的class標(biāo)簽中有一個polymorphism="explicit"屬性,它的作用是:聲明一個顯式多態(tài)關(guān)系,聲明為顯式多態(tài)的類只有在代碼中(如:list object=createQuery("from TuserProfile").list();這里顯式指明了TuserProfile類)明確指定類名的時候才會返回此類實例;
  如果要返回對應(yīng)整個數(shù)據(jù)庫中所有庫表記錄的數(shù)據(jù)對象,可用: List obj=createQuery("from object").list();但不會返回在映射文件中具有polymorphism="explicit"定義的類的實例
  方法
1  加載數(shù)據(jù)的get和load方法區(qū)別:
   a 如果未能發(fā)現(xiàn)符合條件的記錄,get方法返回null,load方法拋出一個ObjectNotFoundException異常
   b load可以返回實體的代理類實例,get永遠(yuǎn)直接返回實體類
    代理類實例:
    實體類:
   c load要在內(nèi)部緩存和二級緩存中搜索現(xiàn)有數(shù)據(jù),get則僅在內(nèi)部緩存中進(jìn)行數(shù)據(jù)查找(根據(jù)id查找),如果在內(nèi)部緩存中沒有找到數(shù)據(jù)則直接從數(shù)據(jù)庫中讀取
 
    內(nèi)部緩存(一級緩存):其中保持了session當(dāng)前所有關(guān)聯(lián)實體的數(shù)據(jù)
    二級緩存:存在于SessionFactory層次,由當(dāng)前所有本SessionFactory構(gòu)造的session實例共享
2 session.find(hql,parameterValue,Hibernate Type of parametervlaue)和session.iterator(hql,parameterValue,Hibernate type of parameterValue) 方法的區(qū)別:
 session.find()返回的是List集合;session.find() 執(zhí)行相應(yīng)SQL后返回記錄并構(gòu)造相應(yīng)的實體對象,再將其納入緩存.find()不會對緩存進(jìn)行數(shù)據(jù)查詢,而是直接從數(shù)據(jù)庫取記錄,對于緩存只寫不讀
 session.iterator()返回的是Iterator集合;執(zhí)行N+1次查詢出所有符合條件的記錄,首先查詢滿足條件的記錄id,再根據(jù)id 查詢所有記錄;iterator首先在本地緩存中根據(jù)id查找對應(yīng)的實體對象是否存在(類似session.load()),若存在則以此數(shù)據(jù)對象作為結(jié) 果返回;若未找到,則執(zhí)行相應(yīng)SQL語句從數(shù)據(jù)庫獲得對應(yīng)的記錄,并構(gòu)建完整數(shù)據(jù)對象,再將其納入緩存
3 緩存對象的移除
  session.evict(user)----從一級緩存中移除對象
  sessionFactory.evict(Tuser.class,user.getId())-------從二級緩存中移除對象;二級緩存可以設(shè)定最大數(shù)據(jù)緩存量,達(dá)到峰值時自動對緩存中的較老數(shù)據(jù)進(jìn)行移除;也可以手工移除(如前)
4 session.save()先在一級緩存中查詢要保存的對象,若找到則認(rèn)為對象處于持久狀態(tài);不會把對象放在二級緩存,而是放在一級緩存
  session.update()先在一級緩存中查詢要保存的對象,若找到則認(rèn)為對象處于持久狀態(tài);將在session.flush()時執(zhí)行update的SQL語句(transaction.commit在真正提交數(shù)據(jù)庫事務(wù)前會調(diào)用session.flush)
  saveorupdate()無需用戶判斷對象的狀態(tài),其自動判斷再執(zhí)行save或者update
5 saveorupdate()方法說明:該方法包含了save()與update()方法的功能,如果傳入的參數(shù)是臨時對象,就調(diào)用save()方法,如 果傳入的參數(shù)是游離對象,就調(diào)用update()方法,如果傳入的是持久化對象,那就直接返回.saveorupdate()方法如何判斷一個對象是處于 臨時狀態(tài)還是游離對象根據(jù)的是以下條件,滿足其一即可:
 1.java對象的ID取值為null
 2.java對象具有version屬性并且取值為null
 3.在映射文件中為<id>元素設(shè)置了undaved-value屬性,并且ID取值與undaved-value屬性值匹配。
 4.在映射文件中為version屬性設(shè)置了unsaved-value屬性,并且version屬性取值與unsaved-value屬性值匹配.
 5.自定義了Hibernate的Interceptor實現(xiàn)類,并且Interceptor的isUnsaved()方法返回true.
實體對象的三種狀態(tài)
java中,對象不引用任何對象且不被任何對象引用時,就會被JVM回收,此時該對象才結(jié)束生命周期.
session緩存:session緩存其實就是session的實現(xiàn)類sessionImp中定義的Map集合,以對象ID為鍵,以對象為值的形式保存.
1 Transient(自由狀態(tài)):剛剛用new語句創(chuàng)建,還沒有被持久化,不處于session的緩存中。即實體對象在內(nèi)存中是自由存在的,它與數(shù)據(jù)庫中的記錄無關(guān);處于臨時狀態(tài)的java對象被稱為臨時對象.
    特征:1.不處在session的緩存中,也可以說,不被任何一個session實例關(guān)聯(lián).
  2.在數(shù)據(jù)庫中沒有對應(yīng)的記錄.
 在以下情況下,java對象進(jìn)入臨時狀態(tài):
  1.當(dāng)通過new語句剛創(chuàng)建了一個java對象,它處于臨時狀態(tài),此時不和數(shù)據(jù)庫中的任何記錄對應(yīng).
  2.session的delete()方法能使一個持久化對象或游離對象轉(zhuǎn)變?yōu)榕R時對象。對于游離對象,delete()方法從數(shù)據(jù)庫中刪除與它對應(yīng)的記錄;對于持久化對象,delete()方法從數(shù)據(jù)庫中刪除與它對應(yīng)的記錄,并且把它從session緩存中刪除.
 
2 Persistent(持久狀態(tài)):已經(jīng)被持久化,加入到了session緩存中。實體對象處于由Hibernate框架所管理的狀態(tài),這種狀態(tài)下,實體 對象的引用被納入Hibernate實體容器中加以管理;處于Persistent狀態(tài)的對象,其變更將由Hibernate固化到數(shù)據(jù)庫中
何時變?yōu)槌志脿顟B(tài):當(dāng)實體對象處于自由狀態(tài)時,通過Session.save方法可將其轉(zhuǎn)換為Persistent狀態(tài),如果一個實體對象是由 Hibernate加載(如通過Session.load方法獲得),那它也處于Persistent狀態(tài);處于持久化狀態(tài)的實體即使沒有調(diào)用 session.save()方法進(jìn)行數(shù)據(jù)持久化,而只用了tx.commit()也會被保存到數(shù)據(jù)庫
持久化對象的特征:
 1.位于一個session實例的緩存中,也可以說,持久化對象總是被一個session實例關(guān)聯(lián).
 2.持久化對象和數(shù)據(jù)庫中的相關(guān)記錄對應(yīng)
 3.session在清理緩存時,會根據(jù)持久化對象的屬性變化,來同步更新數(shù)據(jù)庫
 3 Detached(游離狀態(tài)):已經(jīng)被持久化,但不處于session緩存當(dāng)中.對應(yīng)的Session實例關(guān)閉之后,此對象就處于游離狀態(tài)
 例:
 Tuser user=new Tuser();
 user.setName("Emma");//此時實體對象user處于游離狀態(tài)
 Tansaction tx=session.beginTransaction();
 session.save(user);//此時實體對象user已經(jīng)由Hibernate納入管理容器,處于Persistent狀態(tài)
 tx.commit();
 session.close();//(Tag)     實體對象user此時狀態(tài)為Detached,因為與其關(guān)聯(lián)的session已經(jīng)關(guān)閉   
3 游離對象的特征:
 1.不再位于session緩存中,也可以說,游離對象不實被session關(guān)聯(lián).
 2.游離對象是由持久化對象轉(zhuǎn)變來的,因此在數(shù)據(jù)庫中可能還存在與它對應(yīng)的記錄(只要沒刪除該記錄)
4 Transient狀態(tài)和Detached狀態(tài)的相同之處:兩者都不被session關(guān)聯(lián).兩者的區(qū)別:游離對象是由持久對象轉(zhuǎn)變過來的,因此可能在數(shù)據(jù) 庫中還存對應(yīng)的記錄,而臨時對象在數(shù)據(jù)庫中沒有對應(yīng)的記錄.Detached對象可以再次與某個Session實例相關(guān)聯(lián)而成為Persistent對 象;如下所示
接Tag處:
Transaction tx2=session2.beginTransaction();
session2.update(user);//此時處于Detached狀態(tài)的user對象再次借助session2由Hibernate納入管理容器,恢復(fù)Persistent狀態(tài)
user.setName("Eric");
tx2.commit();//由于user對象再次處于Persistent狀態(tài),因此其屬性變更將自動由Hibernate固化到數(shù)據(jù)庫
5 Transient狀態(tài)的對象與數(shù)據(jù)庫中記錄并不存在對應(yīng)關(guān)系,它所包含的數(shù)據(jù)信息僅是上面的user.setName("Emma")這點而已; Session.save()執(zhí)行后,Hibernate對user對象進(jìn)行了持久化,并為其賦予了主鍵值,這時user對象就與庫表中具備相同id值的 記錄相關(guān)聯(lián);所以,Transient狀態(tài)的user對象與庫表中的數(shù)據(jù)缺乏對應(yīng)關(guān)系,而Detached狀態(tài)的user對象,卻在庫表中存在相對應(yīng)的記 錄(由主鍵惟一確定),簡而言之,Transient狀態(tài)中的實體對象,無主鍵信息,而Deatched狀態(tài)的實體對象包含了其對應(yīng)數(shù)據(jù)庫記錄的主鍵值;
實體對象從Persistent狀態(tài)轉(zhuǎn)變?yōu)門ransient狀態(tài)一般由session.delete方法完成
6 Collection在判斷兩個對象是否相等的時候,會首先調(diào)用對象的hashCode方法,如果hashCode相同的話, 再調(diào)用equals方法,如果兩次判斷均為真,則認(rèn)為對比的兩個對象相等

關(guān)聯(lián)關(guān)系
*********************一對多關(guān)系中,一方<set>的說明*********************************************
1 當(dāng)<set>中同時設(shè)置lazy和outer-join屬性時,如果兩者都為false則采用立即檢索(因為outer-join="false"則不采用迫切左外連接,但lazy="false"則是指采用立即檢索策略);
如果lazy和outer-join其中一個為false另一個為true(不管誰是false誰是true),則以設(shè)置為true的那一個為準(zhǔn)(即 lazy=true,outer-join=false則是采用延遲檢索;相反采用迫切左外連接);如果兩者均為true則同lazy=false, outer-join=true(即采用迫切左外連接,outer-join優(yōu)先級比lazy高);find()方法會忽略outer-join屬性,即 outer-join對find方法無效;
如果<set>中設(shè)有l(wèi)azy且<class>中也設(shè)有l(wèi)azy屬性,則是以<class>中的為準(zhǔn);
    對于get和find方法均是采用立即檢索,與lazy的設(shè)置無關(guān)
2 <set>中的batch-size屬性可以理解為:在加載<set>中的<one-to-many>中的class類對象時,要初始化的對象數(shù)目,以便在后面再次需要初始化時不需要再訪問數(shù)據(jù)庫,從而提高數(shù)據(jù)訪問速度
3 <set>中一般要設(shè)置:lazy=true,outer-join="true",batch-size設(shè)為要在子方初始化的對象個數(shù)(一般為:3-10)
************************多對一關(guān)系中,多方的說明******************************888
1(設(shè)一方[customer.hbm.xml]的class中的lazy為A;多方[order.hbm.xml]的<many-to-one>中的outer-join為B)
 A=true,B=auto,則對于order.hbm.xml的<many-to-one>中的class指向的對象[customer]采用延遲檢索,否則用迫切左外連接檢索
 A=false,B=true,對于order關(guān)聯(lián)的customer采用迫切左外連接檢索
 A=true,B=false 對于order關(guān)聯(lián)的customer對象采用延遲檢索,否則采用立即檢索
  結(jié)論:當(dāng)A=true時,則B無論設(shè)為什么均按照A的設(shè)置進(jìn)行檢索,只有當(dāng)A=false時,才按B的設(shè)置進(jìn)行檢索(A的優(yōu)先級大于B)
2.hibernate.max_fetch_deepth:在迫切左外連接的多層數(shù)據(jù)表的檢索中設(shè)置從第一層檢索表開始的檢索深度(即從第一層檢索表開始要檢索幾層從第一層開始的檢索表)
Java集合
1.Set 集合中的對象不按特定方式排序,且沒有重復(fù)對象;
 該接口主要有兩個實現(xiàn)類HashSet和TreeSet。
 HashSet類按照哈希算法來存取集合中的對象,存取速度比較快。HashSet類還有一個子類LinkedHashSet類,它不僅實現(xiàn)了哈希算法,且實現(xiàn)了鏈表數(shù)據(jù)結(jié)構(gòu)。TreeSet類實現(xiàn)了SortedSet接口  ,具有排序功能.
 為了保證HashSet能正常工作,要求當(dāng)兩個對象用equals()方法比較的結(jié)果為相等時,其哈希碼也相等;即如果覆蓋了equals()方法,也應(yīng)該覆蓋hashCode()方法
Set set = new HashSet();
  String s1 = new String("hello");
  String s2 = s1;
  String s3 = new String("world");
  set.add(s1);
  set.add(s2);
  set.add(s3);
  System.out.println("set的元素個數(shù):" + set.size());//==2
2 List List的主要特征是其對象以線性方式存儲,集合中允許存放重復(fù)對象。List接口主要的實現(xiàn)類有:LinkedList,ArrayList。 LinkedList采用鏈表數(shù)據(jù)結(jié)構(gòu),而ArrayList代表大小可變的數(shù)組.List接口還有一個實現(xiàn)類Vector,其功能和ArrayList 相似,兩者的區(qū)別在于:Vector類的實現(xiàn)了同步機(jī)制,而ArrayList沒有使用同步機(jī)制.
 List對集合中的對象按索引位置排序,允許按照對象在集合中的索引位置檢索對象
 List的iterator()方法和Set的iterator()方法均返回Iterator對象,通過Iterator對象,可以遍歷集合中的所有對象
3 Map:Map(映射)是一種把鍵對象和值對象進(jìn)行映射的集合,其每一個元素都包含了一對鍵對象和值對象,而值對象仍可以是Map類型;向Map集合中加入元素時,必須提供一對鍵對象和值對象,從Map集合中檢索元素時,只要給出鍵對象,就會返回對應(yīng)的值對象。
Map map=new HashMap();
map.put("1","Monday");
map.put("2","Tuesday"); 
map.put("3","Wendsday");
map.put("4","Thursday");
System.out.println("Map測試==="+map.get("2"));//=Tuesday
Map集合中的鍵對象不允許重復(fù),即任意兩個鍵對象通過equals()方法比較的結(jié)果都是false,對于值對象則沒有惟一性的要求,可以將任意多個鍵對象映射到同一個值對象上,但是后加入的值將會覆蓋先加入的值.
Map有兩種比較常用的實現(xiàn):HashMap和TreeMap。HashMap按照哈希算法來存取鍵對象有很好的存取性能
多對一關(guān)系中多方的配置
<many-to-one  name="customer"  column="customer_id" class="pkg.customer"/>
<set
    name="order"
    cascade="sava-update"
   inverse="true">
<key column="customer_id"/>
<one-to-many class="pkg.order"/>
</set>