2007-02-05 23:10:55
屬性
1
unsaved-value:對級聯對象進行數據保存時,Hibernate將根據這個值來判斷對象是否需要保存;先從級聯對象中取出id,如果id和
unsave-value值相等,則認為對象尚未保存,否則認為對象已經保存(這里的保存指的是insert,而不是update)
;在隱式保存的情況下,Hibernate用目標對象的id值和此值比較,如果相等則insert,否則不insert
2
hbm.xml文件的class標簽中有一個polymorphism="explicit"屬性,它的作用是:聲明一個顯式多態關系,聲明為顯式多態的類只有在代碼中(如:list
object=createQuery("from
TuserProfile").list();這里顯式指明了TuserProfile類)明確指定類名的時候才會返回此類實例;
如果要返回對應整個數據庫中所有庫表記錄的數據對象,可用: List
obj=createQuery("from
object").list();但不會返回在映射文件中具有polymorphism="explicit"定義的類的實例
3
inverse:用于在設置雙向一對多關系時設置維護兩個實體關系的一方,inverse=false的一方負責維護雙方關系;在one-to-many關系中,常將many一方設為false方
4
cascade:指的是當主控方執行操作時,關聯對象(被動方)是否同步執行同一操作。例如對主控對象調用save-update或delete方法時,
是否同時對關聯對象(被動方)進行sava-update或delete;設定為all則代表無論主控方執行任何操作
(Insert/update/delete...)都對其關聯類時行同樣的操作
;根據此屬性的設置對相關聯的對象采取相應的操作
cascade="all-delete-orphan"處理方式:
當保存當前對象時保存相關聯的對象,相當于cascade="save-update"
當刪除當前對象時刪除相關聯的對象,相當于cascade="delete"
當雙方存在父子關系時,如果解除了子與父的關系則刪除和父方解除關系的子方記錄
(當關聯雙方存在父子關系時,就可以把父方的cascade設為all-delete-orphan)
5
在<property>標簽中的access屬性說明:
形式<property name="name"
column="name" access="field/property"/>
access默認為property,意思是:Hibernate不是直接訪問持久化類中的name屬性,而是訪問setName()和getName()方法;
access="field",意思是:Hibernate不訪問setName()和getName()方法,而是直接訪問持久化類中的name屬性
6
hbm.xml文件的class標簽中有一個polymorphism="explicit"屬性,它的作用是:聲明一個顯式多態關系,聲明為顯式多態的類只有在代碼中(如:list
object=createQuery("from
TuserProfile").list();這里顯式指明了TuserProfile類)明確指定類名的時候才會返回此類實例;
如果要返回對應整個數據庫中所有庫表記錄的數據對象,可用: List
obj=createQuery("from
object").list();但不會返回在映射文件中具有polymorphism="explicit"定義的類的實例
方法
1 加載數據的get和load方法區別:
a
如果未能發現符合條件的記錄,get方法返回null,load方法拋出一個ObjectNotFoundException異常
b
load可以返回實體的代理類實例,get永遠直接返回實體類
代理類實例:
實體類:
c
load要在內部緩存和二級緩存中搜索現有數據,get則僅在內部緩存中進行數據查找(根據id查找),如果在內部緩存中沒有找到數據則直接從數據庫中讀取
內部緩存(一級緩存):其中保持了session當前所有關聯實體的數據
二級緩存:存在于SessionFactory層次,由當前所有本SessionFactory構造的session實例共享
2 session.find(hql,parameterValue,Hibernate Type of
parametervlaue)和session.iterator(hql,parameterValue,Hibernate type
of parameterValue) 方法的區別:
session.find()返回的是List集合;session.find()
執行相應SQL后返回記錄并構造相應的實體對象,再將其納入緩存.find()不會對緩存進行數據查詢,而是直接從數據庫取記錄,對于緩存只寫不讀
session.iterator()返回的是Iterator集合;執行N+1次查詢出所有符合條件的記錄,首先查詢滿足條件的記錄id,再根據id
查詢所有記錄;iterator首先在本地緩存中根據id查找對應的實體對象是否存在(類似session.load()),若存在則以此數據對象作為結
果返回;若未找到,則執行相應SQL語句從數據庫獲得對應的記錄,并構建完整數據對象,再將其納入緩存
3 緩存對象的移除
session.evict(user)----從一級緩存中移除對象
sessionFactory.evict(Tuser.class,user.getId())-------從二級緩存中移除對象;二級緩存可以設定最大數據緩存量,達到峰值時自動對緩存中的較老數據進行移除;也可以手工移除(如前)
4
session.save()先在一級緩存中查詢要保存的對象,若找到則認為對象處于持久狀態;不會把對象放在二級緩存,而是放在一級緩存
session.update()先在一級緩存中查詢要保存的對象,若找到則認為對象處于持久狀態;將在session.flush()時執行update的SQL語句(transaction.commit在真正提交數據庫事務前會調用session.flush)
saveorupdate()無需用戶判斷對象的狀態,其自動判斷再執行save或者update
5
saveorupdate()方法說明:該方法包含了save()與update()方法的功能,如果傳入的參數是臨時對象,就調用save()方法,如
果傳入的參數是游離對象,就調用update()方法,如果傳入的是持久化對象,那就直接返回.saveorupdate()方法如何判斷一個對象是處于
臨時狀態還是游離對象根據的是以下條件,滿足其一即可:
1.java對象的ID取值為null
2.java對象具有version屬性并且取值為null
3.在映射文件中為<id>元素設置了undaved-value屬性,并且ID取值與undaved-value屬性值匹配。
4.在映射文件中為version屬性設置了unsaved-value屬性,并且version屬性取值與unsaved-value屬性值匹配.
5.自定義了Hibernate的Interceptor實現類,并且Interceptor的isUnsaved()方法返回true.
實體對象的三種狀態
java中,對象不引用任何對象且不被任何對象引用時,就會被JVM回收,此時該對象才結束生命周期.
session緩存:session緩存其實就是session的實現類sessionImp中定義的Map集合,以對象ID為鍵,以對象為值的形式保存.
1
Transient(自由狀態):剛剛用new語句創建,還沒有被持久化,不處于session的緩存中。即實體對象在內存中是自由存在的,它與數據庫中的記錄無關;處于臨時狀態的java對象被稱為臨時對象.
特征:1.不處在session的緩存中,也可以說,不被任何一個session實例關聯.
2.在數據庫中沒有對應的記錄.
在以下情況下,java對象進入臨時狀態:
1.當通過new語句剛創建了一個java對象,它處于臨時狀態,此時不和數據庫中的任何記錄對應.
2.session的delete()方法能使一個持久化對象或游離對象轉變為臨時對象。對于游離對象,delete()方法從數據庫中刪除與它對應的記錄;對于持久化對象,delete()方法從數據庫中刪除與它對應的記錄,并且把它從session緩存中刪除.
2
Persistent(持久狀態):已經被持久化,加入到了session緩存中。實體對象處于由Hibernate框架所管理的狀態,這種狀態下,實體
對象的引用被納入Hibernate實體容器中加以管理;處于Persistent狀態的對象,其變更將由Hibernate固化到數據庫中
何時變為持久狀態:當實體對象處于自由狀態時,通過Session.save方法可將其轉換為Persistent狀態,如果一個實體對象是由
Hibernate加載(如通過Session.load方法獲得),那它也處于Persistent狀態;處于持久化狀態的實體即使沒有調用
session.save()方法進行數據持久化,而只用了tx.commit()也會被保存到數據庫
持久化對象的特征:
1.位于一個session實例的緩存中,也可以說,持久化對象總是被一個session實例關聯.
2.持久化對象和數據庫中的相關記錄對應
3.session在清理緩存時,會根據持久化對象的屬性變化,來同步更新數據庫
3
Detached(游離狀態):已經被持久化,但不處于session緩存當中.對應的Session實例關閉之后,此對象就處于游離狀態
例:
Tuser user=new Tuser();
user.setName("Emma");//此時實體對象user處于游離狀態
Tansaction tx=session.beginTransaction();
session.save(user);//此時實體對象user已經由Hibernate納入管理容器,處于Persistent狀態
tx.commit();
session.close();//(Tag)
實體對象user此時狀態為Detached,因為與其關聯的session已經關閉
3 游離對象的特征:
1.不再位于session緩存中,也可以說,游離對象不實被session關聯.
2.游離對象是由持久化對象轉變來的,因此在數據庫中可能還存在與它對應的記錄(只要沒刪除該記錄)
4
Transient狀態和Detached狀態的相同之處:兩者都不被session關聯.兩者的區別:游離對象是由持久對象轉變過來的,因此可能在數據
庫中還存對應的記錄,而臨時對象在數據庫中沒有對應的記錄.Detached對象可以再次與某個Session實例相關聯而成為Persistent對
象;如下所示
接Tag處:
Transaction tx2=session2.beginTransaction();
session2.update(user);//此時處于Detached狀態的user對象再次借助session2由Hibernate納入管理容器,恢復Persistent狀態
user.setName("Eric");
tx2.commit();//由于user對象再次處于Persistent狀態,因此其屬性變更將自動由Hibernate固化到數據庫
5
Transient狀態的對象與數據庫中記錄并不存在對應關系,它所包含的數據信息僅是上面的user.setName("Emma")這點而已;
Session.save()執行后,Hibernate對user對象進行了持久化,并為其賦予了主鍵值,這時user對象就與庫表中具備相同id值的
記錄相關聯;所以,Transient狀態的user對象與庫表中的數據缺乏對應關系,而Detached狀態的user對象,卻在庫表中存在相對應的記
錄(由主鍵惟一確定),簡而言之,Transient狀態中的實體對象,無主鍵信息,而Deatched狀態的實體對象包含了其對應數據庫記錄的主鍵值;
實體對象從Persistent狀態轉變為Transient狀態一般由session.delete方法完成
6
Collection在判斷兩個對象是否相等的時候,會首先調用對象的hashCode方法,如果hashCode相同的話, 再調用equals方法,如果兩次判斷均為真,則認為對比的兩個對象相等
關聯關系
*********************一對多關系中,一方<set>的說明*********************************************
1
當<set>中同時設置lazy和outer-join屬性時,如果兩者都為false則采用立即檢索(因為outer-join="false"則不采用迫切左外連接,但lazy="false"則是指采用立即檢索策略);
如果lazy和outer-join其中一個為false另一個為true(不管誰是false誰是true),則以設置為true的那一個為準(即
lazy=true,outer-join=false則是采用延遲檢索;相反采用迫切左外連接);如果兩者均為true則同lazy=false,
outer-join=true(即采用迫切左外連接,outer-join優先級比lazy高);find()方法會忽略outer-join屬性,即
outer-join對find方法無效;
如果<set>中設有lazy且<class>中也設有lazy屬性,則是以<class>中的為準;
對于get和find方法均是采用立即檢索,與lazy的設置無關
2
<set>中的batch-size屬性可以理解為:在加載<set>中的<one-to-many>中的class類對象時,要初始化的對象數目,以便在后面再次需要初始化時不需要再訪問數據庫,從而提高數據訪問速度
3
<set>中一般要設置:lazy=true,outer-join="true",batch-size設為要在子方初始化的對象個數(一般為:3-10)
************************多對一關系中,多方的說明******************************888
1(設一方[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關聯的customer采用迫切左外連接檢索
A=true,B=false
對于order關聯的customer對象采用延遲檢索,否則采用立即檢索
結論:當A=true時,則B無論設為什么均按照A的設置進行檢索,只有當A=false時,才按B的設置進行檢索(A的優先級大于B)
2.hibernate.max_fetch_deepth:在迫切左外連接的多層數據表的檢索中設置從第一層檢索表開始的檢索深度(即從第一層檢索表開始要檢索幾層從第一層開始的檢索表)
Java集合
1.Set 集合中的對象不按特定方式排序,且沒有重復對象;
該接口主要有兩個實現類HashSet和TreeSet。
HashSet類按照哈希算法來存取集合中的對象,存取速度比較快。HashSet類還有一個子類LinkedHashSet類,它不僅實現了哈希算法,且實現了鏈表數據結構。TreeSet類實現了SortedSet接口 ,具有排序功能.
為了保證HashSet能正常工作,要求當兩個對象用equals()方法比較的結果為相等時,其哈希碼也相等;即如果覆蓋了equals()方法,也應該覆蓋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的元素個數:"
+ set.size());//==2
2 List
List的主要特征是其對象以線性方式存儲,集合中允許存放重復對象。List接口主要的實現類有:LinkedList,ArrayList。
LinkedList采用鏈表數據結構,而ArrayList代表大小可變的數組.List接口還有一個實現類Vector,其功能和ArrayList
相似,兩者的區別在于:Vector類的實現了同步機制,而ArrayList沒有使用同步機制.
List對集合中的對象按索引位置排序,允許按照對象在集合中的索引位置檢索對象
List的iterator()方法和Set的iterator()方法均返回Iterator對象,通過Iterator對象,可以遍歷集合中的所有對象
3
Map:Map(映射)是一種把鍵對象和值對象進行映射的集合,其每一個元素都包含了一對鍵對象和值對象,而值對象仍可以是Map類型;向Map集合中加入元素時,必須提供一對鍵對象和值對象,從Map集合中檢索元素時,只要給出鍵對象,就會返回對應的值對象。
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集合中的鍵對象不允許重復,即任意兩個鍵對象通過equals()方法比較的結果都是false,對于值對象則沒有惟一性的要求,可以將任意多個鍵對象映射到同一個值對象上,但是后加入的值將會覆蓋先加入的值.
Map有兩種比較常用的實現:HashMap和TreeMap。HashMap按照哈希算法來存取鍵對象有很好的存取性能
多對一關系中多方的配置
<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>