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

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