hibernate持久化數(shù)據(jù)庫第二天.ppt_第1頁
hibernate持久化數(shù)據(jù)庫第二天.ppt_第2頁
hibernate持久化數(shù)據(jù)庫第二天.ppt_第3頁
hibernate持久化數(shù)據(jù)庫第二天.ppt_第4頁
hibernate持久化數(shù)據(jù)庫第二天.ppt_第5頁
已閱讀5頁,還剩130頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

1、hibernate持久化數(shù)據(jù)庫,第二天,概要,知識點一:java對象持久化(復習) 知識點二:Hibernate關聯(lián)映射(熟練掌握如下實體對象關聯(lián)) 1、單向的ont-to-many 2、單向的many-to-one 3、雙向的one-to-many 4、many-to-many 熟練掌握如下屬性 1、cascade 級聯(lián)操作 2、inverse 反轉(zhuǎn) 3、lazy 延遲加載、懶加載,知識點一:Java對象持久化概述,Java對象持久化概述,Hibernate是什么 面向java環(huán)境的對象/關系數(shù)據(jù)庫映射工具。 1.開源的持久層框架. 2.ORM(Object/Relational Mappi

2、ng)映射工具,建立面向?qū)ο蟮挠蚰P秃完P系數(shù)據(jù)模型之間的映射. 3.連接java應用和數(shù)據(jù)庫的中間件. 4.對JDBC進行封裝,負責java對象的持久化. 5.在分層結(jié)構(gòu)中處于持久化層,封裝對數(shù)據(jù)庫的訪問細節(jié), 使業(yè)務邏輯層更專注于實現(xiàn)業(yè)務邏輯,Java對象持久化概述,為什么要用Hibernate 1、Hibernate對JDBC訪問數(shù)據(jù)庫的代碼做了封裝,大大簡化 了數(shù)據(jù)訪問層繁瑣的重復性代碼。 2、Hibernate是一個基于jdbc的主流持久化框架,是一個優(yōu)秀 的orm實現(xiàn),它很大程度的簡化了dao層編碼工作。 3、Hibernate使用java的反射機制,而不是字節(jié)碼增強程序類實現(xiàn) 透明

3、性 4、Hibernate的性能非常好,因為它是一個輕量級框架。映射的靈 活性很出色。它支持很多關系型數(shù)據(jù)庫,從一對一到多對多的各 種復雜關系。,Java對象持久化概述,Java 應用的持久化分層 為了把數(shù)據(jù)訪問細節(jié)和業(yè)務邏輯分開, 可以把數(shù)據(jù)訪問作為單獨的持久化層,表述層,業(yè)務邏輯層,數(shù)據(jù)庫層,表述層,業(yè)務邏輯層,持久化層,數(shù)據(jù)庫層,Java對象持久化概述,Hibernate中間件:Hibernate不和特定的業(yè)務領域相關,能夠把任意一個Java應用與數(shù)據(jù)庫系統(tǒng)連接,可以理解為是一種中間件。,應用1,業(yè)務邏輯層,應用2,業(yè)務邏輯層,應用3,業(yè)務邏輯層,持久化層 (hibernate),數(shù)據(jù)庫

4、1,數(shù)據(jù)庫2,數(shù)據(jù)庫3,持久化層封裝了數(shù)據(jù)訪問的細節(jié),為業(yè)務邏輯層提供了面向?qū)ο蟮腁PI。完善的持久化層應該 達到的目標: 1.代碼重用性高,可完成所有的數(shù)據(jù)訪問操作。 2.如果需要的話,能夠支持多種數(shù)據(jù)庫平臺。 3.具有相對獨立性,當持久化層變化時,不會影響上層實現(xiàn)。,Java對象持久化概述,軟件模型 概念模型:模擬問題域中的真實實體。描述每個實體的概念和屬性及實體間關系。不描述實體行為。實體間的關系有一對一、一對多和多對多。,客戶 Name age,訂單 orderNumber price,1,*,Java對象持久化概述,軟件模型 關系數(shù)據(jù)模型:在概念模型的基礎上建立起來的,用于描述這些關

5、系數(shù)據(jù)的靜態(tài)結(jié)構(gòu)。有以下內(nèi)容組成: 1.若干表 2.表的所有索引 3.視圖 4.觸發(fā)器 5.表與表之間的參照完整性,Customers表 ID NAME AGE,ORDERS表 ID CustomerID Order_number price,Java對象持久化概述,軟件模型 域模型:在軟件的分析階段創(chuàng)建概念模型,在軟件設計階段創(chuàng)建域模型。 組成部分: 1.具有狀態(tài)和行為的域?qū)ο蟆?2.域?qū)ο笾g的關聯(lián)。,Java對象持久化概述,軟件模型 域?qū)ο?domain object):構(gòu)成域模型的基本元素就是域?qū)ο?。對真實世界的實體的軟件抽象,也叫做業(yè)務對象(Business Object(BO).域

6、對象可代表業(yè)務領域中的人、地點、事物或概念。 域?qū)ο蠓譃橐韵聨追N: 實體域?qū)ο螅和ǔJ侵笜I(yè)務領域中的名詞。(pojo) (plain old java object)。-映射數(shù)據(jù)庫中的表 過程域?qū)ο螅簯弥械臉I(yè)務邏輯或流程。依賴 于實體域?qū)ο?,業(yè)務領域中的動詞。如 發(fā)出訂單、登陸等。(對pojo操作的方法) 事件域?qū)ο螅簯弥械囊恍┦录ň?、異常)?面試題:,根據(jù)類之間的關系,分離下面語句中的對象,并說明對象之間的關系: 我早上出門先到公交車站乘坐公交車到地鐵站,然后乘坐地鐵到公司上班 有一間屋子,屋子有門,窗戶,屋子中有一張床,一張椅子,椅子有四條腿,Java對象持久化概述,軟件模型 域

7、對象間的關系 1.關聯(lián):類間的引用關系。以屬性定義的方式表現(xiàn)。,關聯(lián)可分為一對一、一對多和多對多。還可分為單向關聯(lián)和雙向關聯(lián)。,Order,Customer,Java對象持久化概述,軟件模型 域?qū)ο箝g的關系 依賴:類之間訪問關系。無需定義成屬性。在A中訪問B中的 方法或?qū)傩?,或者A負責實例化B。,BusinessService,Customer,Java對象持久化概述,軟件模型 域?qū)ο箝g的關系 3.聚集(Aggregation):整體與部分的關系。例人與手的關系。部分類的對象不能單獨存在,他的生命周期依賴于整體類的對象的生命周期,整體消失時,部分也隨之消失。,Person hand:set,H

8、and ,Java對象持久化概述,軟件模型 域?qū)ο箝g的關系 4.一般化(Generalization):類之間繼承關系。,Employee name,HourEmployee rate,SalaryEmployee salary,Java對象持久化概述,內(nèi)存,Customer對象,order對象,數(shù)據(jù)庫,持久化,重新加載到內(nèi)存,軟件模型 域?qū)ο蟮某志没拍?實體域?qū)ο笤趦?nèi)存中創(chuàng)建后,不能永久存在。將實體域?qū)ο笥谰帽4嫫饋?,就是持久化的過程。通常只有實體域?qū)ο笮枰志没?,過程域?qū)ο蠛褪录驅(qū)ο笠话悴恍枰志没?。廣義持久化指增、刪、改、查。,Java對象持久化概述,ORM:(Object/Rela

9、tion Mapping): 對象/關系映射 主要解決對象-關系的映射 ORM的實現(xiàn)思想:將關系數(shù)據(jù)庫中表中的記錄映射成為對象,以對象的形式展現(xiàn),程序員可以把對數(shù)據(jù)庫的操作轉(zhuǎn)化為對對象的操作。因此ORM的目的是為了方便開發(fā)人員以面向?qū)ο蟮乃枷雭韺崿F(xiàn)對數(shù)據(jù)庫的操作。 ORM 采用元數(shù)據(jù)來描述對象-關系映射細節(jié), 元數(shù)據(jù)通常采用 XML 格式, 并且存放在專門的對象-關系映射文件中,customers,Java對象持久化概述,ORM:(Object/Relation Mapping): 對象/關系映射,域模型 (對象、屬性、關聯(lián)、繼承和多態(tài)),ORM API ORM 實現(xiàn),關系數(shù)據(jù)模型 (表、字段

10、、索引、主鍵和外鍵),業(yè)務邏輯層,對象-關系映射文件 (xml),持久化層,數(shù)據(jù)庫層,參照,ORM 充當業(yè)務邏輯層和數(shù)據(jù)庫層之間的橋梁,Java對象持久化概述,ORM:(Object/Relation Mapping): 對象/關系映射 ORM中間件的使用方法 采用元數(shù)據(jù)來描述對象-關系映射細節(jié),元數(shù)據(jù)通常采用xml格式,并存放在專門的對象-關系映射文件中。只要配置了持久化類與表的映射關系,orm中間件在運行時就能夠參照映射文件的信息,把域?qū)ο蟪志没綌?shù)據(jù)庫中。,public vid deleteCustomer(Customer c) Session session = getSession

11、(); session.save(c); 執(zhí)行步驟如下: 1.運用反射機制,獲得Customer對象的Customer.class類。 2.參照映射文件得到Customer類對應的表的信息,以及和Customer類關聯(lián)的類以及 相應的表信息。 3.根據(jù)以上信息生成SQL語句。 4.調(diào)用hibernate API,執(zhí)行該語句。,持久化類的屬性及訪問方法,知識點1:Hibernate中持久化類的訪問者有兩個(從保存和查詢兩條路線看),Java應用程序不能訪問持久化類的private方法,而hibernate沒有這 個限制,它可以訪問各種級別的方法。,持久化類的屬性及訪問方法,知識點2:基本數(shù)據(jù)類型

12、和包裝類型區(qū)別: 基本數(shù)據(jù)類型和包裝類型對應的hibernate映射類型相同。,基本類型可直接運算、無法表達null、數(shù)字類型的默認值為0。 包裝類默認值是null。當對于默認值有業(yè)務意義的時候需要使用包裝類。,例如:User類有一個int類型的scope屬性,表示用戶的考試分數(shù).int類型的scope屬性無法表達這樣的業(yè)務需求: * 如果scope的屬性為null,表示該用戶的成績是未知的,有可能得了100分,也有可能得了0分,只是暫時還不知道成績 * 如果scope屬性為0,表示用戶考試成績?yōu)?分. * 在上面的情況中必須使用包裝類型,持久化類的屬性及訪問方法,知識點3:Hibernate

13、訪問持久化類屬性的策略 1.propertye 默認值:表明hibernate通過getXXX和 setXXX來訪問類屬性。推薦使用。提高域模型透明性。 2.field:hibernate通過java反射機制直接訪問類屬性。對于沒有 javabean方法的屬性可設置該訪問策略。 3 noop:它映射Java持久化類中不存在的屬性,即主要用于HQL(用query接口測試,使用hql語句)中,當數(shù)據(jù)庫中有某列,而實體中不存在的情況。, ,持久化類的屬性及訪問方法,知識點4:在持久化類的方法中加入程序邏輯 在Customer.hbm.xml文件中無需映射firstname和lastname屬 性,而

14、是映射name屬性。,盡管類中并沒有name屬性,由于hibernate不是直接訪問Name屬性,而是調(diào)用 get、set方法,因此建立了Firstname、Lastname和表之間的聯(lián)系。,持久化類的屬性及訪問方法,知識點4:在持久化類的方法中加入程序邏輯 不管在類中是否存在name屬性,只要在Customer.hbm.xml文件中映射了name屬性,在hql語句中就能訪問他。,如果改成: 后過如何? 運行出錯 field name not found on com.demo.pojo.Customer,持久化類的屬性及訪問方法,知識點5:設置派生屬性 利用元素的formula屬性,用來設置

15、一個sql表達式,hibernate將根據(jù)它來計算出派生屬性的值。 在customer類中增加兩個屬性 * private Double price; * private Double totalprice;/在數(shù)據(jù)庫中沒有對應的列 在Customer.hbm.xml文件中增加如下配置 注意:在sql語句中使用別名,派生屬性中使用的是sql語句,持久化類的屬性及訪問方法,知識點6:控制insert、update語句,處理sql引用標示符,在SQL語法中,標示符是指用于為數(shù)據(jù)庫表、視圖、字段或索引等名字的字符串,常規(guī)標示符不包括空格,也不包含特殊字符,因此無需使用引用符號。如果數(shù)據(jù)庫表名或列名包

16、含特殊字符,可以使用引用標示符(鍵盤下面的字符)。 注意:請在“英文輸入法”狀態(tài)下使用該符號,類中增加 private String des; 映射文件增加 ,知識點7:處理sql引用標示符,對象-關系映射基礎,如果在一個映射文件中包含多個類,并且這些類位于同一個包中,可以設置元素的package屬性,避免為每個類提供完整的類名。,知識點8:設置類的包名,知識點二:映射文件中的標識符,映射文件中的標識符,* Java按地址區(qū)分同一個類的不同對象. * 關系數(shù)據(jù)庫用主鍵區(qū)分同一條記錄. * Hibernate使用ID來建立內(nèi)存中的對象和數(shù)據(jù)庫中記錄的對應關系。對象的ID和數(shù)據(jù)庫的表的主鍵對應關系

17、。為保證ID的唯一性,應該讓Hibernate來為ID付值。(hibernate的主鍵策略),知識點1:唯一性的標示,映射文件中的標識符,知識點2:區(qū)分自然主鍵和代理主鍵,映射文件中的標識符,關系型數(shù)據(jù)庫按主鍵區(qū)分不同記錄 把主鍵定義為自動增長類型 在MySQL中,把字段設為auto_increment類型,數(shù)據(jù)庫會自動為主鍵賦值。 在SQLServer中,把字段設為identity類型,數(shù)據(jù)庫會自動為主鍵賦值。 oracle從序列(sequence)中獲取自動增長的描述符 create sequence seq_customer increment by 1 start with 1 ins

18、ert into customers values(seq_customer.nextval,.),知識點3:數(shù)據(jù)庫中的代理主鍵介紹,映射文件中的標識符,Java語言按內(nèi)存地址區(qū)分不同的對象 -equals()和=方法決定引用值是否指向同一對象 equals()在類中被覆蓋,為的是當兩個分離的對象的內(nèi)容和類型相配的話,返回真值。 Java.lang 包中的Object 類有public boolean equals (Object obj)方法。它比較兩個對象是否相等。僅當被比較的兩個引用指向同一對象時,對象的equals()方法返回true。 =運算符也進行等值比較。也就是說,對于任何引用值

19、X 和Y,當且僅當X 和Y 指向同一對象時, X=Y返回真。 當兩個分離的對象的內(nèi)容和類型相配的話,String,Date,F(xiàn)ile 類和所有其它override equals()的包裝類(Integer,Double,等等)將返回真。,知識點4:回顧java語言如何區(qū)分對象,映射文件中的標識符,ID是關系數(shù)據(jù)庫中的主鍵在java對象模型中的等價物。在運行時,hibernate根據(jù)ID來維持java對象和數(shù)據(jù)庫記錄的對應關系。(session的一級緩存),Customer c1 = (Customer)session.load(Customer.class,1); Customer c2 =

20、(Customer)session.load(Customer.class,1); Customer c3 = (Customer)session.load(Customer.class,3); c1 = c2 true c1 = c3 false 標簽用來設定標示符生成器。Hibernate提供了標識符生成器接 口:org.hibernate.id.IdentifierGenerator并提供了多種內(nèi)置的實現(xiàn)。,知識點5: Hibernate中用對象標示符(ID)來區(qū)分對象,ID和 generator屬性說明,id:設定持久化類的 id 和表的主鍵的映射 name: 標識持久化類 id 的屬

21、性名 column: 設置標識屬性所映射的數(shù)據(jù)列的列名(主鍵字段的名字). unsaved-value:若設定了該屬性, Hibernate 會通過比較持久化類的 id 值和該屬性值來區(qū)分當前持久化類的對象是否為臨時對象,在Hibernate3中幾乎不再需要. type:指定 Hibernate 映射類型. Hibernate 映射類型是 Java 類型與 SQL 類型的橋梁. 如果沒有為某個屬性顯式設定映射類型, Hibernate 會運用反射機制先識別出持久化類的特定屬性的 Java 類型, 然后自動使用與之對應的默認的 Hibernate 映射類型 Java 的基本數(shù)據(jù)類型和包裝類型對應

22、相同的 Hibernate 映射類型. 基本數(shù)據(jù)類型無法表達 null, 所以對于持久化類的 id 推薦使用包裝類型,generator:設定持久化類的標識符生成器 class: 指定使用的標識符生成器全限定類名或其縮寫名,映射文件中的標識符-主鍵生成策略,映射文件中的標識符,increment 標識符生成器由 Hibernate 以遞增的方式為代理主鍵賦值 Hibernate 會先讀取 NEWS 表中的主鍵的最大值, 而接下來向 NEWS 表中插入記錄時, 就在 max(id) 的基礎上遞增, 增量為 1.(帶走+1) 適用范圍: 由于 increment 生存標識符機制不依賴于底層數(shù)據(jù)庫系

23、統(tǒng), 因此它適合所有的數(shù)據(jù)庫系統(tǒng) 適用于只有單個 Hibernate 應用進程訪問同一個數(shù)據(jù)庫的場合 id 必須為 long, int 或 short 類型, 如果把 id 定義為 byte 類型, 在運行時會拋出異常,知識點6: increment 標識符生成器,映射文件中的標識符,知識點7: identity 標識符生成器,identity 標識符生成器由底層數(shù)據(jù)庫來負責生成標識符, 它要求底層數(shù)據(jù)庫把主鍵定義為自動增長字段類型(加1帶走) 適用范圍: 由于 identity 生成標識符的機制依賴于底層數(shù)據(jù)庫系統(tǒng), 因此, 要求底層數(shù)據(jù)庫系統(tǒng)必須支持自動增長字段類型. 支持自動增長字段類型

24、的數(shù)據(jù)庫包括: DB2, MySQL, MSSQLServer, Sybase 等 id 必須為 long, int 或 short 類型, 如果把 id 定義為 byte 類型, 在運行時會拋出異常,映射文件中的標識符,知識點8:sequence 標識符生成器,sequence 標識符生成器利用底層數(shù)據(jù)庫提供的序列來生成標識符. Hibernate 在持久化一個 News 對象時, 先從底層數(shù)據(jù)庫的 news_seq 序列中獲得一個唯一的標識號, 再把它作為主鍵值 適用范圍: 由于 sequence 生成標識符的機制依賴于底層數(shù)據(jù)庫系統(tǒng)的序列, 因此, 要求底層數(shù)據(jù)庫系統(tǒng)必須支持序列. 支持

25、序列的數(shù)據(jù)庫包括: DB2 Oracle id 必須為 long, int 或 short 類型, 如果把 id 定義為 byte 類型, 在運行時會拋出異常,Oralce數(shù)據(jù)庫中序列的名稱,映射文件中的標識符,知識點9:hilo 標識符生成器,hilo 標識符生成器由 Hibernate 按照一種 high/low 算法*生成標識符, 它從數(shù)據(jù)庫的特定表的字段中獲取 high 值. Hibernate 在持久化一個 News 對象時, 由 Hibernate 負責生成主鍵值. hilo 標識符生成器在生成標識符時, 需要讀取并修改 HI_TABLE 表中的 NEXT_VALUE 值. 適用范

26、圍: 由于 hilo 生存標識符機制不依賴于底層數(shù)據(jù)庫系統(tǒng), 因此它適合所有的數(shù)據(jù)庫系統(tǒng) id 必須為 long, int 或 short 類型, 如果把 id 定義為 byte 類型, 在運行時會拋出異常,存放使用次數(shù)的表名,hi_table表的列,存放使用次數(shù),步長,映射文件中的標識符,知識點10:native 標識符生成器,native 標識符生成器依據(jù)底層數(shù)據(jù)庫對自動生成標識符的支持能力, 來選擇使用 identity, sequence 或 hilo 標識符生成器. 適用范圍: 由于 native 能根據(jù)底層數(shù)據(jù)庫系統(tǒng)的類型, 自動選擇合適的標識符生成器, 因此很適合于跨數(shù)據(jù)庫平臺開

27、發(fā) id 必須為 long, int 或 short 類型, 如果把 id 定義為 byte 類型, 在運行時會拋出異常,映射文件中的標識符,知識點11_1: assigned 標識符生成器 映射單個自然主鍵,映射文件中的標識符,知識點11_2: 映射自然主鍵 -映射復合主鍵 方法一,映射文件中的標識符,知識點11_3: 映射自然主鍵 -映射復合主鍵 方法二,知識點三:映射一對多關聯(lián)關系,一對多關聯(lián)關系,單向關聯(lián):僅僅建立從Order到Customer的多對一關聯(lián),即僅僅在Order類中定義customer屬性?;蛘邇H僅建立從Customer到Order的一對多關聯(lián),即僅僅在Customer類

28、中定義orders集合。 雙向關聯(lián):既建立從Order到Customer的多對一關聯(lián),又建立從Customer到Order的一對多關聯(lián)。,單向多對一,單向一對多,雙向多對一,建立多對一的單向關聯(lián)關系,單向 n-1 關聯(lián)只需從 n 的一端可以訪問 1 的一端 域模型: 從 Order 到 Customer 的多對一單向關聯(lián)需要在Order 類中定義一個 Customer 屬性, 而在 Customer 類中無需定義存放 Order 對象的集合屬性 關系數(shù)據(jù)模型:ORDERS 表中的 CUSTOMER_ID 參照 CUSTOMER 表的主鍵,ORDERS 表,CUSTOMERS 表,建立多對一的單

29、向關聯(lián)關系,Hibernate 使用 元素來映射多對一關聯(lián)關系,many-to-one屬性: * name:設定待映射的持久化類的名字。 * column:設定和持久化類的屬性對應的表的外鍵。 * class:設定持久化類的屬性的類型。 * not-null:是否允許為空。,建立多對一的單向關聯(lián)關系,建立多對一的單向關聯(lián)關系,知識點1:先保存訂單,再保存客戶,Hibernate的輸出結(jié)果: Hibernate: insert into orders (order_number, price, customer_id) values (?, ?, ?) Hibernate: insert int

30、o customers (name) values (?) Hibernate: update orders set order_number=?, price=?, customer_id=? where id=?,Jdbc執(zhí)行: * insert into orders (id,order_number, price, customer_id) values (?, ?, ?,null); * insert into customers (id,name) values (?,?) * c_id=select id from customers * update orders set or

31、der_number=?, price=?, customer_id=? where id=?,建立多對一的單向關聯(lián)關系,知識點2:先保存客戶,再保存訂單,Hibernate的輸出結(jié)果: Hibernate: insert into customers (name) values (?) Hibernate: insert into orders (order_number, price, customer_id) values (?, ?, ?),Jdbc執(zhí)行: * insert into customers (id,name) values (?,?) * c_id=select id f

32、rom customers * insert into orders (id,order_number, price, customer_id) values (?, ?, ?,cid);,建立多對一的單向關聯(lián)關系,知識點3:查詢訂單,Hibernate的輸出結(jié)果: Hibernate: select order0_.id as id1_1_, order0_.order_number as order2_1_1_, order0_.price as price1_1_, order0_.customer_id as customer4_1_1_, customer1_.id as id0_0

33、_, customer1_.name as name0_0_ from orders order0_ left outer join customers customer1_ on order0_.customer_id=customer1_.id where order0_.id=?,Jdbc執(zhí)行: SELECT * FROM customers c LEFT OUTER JOIN orders o ON(c.id=o.customer_id) WHERE o.id=2,建立多對一的單向關聯(lián)關系,知識點4:先保存客戶,再保存訂單 在下面的代碼中注釋掉session.save(c),會有什么后

34、果,產(chǎn)生如下異常 org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.demo.pojo.Customer,建立多對一的單向關聯(lián)關系, ,知識點4:級聯(lián)保存和更新,當hibernate持久化一個臨時對象時,在默認情況下,他不會自動持久化所關聯(lián)的其他臨時對象,會拋出TransientObjectException.如果設定many-to-one元素的cascade屬性為sa

35、ve-update的話,可實現(xiàn)自動持久化所關聯(lián)的對象。,建立多對一的單向關聯(lián)關系,建立一對多的雙向關聯(lián)關系,雙向 1-n 與 雙向 n-1 是完全相同的兩種情形 雙向 1-n 需要在 1 的一端可以訪問 n 的一端, 反之依然. 域模型:從 Order 到 Customer 的多對一單向關聯(lián)需要在Order 類中定義一個 Customer 屬性, 而在 Customer 類中需定義存放 Order 對象的集合屬性 關系數(shù)據(jù)模型:ORDERS 表中的 CUSTOMER_ID 參照 CUSTOMER 表的主鍵,ORDERS 表,CUSTOMERS 表,建立一對多的雙向關聯(lián)關系,Hibernate使

36、用set元素來映射一對多關聯(lián)關系, 元素來映射持久化類的 set 類型的屬性 name:設定待映射持久化類的屬性名。 cascade:設定級聯(lián)操作的程度。 key子屬性:設定與所關聯(lián)的持久化類對應的表的外鍵。 * column: 指定關聯(lián)表的外鍵名 one-to-many子屬性:設定所關聯(lián)的持久化類(集合中存放的對象)。 * class: 指定關聯(lián)的持久化類的類名,映射一對多關聯(lián)關系,Hibernate要求在持久化類中定義集合屬性時,必須把屬性聲明為接口類型,如Set、Map、List.聲明為接口類型可提高持久化類的透明性,當hibernate調(diào)用setOrders()方法時,傳遞的參數(shù)是Hi

37、bernate自定義的實現(xiàn)該接口類的實例。如果定義成類(如HashSet)型,強迫hibernate把該類型的實例傳給他。 底層代碼: Set orders= PersistentSet class PersistentSet implements java.util.Set 通常在定義集合屬性時,直接初始化為一個實現(xiàn)類的實例。 private Set orders = new HashSet(); 可避免空指針異常。,知識點5:定義為接口類型,建立一對多的雙向關聯(lián)關系,知識點6:保存客戶和訂單(客戶和訂單建立雙向關聯(lián)),建立一對多的雙向關聯(lián)關系,知識點7:保存客戶和不保存訂單 在下面的代碼中

38、注釋掉session.save(order1),會有什么后果,產(chǎn)生如下異常 org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.demo.pojo.Customer,建立一對多的雙向關聯(lián)關系,知識點7:級聯(lián)保存和更新 當hibernate持久化一個臨時對象時,在默認情況下,他不會自動持久化所關聯(lián)的其他臨時對象,會拋出TransientObjectException.如果設

39、定set元素的cascade屬性為save-update的話,可實現(xiàn)自動持久化所關聯(lián)的對象。, 元素來映射持久化類的 set 類型的屬性 cascade:設定級聯(lián)操作的程度。,建立一對多的雙向關聯(lián)關系,知識點8:查詢客戶和訂單,Jdbc實現(xiàn) select customer0_.id as id0_0_, customer0_.name as name0_0_ from customers customer0_ where customer0_.id=? select orders0_.customer_id as customer4_0_1_, orders0_.id as id1_, ord

40、ers0_.id as id1_0_, orders0_.order_number as order2_1_0_, orders0_.price as price1_0_, orders0_.customer_id as customer4_1_0_ from orders orders0_ where orders0_.customer_id=?,建立一對多的雙向關聯(lián)關系,1、order1關聯(lián)到customer 而customer沒有關聯(lián)到order1 2、customer關聯(lián)到order2 order3 而order2 order3 沒有關聯(lián)到customer 問題 session.sav

41、e(order1) 插入幾條記錄-4 session.save(customer) 插入幾條記錄-3 session.save(order2) 插入幾條記錄-1,知識點9:對象導航,建立一對多的雙向關聯(lián)關系,知識點9:對象導航,Order orderu1=new Order(); orderu1.setOrderNumber(o_001); Order orders2=new Order(); orders2.setOrderNumber(o_002); Order orders3=new Order(); orders3.setOrderNumber(o_003); Customer c=n

42、ew Customer(); c.setName(楊逍); /orderu1關聯(lián)c c不關聯(lián)order1 orderu1.setCustomer(c); /c關聯(lián)order2和order3 order2和order3不關聯(lián)c c.getOrders().add(orders2); c.getOrders().add(orders3); /session.save(orders2); session.save(orderu1);,建立一對多的雙向關聯(lián)關系,知識點10:保持程序的健壯性 Order orderu1=new Order(); orderu1.setOrderNumber(o_001)

43、; Customer c=new Customer(); c.setName(楊逍); /訂單和客戶關聯(lián) orderu1.setCustomer(c); /客戶和訂單關聯(lián) /c.getOrders().add(orderu1); 這句話是否是可有可無的,為了保持程序的健壯性,加上 /保存客戶 session.save(c); /保存訂單 session.save(orderu1);,方法名(Customer c) c.getOrders().size.=0 這是在使用訂單的時候就關聯(lián)不上訂單了 ,建立一對多的雙向關聯(lián)關系,更改訂單表id=6的customer_id=3更改為4,上面的代碼產(chǎn)生兩

44、條update語句 ,如何產(chǎn)生一條語句呢,完成上面的功能呢? Hibernate: update orders set order_number=?, price=?, customer_id=? where id=? Hibernate: update orders set customer_id=? where id=?,知識點11:訂單變更客戶,建立一對多的雙向關聯(lián)關系,更改訂單表id=6的customer_id=3更改為4 * 使用session緩存的監(jiān)控功能講解為什么產(chǎn)生兩條update語句,Hibernate會自動清理緩存中的所有持久化對象,按照持久化對象的改變來同步更新數(shù)據(jù)庫,因

45、此執(zhí)行了上述的兩條更新語句所以會產(chǎn)生兩條update語句,知識點11:訂單變更客戶,建立一對多的雙向關聯(lián)關系,在hibernate中通過對 inverse 屬性的值決定是由雙向關聯(lián)的哪一方來維護表和表之間的關系. inverse=false 的為主動方,inverse=true 的為被動方, 由主動方負責維護關聯(lián)關系 在沒有設置 inverse=true 的情況下,父子兩邊都維護父子關系 在 1-n 關系中,將 n 方設為主控方將有助于性能改善(如果要國家元首記住全國人民的名字,不是太可能,但要讓全國人民知道國家元首,就容易的多) 在 1-N 關系中,若將 1 方設為主控方 會額外多出 upd

46、ate 語句。,知識點11:set中inverse屬性,建立一對多的雙向關聯(lián)關系,/查詢客戶 Customer c4=(Customer)session.load(Customer.class, 4); /查詢訂單 Order o6=(Order)session.load(Order.class, 6); /建立關聯(lián)關系 o6.setCustomer(c4); /c4.getOrders().add(o6); /加上和不加沒有影響(不按照集合的變化來更新數(shù)據(jù)庫) - 以上代碼僅設置了order對象的customer屬性,hibernate仍然會按照 order對象的狀態(tài)的變化來同步更新數(shù)據(jù)庫,

47、執(zhí)行以下sql語句: Update orders set order_number=.,customer_id=1 where id = 1,知識點11:set中inverse屬性,建立一對多的雙向關聯(lián)關系,/查詢客戶 Customer c4=(Customer)session.load(Customer.class, 4); /查詢訂單 Order o6=(Order)session.load(Order.class, 6); /建立關聯(lián)關系 /o6.setCustomer(c4); /去掉(有影響不會更新) c4.getOrders().add(o6); - 以上代碼僅設置了custome

48、r對象的orders屬性,由于元素的 inverse屬性為true,因此,hibernate不會按照customer對象的狀態(tài) 變化來同步更新數(shù)據(jù)庫。,知識點11:set中inverse屬性,建立一對多的雙向關聯(lián)關系,結(jié)論: 1.在映射一對多的雙向關聯(lián)關系時,應該在one方把inverse屬性設為true, 這可以提高性能。 2.在建立兩個對象的關聯(lián)時,應該同時修改關聯(lián)兩端的相應屬性: customer.getOrders().add(order); order.setCustomer(customer); 這樣才會使程序更加健壯,提高業(yè)務邏輯層的獨立性,使業(yè)務邏輯層的程序代碼 不受Hiber

49、nate實現(xiàn)類的影響。同理,當刪除雙向關聯(lián)的關系時,也應該修改 關聯(lián)兩端的對象的相應屬性: Customer.getOrders().remove(order); Order.setCustomer(null);,知識點11:set中inverse屬性,建立一對多的雙向關聯(lián)關系,知識點12:解除關聯(lián)關系,解除6號訂單和3號客戶的關聯(lián),建立一對多的雙向關聯(lián)關系,知識點13:級聯(lián)刪除刪除1號客戶的同時,刪除1號客戶所關聯(lián)的訂單,如果cascade屬性取默認值none,不會自動刪除和customer關聯(lián)的其他持久化對象。如 果希望刪除customer時,自動刪除和customer關聯(lián)的order對象

50、,可把cascade屬性設 為delete。 再運行刪除方法的時候,會自動刪除order對象,此時hibernate執(zhí)行如下語句: delete from orders where customer_id = 1; delete customers where id = 1; delete from orders where id=1,建立一對多的雙向關聯(lián)關系,知識點14:理解什么是父子關系,所謂父子關系: 是指父方來控制子方的持久化生命周期,子方對象必須和一個父方對象關聯(lián)。,Customer(父方),Order(子方),建立一對多的雙向關聯(lián)關系,知識點14:解除關聯(lián)關系 -父子關系 解除6號

51、訂單和3號客戶的關聯(lián),同時刪除6號訂單,/查詢客戶 Customer c3=(Customer)session.load(Customer.class, 3); /查詢訂單 Order o6=(Order)session.load(Order.class, 6); /設置訂單關聯(lián)的客戶為null o6.setCustomer(null); /從客戶集合刪除訂單 c3.getOrders().remove(o6); mit(); - 如果cascade為默認值none,hibernate會執(zhí)行如下語句: update orders set Customer_id = null where ID

52、= 2; 如果希望程序自動刪除不再和customer關聯(lián)的order對象,可以把cascade屬性設為 all-delete-orphan 或 delete-orphan delete from orders where id=6,建立一對多的雙向關聯(lián)關系,知識點14:解除關聯(lián)關系 -父子關系,當customer.hbm.xml的元素的cascade屬性取值為all-delete-orphan, Hibernate會按照如下方式處理customer對象: 1.當保存或更新customer對象時,級聯(lián)保存或更新所有關聯(lián)的order對象, 相當于save-update. 2.當刪除customer

53、對象時,級聯(lián)刪除所有的order對象,相當于delete。 3.刪除不再和customer對象關聯(lián)的所有order對象。 當關聯(lián)雙方存在父子關系時,就可以把父方的cascade屬性設為all-delete-orphan.,cascade 屬性,在對象 關系映射文件中, 用于映射持久化類之間關聯(lián)關系的元素, , 和 都有一個 cascade 屬性, 它用于指定如何操縱與當前對象關聯(lián)的其他對象.,建立一對多的雙向關聯(lián)關系, 元素有一個 order-by 屬性, 如果設置了該屬性, 當 Hibernate 通過 select 語句到數(shù)據(jù)庫中檢索集合對象時, 利用 order by 子句進行排序 or

54、der-by 屬性中還可以加入 SQL 函數(shù),知識點15:在數(shù)據(jù)庫中對集合排序,知識點四: -操縱持久化對象 -session 緩存的問題(一級緩存) -sessionFactory 二級緩存系統(tǒng)級緩存,操縱持久化對象,知識點1:回顧Java對象在JVM中的生命周期,hibernate 操縱持久化對象,hibernate 操縱持久化對象,操縱持久化對象,操縱持久化對象概述,Session 接口是 Hibernate 向應用程序提供的操縱對數(shù)據(jù)庫的最主要的接口, 它提供了基本的保存, 更新, 刪除和加載Java 對象的方法.,知識點2: session概述,操縱持久化對象,在 Session 接

55、口的實現(xiàn)中包含一系列的 Java 集合, 這些 Java 集合構(gòu)成了 Session 緩存. 只要 Session 實例沒有結(jié)束生命周期, 存放在它緩存中的對象也不會結(jié)束生命周期 當session的save()方法持久化一個對象時,該對象被載入緩存,以后即使程序中不再引用該對象,只要緩存不清空,該對象仍然處于生命周期中。當試圖load()對象時,會判斷緩存中是否存在該對象,有則返回。沒有在查詢數(shù)據(jù)庫,知識點3:理解session的緩存,操縱持久化對象,Session 具有一個緩存, 位于緩存中的對象稱為持久化對象, 它和數(shù)據(jù)庫中的相關記錄對應. Session 能夠在某些時間點, 按照緩存中對

56、象的變化來執(zhí)行相關的 SQL 語句, 來同步更新數(shù)據(jù)庫, 這一過程被稱為清理緩存(flush) 默認情況下 Session 在以下時間點清理緩存: 當應用程序調(diào)用 Transaction 的 commit()方法的時, 該方法先清理緩存(session.flush(),然后在向數(shù)據(jù)庫提交事務(mit() 當應用程序執(zhí)行一些查詢操作時,如果緩存中持久化對象的屬性已經(jīng)發(fā)生了變化,會先清理緩存,以保證查詢結(jié)果能夠反映持久化對象的最新狀態(tài) 顯式調(diào)用 Session 的 flush() 方法.,知識點4_1:清理session的緩存,操縱持久化對象,區(qū)別: flush: 進行清理緩存(此時緩存中的數(shù)據(jù)并

57、不丟失)的操作,讓緩存和數(shù)據(jù)庫同步 執(zhí)行一些列sql語句,但不提交事務,; commit:先調(diào)用flush() 方法,然后提交事務. 則意味著提交事務意味著對數(shù)據(jù)庫操作永久保存下來。 reresh:刷新,讓session和數(shù)據(jù)庫同步,執(zhí)行查詢,把數(shù)據(jù)庫的最新信息顯示出來,更新本地緩存的對象狀態(tài). clear:清空緩存,等價于list.removeAll();,知識點4_2:清理session的緩存,操縱持久化對象,知識點4_2:清理session的緩存,操縱持久化對象,1 Customer c = new Customer(“TOM”,new HashSet(); 2 session.save

58、(c); /customer對象被持久化,并且加入到session的緩存中 3 Long id = c.getId(); 4 c = null; /c變量不再引用customer對象 5 /從session緩存中讀取customer對象,使r2變量引用customer對象 6 Customer r2 = (Customer)session.load(Customer.class,id); 7 mit(); /緩存中的對象和數(shù)據(jù)庫同步 8 session.close(); /關閉session 清空緩存 9 System.out.println(r2.getName(); /訪問customer對象 10 r2 = null; /r2對象不再引用customer對象,customer對象結(jié)束生命周期 - 緩存的作用: 1。減少訪問數(shù)據(jù)庫的頻率。 2。保證緩存中的對象與數(shù)據(jù)庫中的相關記錄保持同步。 3。當緩存中的持久化對象之間存在循環(huán)關聯(lián)關系時,Sess

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論