面向?qū)ο蠓治雠c設(shè)計 課件 第12章 對象的持久化_第1頁
面向?qū)ο蠓治雠c設(shè)計 課件 第12章 對象的持久化_第2頁
面向?qū)ο蠓治雠c設(shè)計 課件 第12章 對象的持久化_第3頁
面向?qū)ο蠓治雠c設(shè)計 課件 第12章 對象的持久化_第4頁
面向?qū)ο蠓治雠c設(shè)計 課件 第12章 對象的持久化_第5頁
已閱讀5頁,還剩60頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第12章對象的持久化學習目標

了解和掌握持久化的概念和一般方法

理解和掌握通過序列化技術(shù)實現(xiàn)的持久化方法

理解和掌握對象關(guān)系映射的概念和實現(xiàn)方法,理解和掌握對象到關(guān)系數(shù)據(jù)庫的映射方法

了解和掌握數(shù)據(jù)對象到關(guān)系數(shù)據(jù)庫的持久化方法第12章對象的持久化面向?qū)ο笙到y(tǒng)中,對象是系統(tǒng)最基本的構(gòu)成要素,不同的對象往往有不同程度的持久性。因此,設(shè)計和實現(xiàn)一個面向?qū)ο笙到y(tǒng)時,不僅僅需要考慮對象和對象之間的協(xié)作。還需要考慮對象的持久化問題。任何對象都有其特定的生存期,對于生存期較長的持久對象,還需要有其特定的持久方法。關(guān)系數(shù)據(jù)庫是目前應用系統(tǒng)中最重要的信息存儲和管理方法。關(guān)系數(shù)據(jù)庫中,數(shù)據(jù)被結(jié)構(gòu)化成若干個簡單的數(shù)據(jù)表格。這些表格雖然看起來簡單,但一個應用系統(tǒng)的數(shù)據(jù)庫中往往建有大量的數(shù)據(jù)表格,表格之間的關(guān)系也錯綜復雜,分析、設(shè)計和實現(xiàn)一個這樣的數(shù)據(jù)庫也就不是一件很容易的事了。本章將首先討論使用數(shù)據(jù)文件的持久化,然后再詳細地討論使用關(guān)系數(shù)據(jù)庫的對象持久化。12.1持久對象和持久化方法軟件中的任何對象都要占用一定量的存儲空間(內(nèi)存或外存),并在一定的時間內(nèi)存在。我們把一個對象從最初的建立到最終消亡的時間間隔稱為對象的生存期。顯然,不同的對象會有不同的生存期。從持久化的角度來看,可以將系統(tǒng)中的對象分為非持久對象和持久對象。非持久對象是指那些僅在軟件運行期間存在的對象,這些對象的主要特征是其存在性與軟件狀態(tài)相關(guān),軟件運行時它們可以根據(jù)需要而存在,軟件停止運行時,這些對象則不再需要繼續(xù)存在,所以,它們也不需要持久化。12.1持久對象和持久化方法持久對象是指存在性與軟件的運行狀態(tài)無關(guān)的對象,所以,持久對象需要在軟件停止運行時也還要繼續(xù)存在。直到其生命期終結(jié)時,這些對象才被最終撤銷。一般情況下,持久對象可以跨越不同的軟件運行期而存在,有的持久對象還可以跨越不同的軟件系統(tǒng)而存在。軟件運行時,系統(tǒng)中的對象一般都占據(jù)一定的內(nèi)存空間而存在。當軟件停止運行時,持久對象通常需要存儲在某個數(shù)據(jù)文件或數(shù)據(jù)庫中,以保證其存在性。當軟件重新處在運行狀態(tài)時,這些對象將會根據(jù)需要被調(diào)入內(nèi)存并參與系統(tǒng)的運行。程序運行結(jié)束后,這些對象的屬性數(shù)據(jù)(可能是更新后的)將再被保存在數(shù)據(jù)文件或數(shù)據(jù)庫中。對象最終被撤銷時,這些對象的數(shù)據(jù)將被從數(shù)據(jù)文件或數(shù)據(jù)庫中刪除,從而結(jié)束其生命周期。12.1持久對象和持久化方法實現(xiàn)持久化技術(shù)所需要的主要操作,不外乎就是所謂的增、刪、改和查等四個基本操作:1.增加對象:系統(tǒng)在創(chuàng)建新的持久對象時,需要及時地將這些對象的屬性數(shù)據(jù)保存到某個數(shù)據(jù)文件或數(shù)據(jù)庫中去,以實現(xiàn)這些對象的持久性存儲。2.修改對象:系統(tǒng)修改了某個或某些持久對象的屬性時,需要及時更新存儲在外存上的相應的屬性數(shù)據(jù),以保持系統(tǒng)狀態(tài)的一致性。3.刪除對象:當系統(tǒng)最終撤銷一個持久對象時,需要及時刪除被撤銷對象存儲在外存上的屬性數(shù)據(jù)。4.查找對象:當系統(tǒng)需要讀取或定位存儲在外存上的某個或某些持久對象時,所需要完成的操作。其過程是根據(jù)給定條件(如對象標識符),在外存上或定位讀取滿足條件的對象屬性數(shù)據(jù)。當系統(tǒng)中使用了大量持久對象的數(shù)據(jù)時,創(chuàng)建、修改和刪除這三個操作還都應該包含這個查找操作。12.1持久對象和持久化方法另外,持久化技術(shù)必然需要是要外存上的存儲技術(shù)。目前,數(shù)據(jù)在外存上的存儲技術(shù)主要分為文件存儲和數(shù)據(jù)庫存儲兩種技術(shù)。所以,最常見的持久化技術(shù)就包括使用數(shù)據(jù)文件的持久化技術(shù)和使用數(shù)據(jù)庫存儲技術(shù)的持久化技術(shù)兩種情況。設(shè)計時可根據(jù)具體情況選擇或設(shè)計不同的持久化技術(shù)實現(xiàn)持久對象的持久化。12.2基于數(shù)據(jù)文件的序列化技術(shù)基于數(shù)據(jù)文件的序列化技術(shù)又成為序列化或串行化(Serialize)技術(shù)。適用于系統(tǒng)中某些類型的持久對象的數(shù)量固定或較少,并且這些對象之間還不具有強制性、結(jié)構(gòu)性的一致性方面的約束時的情況。序列化(Serialization)是一種將對象的狀態(tài)信息轉(zhuǎn)換為可以存儲或傳輸?shù)男问降倪^程。通過序列化技術(shù),對象可以將其當前狀態(tài)寫入到某個臨時的或具有持久性存儲區(qū)。以后,還可以通過從相應的存儲區(qū)中讀出或反序列化出對象的狀態(tài)數(shù)據(jù),并以此重建該對象??梢钥闯觯蛄谢藘蓚€過程:一個是將對象的狀態(tài)信息轉(zhuǎn)換為適合于存儲或傳輸?shù)男蛄谢问降臄?shù)據(jù)的序列化過程。另一則是將序列化形式的數(shù)據(jù)轉(zhuǎn)換成數(shù)據(jù)對象的屬性數(shù)據(jù)的過程。二者顯然應該是互逆的兩個過程。這兩個過程的引出的另一個問題是,序列化過程應與對象屬性的可見性無關(guān)。序列化時,對象的大多數(shù)屬性都應該是可序列化的,這與屬性的可見性無關(guān)。反序列化過程也一樣。這在客觀上要求需要序列化的對象必須實現(xiàn)其自己的序列化過程(或方法)。12.2基于數(shù)據(jù)文件的序列化技術(shù)1.MFC框架提供的序列化技術(shù)圖12-1給出了MFC類庫中提供的序列化框架。其中CSearlizeObject是一個自定義的需要序列化的類,它需要以CObject類作為基類,并實現(xiàn)Serialize方法以實現(xiàn)序列化,屬性的序列化決策就包含在這個方法(Serialize)中。圖12-1MFC中的序列化技術(shù)框架12.2基于數(shù)據(jù)文件的序列化技術(shù)1.MFC框架提供的序列化技術(shù)圖12-2描述了MFC程序使用序列化技術(shù)將對象屬性數(shù)據(jù)寫入某個文件的過程。MFC中使用CObject抽象類,為序列化定義了一個接口,需要序列化的類必須實現(xiàn)這個接口,并且覆蓋CObject類中的Serialize(CArchive&ar)方法。這個方法的主要特點是它同時封裝了序列化和反序列化這兩個互逆的過程。用戶實現(xiàn)這個過程時,可以自主地決定序列化哪些屬性及其序列化的讀寫順序,此方法對設(shè)計人員的主要約束是序列化和反序列化這些屬性的順序必須一致。12.2基于數(shù)據(jù)文件的序列化技術(shù)1.MFC框架提供的序列化技術(shù)圖12-2MFC序列化對象屬性的過程12.2基于數(shù)據(jù)文件的序列化技術(shù)2.Java語言提供的序列化技術(shù)Java程序設(shè)計語言也則提供了一種使用起來非常簡單的序列化技術(shù)。java序列化技術(shù)提供了Serializable接口和transient關(guān)鍵字兩個機制來支持序列化。Serializable接口是一個沒有封裝任何屬性和可重定義方法的一個接口,其主要作用是聲明一個類是否支持序列化。對于可序列化對象的屬性來說,其默認選項都是可序列化的,當某個屬性不需要序列化時,就可以在這個屬性前面加上一個transient修飾符,這個屬性就不再參與序列化了。其具體的序列化和反序列化過程則被Serializable接口完全封裝了。另外,java序列化結(jié)果是將對象的內(nèi)容序列化成一個流,對于這樣的流,既可用于網(wǎng)絡(luò)傳輸,也可用于磁盤文件的讀寫。12.2基于數(shù)據(jù)文件的序列化技術(shù)2.Java語言提供的序列化技術(shù)圖12-3Java對象的反序列化12.2基于數(shù)據(jù)文件的序列化技術(shù)2.Java語言提供的序列化技術(shù)圖12-4Java序列化數(shù)據(jù)對象12.2基于數(shù)據(jù)文件的序列化技術(shù)2.Java語言提供的序列化技術(shù)下列代碼給出了一個圖12-2和圖12-3中描述的序列化的具體實現(xiàn)。importjava.io.Serializable;publicclassPersonimplementsSerializable{privateStringname;privateintage;publicvoidsetName(Stringname){=name;}publicStringgetName(){returnname;}publicvoidsetAge(intage){this.age=age;}publicintgetAge(){returnage;}}12.2基于數(shù)據(jù)文件的序列化技術(shù)2.Java語言提供的序列化技術(shù)publicclassTestObjSerializeAndDeserialize{publicstaticvoidmain(String[]args)throwsException{SerializePerson();//序列化Person對象Personp=DeserializePerson();//反序列Perons對象System.out.println(MessageFormat.format("name:{0},age:{1}",p.getName(),p.getAge());}}12.2基于數(shù)據(jù)文件的序列化技術(shù)2.Java語言提供的序列化技術(shù)privatestaticvoidSerializePerson()throwsFileNotFoundException,IOException{Personperson=newPerson();person.setName("張三");person.setAge(25);ObjectOutputStreamoo=newObjectOutputStream(newFileOutputStream(newFile("E:/Person.txt")));oo.writeObject(person);//序列化Person對象;oo.close();}12.2基于數(shù)據(jù)文件的序列化技術(shù)2.Java語言提供的序列化技術(shù)privatestaticPersonDeserializePerson()throwsException,IOException{ObjectInputStreamoo=newObjectInputStream(newFileInputStream(newFile("E:/Person.txt")));Personperson=(Person)ois.readObject();//反序列化Person對象

returnperson;}12.3對象模型到關(guān)系數(shù)據(jù)庫的映射從面向?qū)ο蠓椒ǖ陌l(fā)展過程來看,對象模型實質(zhì)上就是對傳統(tǒng)的實體聯(lián)系(ER)模型的一種擴展。傳統(tǒng)的結(jié)構(gòu)化設(shè)計方法中,人們通常首先設(shè)計出系統(tǒng)的實體聯(lián)系模型作為系統(tǒng)的數(shù)據(jù)模型,然后再將這個數(shù)據(jù)模型轉(zhuǎn)換成數(shù)據(jù)庫的關(guān)系模型,從而完成數(shù)據(jù)庫的設(shè)計。面向?qū)ο蠓椒ㄖ校@然也可以用對象模型替代傳統(tǒng)方法中的實體聯(lián)系ER模型來完成數(shù)據(jù)庫的設(shè)計。12.3.1對象到數(shù)據(jù)表的映射對象模型到關(guān)系模型的映射方法的基本思路就是將對象模型中的每個類映射成一個關(guān)系,將這個類的持久屬性映射成域,類的每個實例(即對象)映射成一個記錄。而在具體實現(xiàn)映射時,還要考慮到對象模型中的類之間的各種關(guān)系(如繼承、關(guān)聯(lián)、組合、聚合和依賴等),并把這些關(guān)系也都映射到關(guān)系模型之中。12.3.1對象到數(shù)據(jù)表的映射1.數(shù)據(jù)表主鍵的映射再將一個類映射到一個關(guān)系時,一個比較重要的問題就是主鍵的映射問題。映射時應根據(jù)對象屬性的語義特征識別或定義出對應表的候選鍵和主鍵,從而對應定義數(shù)據(jù)表的實體完整性。當然,也可以根據(jù)這些類之間的關(guān)系識別出表的外鍵,從而進一步定義表的參照完整性。12.3.1對象到數(shù)據(jù)表的映射1.數(shù)據(jù)表主鍵的映射圖12-5給出了一個將“教師類”映射成“教師表”的例子。教師表是從教師類直接映射得到的,其主鍵是教師類的一個屬性(對象標識符)。圖12-5類到數(shù)據(jù)表的映射12.3.1對象到數(shù)據(jù)表的映射1.數(shù)據(jù)表主鍵的映射關(guān)系數(shù)據(jù)庫中,候選鍵是指由表中能唯一標識表中的記錄的屬性構(gòu)成的集合。一個表中可能會有多個不同的候選鍵,數(shù)據(jù)表中對候選鍵的約束是候選鍵中的任何屬性的值都不能為空。主鍵可以是任意選定的一個候選鍵,這通常是人為選定的,選定原則是選定的主鍵應具有用戶可理解的標識數(shù)據(jù)方面的意義并且服從用戶的業(yè)務(wù)邏輯。每個數(shù)據(jù)表必須擁有一個主鍵。外鍵則是指當前表中某個屬性集合,這個屬性集合恰好是數(shù)據(jù)庫中某個表的主鍵(或候選鍵)。數(shù)據(jù)庫系統(tǒng)中,對外鍵的約束條件是,它要么取空值,要么其值必須包含在相關(guān)聯(lián)的數(shù)據(jù)表中。外鍵通常用于持久化對象模型中的關(guān)聯(lián)關(guān)系和泛化關(guān)系。12.3.1對象到數(shù)據(jù)表的映射在將類映射成表時,可用如下兩種方法來定義對應的主鍵。(1)將對象標識符定義為表的主鍵設(shè)計需要持久化的實體類時,就可以為這個類設(shè)計一個或若干個具有唯一標識其實例作用的屬性(對象標識符),映射到數(shù)據(jù)庫時可直接將這個屬性映射為數(shù)據(jù)表的主鍵。例如,學生的學號、工廠的設(shè)備編號等。這樣設(shè)計出來的屬性兼具對象標識符和數(shù)據(jù)庫主鍵兩個方面的意義。并且在將類映射為關(guān)系時,僅在每張表中增加一個列,該列既可作為表的主鍵,也可作為該對象的對象標識符列。在將對象模型中的關(guān)聯(lián)關(guān)系或關(guān)聯(lián)類映射為數(shù)據(jù)表時,關(guān)聯(lián)表的主鍵就可以由與該關(guān)聯(lián)關(guān)系相連接的類的對象標識符組成。這種方法的缺點是,有時會導致對象中可能會含有缺乏問題域方面意義的屬性。不便于用戶理解和使用。12.3.1對象到數(shù)據(jù)表的映射2.對象屬性到域的映射關(guān)系數(shù)據(jù)庫中的域(domain)被定義成一組具有相同數(shù)據(jù)類型的值的集合。落實到具體的關(guān)系數(shù)據(jù)庫系統(tǒng)時,其內(nèi)容就包含了數(shù)據(jù)類型、取值范圍、存儲長度、缺省值和是否可以取空值等方面的內(nèi)容。將類屬性映射到域時,需要清楚地給出每一個域的準確定義。定義數(shù)據(jù)類型時,需要考慮的如何將屬性的數(shù)據(jù)類型轉(zhuǎn)換成數(shù)據(jù)庫系統(tǒng)支持的數(shù)據(jù)類型,二者的關(guān)系一致時,可直接使用。不一致時,則需要考慮使用等價的或兼容的數(shù)據(jù)類型,以確保對象存儲在不同位置的等價性。12.3.1對象到數(shù)據(jù)表的映射2.對象屬性到域的映射對象模型中,通常定義了一些約束條件,如屬性的缺省值、取值范圍以及屬性之間關(guān)系等,這些約束條件通常還與用戶的業(yè)務(wù)邏輯有關(guān)。映射時可考慮將這些約束映射到數(shù)據(jù)庫表中。如對象屬性缺省值可直接映射到數(shù)據(jù)表的中相應字段的缺省值;取值范圍可視情況映射成表屬性的數(shù)據(jù)類型、存儲長度甚至可以映射成SQL的Check子句來表示。枚舉域限定了域所能取值的范圍。枚舉域的實現(xiàn)比簡單域的實現(xiàn)要復雜一些。12.3.2繼承關(guān)系的映射

在將類映射成關(guān)系數(shù)據(jù)庫中的數(shù)據(jù)表時,必然需要處理類之間的繼承關(guān)系。從本質(zhì)上來說,繼承是純粹的類之間的一種關(guān)系,而不是對象之間的關(guān)系。同對象之間的關(guān)聯(lián)關(guān)系相比較,繼承關(guān)系是一種更為抽象地關(guān)系。數(shù)據(jù)庫中存儲的數(shù)據(jù)通常是系統(tǒng)某些對象的數(shù)據(jù)映像。因此,繼承關(guān)系到數(shù)據(jù)庫的映射應該兼顧類及這些類的實例到數(shù)據(jù)庫的映射。

圖12-6給出了某學校管理信息系統(tǒng)中的員工信息類的類圖。12.3.2繼承關(guān)系的映射

圖12-6給出了某學校管理信息系統(tǒng)中的員工信息類的類圖。圖12-6員工信息類類圖12.3.2繼承關(guān)系的映射

圖12-6給出了某學校管理信息系統(tǒng)中的員工信息類的類圖。圖12-6員工信息類類圖12.3.2繼承關(guān)系的映射將這些類映射到數(shù)據(jù)庫時的實質(zhì)就是要將這個學校的所有員工都存儲到數(shù)據(jù)庫中去。類圖描述了教師(teacher)、管理人員(manager)和工人(Worker)等三種人員,并且它們還擁有一個共同的員工角色。這時的每個對象都至少擁有了兩種角色,即其本身的角色(如教師、管理人員和工人)和員工角色。映射時,通??刹扇∪缦聨追N基本方法來處理類之間的繼承關(guān)系。1.將每個類都映射成一個數(shù)據(jù)表這種方式將繼承關(guān)系中的每一個類(超類和子類)都映射成一張表,所有這些表都共享同一個公共的主鍵。這種方式下,將圖12-6中的類映射成數(shù)據(jù)表時,得到的映射結(jié)果如圖12-7所示。12.3.2繼承關(guān)系的映射1.將每個類都映射成一個數(shù)據(jù)表將每個類(超類和子類)都映射成一張表,所有表共享同一個公共的主鍵。圖12-7將每個類都映射成數(shù)據(jù)表12.3.2繼承關(guān)系的映射1.將每個類都映射成一個數(shù)據(jù)表將每個類(超類和子類)都映射成一張表,所有表共享同一個公共的主鍵。圖12-7將每個類都映射成數(shù)據(jù)表12.3.2繼承關(guān)系的映射這種方式的缺點:1)每個類都被映射成一張表會導致數(shù)據(jù)庫中表的數(shù)量偏多。2)同一個對象的屬性需要存儲在多個相互關(guān)聯(lián)的表中,這會導致大量的多表操作,從而延長數(shù)據(jù)的讀寫時間,影響數(shù)據(jù)庫的訪問效率。12.3.2繼承關(guān)系的映射2.將繼承關(guān)系中的每個子類映射成一張數(shù)據(jù)表在這種映射方法中,繼承關(guān)系中的超類將不再映射為數(shù)據(jù)表,而是僅將繼承關(guān)系中子類映射成數(shù)據(jù)表,并且建立的數(shù)據(jù)表中既包含對應子類中的屬性,也包含該子類從其基類中繼承的屬性。這樣就可以有效地減少了數(shù)據(jù)庫表的數(shù)量。12.3.2繼承關(guān)系的映射12.3.2繼承關(guān)系的映射2.將繼承關(guān)系中的每個子類映射成一張數(shù)據(jù)表這種方法的優(yōu)點是每一類對象的屬性數(shù)據(jù)都存儲在同一張表中,可以效地避免第一種映射方法導致的多表操作。其缺點是:當修改某個類時,必須修改它對應的表和它的所有子類對應的表。例如,如果要向人員類中添加“工齡”這樣一個新屬性時,那么就需要同時在上述三張表中添加同樣的屬性。另外,當對象充當多種角色時,為系統(tǒng)增加了新的完整性負擔。例如,當圖12-8中的教師、管理人員和工人三種對象以員工的身份同時出現(xiàn)在系統(tǒng)中時,系統(tǒng)還需要維護這些實體本身的完整性。解決辦法是分別為教師、管理人員和工人三種對象的主鍵定義不同的編碼規(guī)則,以便系統(tǒng)能夠正確地區(qū)分這些不同的實體。12.3.2繼承關(guān)系的映射3.將繼承關(guān)系中的超類映射成一張數(shù)據(jù)表在使用這種方法時,需將所有子類的屬性都存放在超類所對應的數(shù)據(jù)庫表中。換句話來說,就是將一個完整的類層次結(jié)構(gòu)映射為一張數(shù)據(jù)庫表,并且將這個層次結(jié)構(gòu)中所有類的持久屬性都存儲在這張數(shù)據(jù)庫表中。這種方法避免了將每一個子類都映射為數(shù)據(jù)庫表,從而減少了數(shù)據(jù)表的數(shù)量。圖12-9給出了按照此方法將圖12-6中的類層次結(jié)構(gòu)映射得到的數(shù)據(jù)庫表結(jié)構(gòu)的例子。12.3.2繼承關(guān)系的映射3.將繼承關(guān)系中的超類映射成一張數(shù)據(jù)表圖12-9將繼承關(guān)系中超類映射成數(shù)據(jù)表12.3.2繼承關(guān)系的映射3.將繼承關(guān)系中的超類映射成一張數(shù)據(jù)表這種方法的優(yōu)點是簡單,因為所需的所有數(shù)據(jù)都可以在一張表中找到。缺點任何一個類的修改都會影響到數(shù)據(jù)表的修改。因此,這種映射方法還增加了類層次結(jié)構(gòu)中的耦合性,即該結(jié)構(gòu)層次中的任何一個類的修改都可能引起數(shù)據(jù)表結(jié)構(gòu)的修改,當然也就有可能影響到這個類層次結(jié)構(gòu)中的所有類。12.3.2繼承關(guān)系的映射3.將繼承關(guān)系中的超類映射成一張數(shù)據(jù)表由于這種方法將多種不同類型的對象存儲在同一個數(shù)據(jù)表中,顯然會存在大量的空字段,從而造成數(shù)據(jù)庫空間上的浪費。最后的問題是,如果類結(jié)構(gòu)層次中還存在具有多種同層次角色的對象存在時,這種方法還會引起新的多繼承方面的問題。例如,對于圖12-8中的數(shù)據(jù)庫表來說。如果系統(tǒng)中含有了同時充當了多種角色的對象,如一個既是管理人員,同時也是一個教師的員工。那么這個方法也會帶來新的問題。12.3.2繼承關(guān)系的映射3.將繼承關(guān)系中的超類映射成一張數(shù)據(jù)表由于這種方法將多種不同類型的對象存儲在同一個數(shù)據(jù)表中,顯然會存在大量的空字段,從而造成數(shù)據(jù)庫空間上的浪費。最后的問題是,如果類結(jié)構(gòu)層次中還存在具有多種同層次角色的對象存在時,這種方法還會引起新的多繼承方面的問題。例如,對于圖12-8中的數(shù)據(jù)庫表來說。如果系統(tǒng)中含有了同時充當了多種角色的對象,如一個既是管理人員,同時也是一個教師的員工。那么這個方法也會帶來新的問題。12.3.3關(guān)聯(lián)關(guān)系的映射在將對象模型向關(guān)系數(shù)據(jù)庫映射時,不僅要將對象映射至數(shù)據(jù)庫,而且還要將對象之間的關(guān)系也映射到數(shù)據(jù)庫。對象之間主要關(guān)聯(lián)、聚合和組合等三種關(guān)系。本小節(jié)將詳細討論關(guān)聯(lián)、聚合和組合這三種關(guān)系到數(shù)據(jù)庫的映射。12.3.3關(guān)聯(lián)關(guān)系的映射從面向?qū)ο蟮慕嵌葋砜?,關(guān)聯(lián)、聚合與組合都是對象之間的關(guān)聯(lián)關(guān)系,只不過組合和聚合是一種特殊的部分和整體之間的特殊的關(guān)聯(lián)關(guān)系。關(guān)聯(lián)的方式不同,決定了關(guān)聯(lián)對象之間的連接方式、訪問方式以及承擔的系統(tǒng)責任的不同。同時,對象之間的耦合程度也不相同。從數(shù)據(jù)庫的角度看,數(shù)據(jù)庫中的存儲的對象僅僅是系統(tǒng)對象的一種數(shù)據(jù)鏡像,數(shù)據(jù)庫中的對象將不再直接參與系統(tǒng)事務(wù),或者說,它們在數(shù)據(jù)庫中與在系統(tǒng)中所承擔的責任是不相同的。因此,數(shù)據(jù)庫中的對象只要能夠正確描述它的狀態(tài)及以其他對象之間關(guān)系,并能夠正確地跟蹤和及時更新這些狀態(tài)和關(guān)系的變化就可以了。12.3.3關(guān)聯(lián)關(guān)系的映射關(guān)聯(lián)關(guān)系描述了對象之間的訪問關(guān)系,即在一個對象內(nèi)部的任何地方均可訪問到關(guān)聯(lián)對象提供的服務(wù)。在數(shù)據(jù)庫中,關(guān)聯(lián)關(guān)系則僅需要描述成當前對象與哪些個對象有關(guān)聯(lián)關(guān)系即可。關(guān)系數(shù)據(jù)庫中,對象之間的關(guān)系可以使用外鍵機制加以描述。對于一張表來說,外鍵是當前表的一個或多個數(shù)據(jù)屬性,它同時還是另一張表的主鍵或主鍵的一部分。通過外鍵,可以描述一張表中的一個記錄(對象)與另一張表中的某一記錄(對象)之間存在的關(guān)聯(lián)。系統(tǒng)在實例化這些對象時,就可以通過解析表中存儲的這些外鍵的值,實例化出對象之間的關(guān)聯(lián)關(guān)系。下面,我們將從關(guān)聯(lián)多重性的角度出發(fā),討論關(guān)聯(lián)關(guān)系到數(shù)據(jù)庫的映射。12.3.3關(guān)聯(lián)關(guān)系的映射1.一對一關(guān)聯(lián)的映射一對一關(guān)聯(lián)表示對象之間的一對一的聯(lián)系。這種關(guān)聯(lián)的映射可以在一個映射表中加上另一個映射表的主鍵即可。當關(guān)聯(lián)的兩端至少有一個是必選的關(guān)聯(lián)時,可將必選端對象映射的表的主鍵加在另一端對象的映射的表中。此時,加入的外鍵應該帶有一個非空的完整性約束。當關(guān)聯(lián)的兩端都可選時,可將任意一端的對象的映射表的主鍵加在另一端對象的映射表中。12.3.3關(guān)聯(lián)關(guān)系的映射1.一對一關(guān)聯(lián)的映射值得注意的是,實現(xiàn)一對一關(guān)聯(lián)映射時應避免將關(guān)聯(lián)雙方的主鍵分別放置在對應的兩張表中,原因是這種做法容易引起數(shù)據(jù)庫數(shù)據(jù)一致性方面的問題,并且這種做法也不能改善數(shù)據(jù)庫的性能。12.3.3關(guān)聯(lián)關(guān)系的映射1.一對一關(guān)聯(lián)的映射12.3.3關(guān)聯(lián)關(guān)系的映射2.一對多關(guān)聯(lián)的映射

實現(xiàn)一對多關(guān)聯(lián)映射時,可將多重性等于1的一端對象的主鍵添加到多重性為多的對象映射表中,并作為表的外鍵,如果多重性為1的關(guān)聯(lián)是強制的,則還需要進一步為這個外鍵添加非空約束,這個非空約束也為數(shù)據(jù)庫系統(tǒng)帶來操作方面的約束。12.3.3關(guān)聯(lián)關(guān)系的映射2.一對多關(guān)聯(lián)的映射實現(xiàn)一對多關(guān)聯(lián)映射時,可將多重性等于1關(guān)聯(lián)角色的主鍵添加到多重性為多的關(guān)聯(lián)角色的映射表中,并作為表的外鍵。如果多重性為1的關(guān)聯(lián)是強制的,則還需要進一步為這個外鍵添加非空約束,這個非空約束也為數(shù)據(jù)庫系統(tǒng)帶來操作方面的約束。圖12-11給出了實現(xiàn)一對一關(guān)聯(lián)映射的實例。圖中,描述了將學院(School)、教師類(Teacher)以及二者之間的關(guān)聯(lián)映射到關(guān)系數(shù)據(jù)庫的結(jié)果。12.3.3關(guān)聯(lián)關(guān)系的映射映射時,將每個類分別映射成一張表,二者之間的關(guān)聯(lián)則通過將學院類(School)的主鍵SchoolID加入到學生表(TeacherTable)中,并作為學生表的外鍵。圖12-11一對多關(guān)聯(lián)到關(guān)系數(shù)據(jù)庫的映射12.3.3關(guān)聯(lián)關(guān)系的映射2.一對多關(guān)聯(lián)的映射對父表進行(如SchoolTable)操作時,應使修改后的表仍然滿足這樣的約束:(1)插入操作對強制對可選約束來說,任何對象(Teacher對象)都可以不受任何約束地添加到父表中,因為這種約束中的父親不一定必須有子女。(2)修改父表的鍵值如果需要修改父表的鍵值,可以使用數(shù)據(jù)庫事務(wù)的方式,同時修改兩張表的數(shù)據(jù),以維護數(shù)據(jù)的參照完整性。(3)刪除父表記錄可先刪除所有子表中的對應記錄,然后再刪除父表中要刪除的記錄。對于子表來說,除了對外鍵的非空約束之外沒有其他附加的約束。如果在School類和Teacher類的關(guān)聯(lián)中,存在的是可選對可選的約束,則在映射所得的數(shù)據(jù)庫表中,TeacherTable中的列SchoolID則僅是一個外鍵,其值可為空。此時,對映射得到的父表上的操作就不存在上述的強制約束。12.3.3關(guān)聯(lián)關(guān)系的映射3.多對多關(guān)聯(lián)的映射多對多關(guān)聯(lián)關(guān)映射到關(guān)系數(shù)據(jù)庫時,為了節(jié)省存儲空間并減少數(shù)據(jù)冗余,需要引入一個關(guān)聯(lián)表。關(guān)聯(lián)表是一個存儲在數(shù)據(jù)庫中的表,用于維護兩張或多張表之間的關(guān)聯(lián)。關(guān)聯(lián)表中的屬性通常應包括關(guān)聯(lián)關(guān)系中各個表的主鍵的組合。關(guān)聯(lián)表的名字通常命名成它所關(guān)聯(lián)的表的名字的組合,或者是關(guān)聯(lián)本身名字。12.3.3關(guān)聯(lián)關(guān)系的映射3.多對多關(guān)聯(lián)的映射圖中給出了學生(Student)和課程(Course)兩個類,二者之間存在著一個多對多的關(guān)聯(lián)關(guān)系。映射到關(guān)系數(shù)據(jù)庫后得到三個表。其中,學生表(StudentTable)和課程表(CourseTable)分別是由學生類(Student)和課程(Course)類映射得到,第三張表學生選課表(Student_Course_Table),則是由兩個類之間的關(guān)聯(lián)映射后得到的關(guān)聯(lián)表,其屬性就是前兩張表的主鍵的組合,并且構(gòu)成這個關(guān)聯(lián)表的主鍵。12.3.3關(guān)聯(lián)關(guān)系的映射圖12-12給出了一個將多對多關(guān)聯(lián)映射到數(shù)據(jù)庫中的實例。圖12-12將多對多關(guān)聯(lián)映射到關(guān)系數(shù)據(jù)庫12.4數(shù)據(jù)庫對象的持久化過程面向?qū)ο笙到y(tǒng)中,將對象持久化到數(shù)據(jù)庫的過程與基于文件的對象持久化過程類似,也可以分成序列化和反序列化兩個過程。不同的是,一方面,關(guān)系數(shù)據(jù)庫擁有著嚴格的結(jié)構(gòu)定義。另一方面,并且數(shù)據(jù)庫的訪問通常要使用標準的SQL語句來訪問數(shù)據(jù)。下面簡單地討論一下,面向?qū)ο笙到y(tǒng)中訪問數(shù)據(jù)庫的基本技術(shù)。12.4.1使用SQL語句使用SQL語句可以完成的任務(wù)包括:查詢:通過查詢語句可以從數(shù)據(jù)庫中查找滿足條件的記錄,必要時可以根據(jù)查詢結(jié)果創(chuàng)建對象,并將這些對象加入到系統(tǒng)中。插入:將系統(tǒng)中新產(chǎn)生的系統(tǒng)對象插入到對應的數(shù)據(jù)庫表中。刪除:當某個系統(tǒng)對象的生命期結(jié)束時,可以通過發(fā)送一個刪除語句刪除數(shù)據(jù)庫中存儲的數(shù)據(jù)記錄。修改:當某個持久對象的持久屬性得知發(fā)生改變,可以通過發(fā)送一個更新語句修改該對象的屬性數(shù)據(jù),以持久化對象的狀態(tài)。12.4.1使用SQL語句這些任務(wù)中,可以將以增加對象、刪除對象和修改對象屬性為目的的插入、刪除和修改等三種操作定義成類方法直接安排該對象所對應的類或相關(guān)的類中。以讀入和創(chuàng)建對象為目的的查詢操作則可以定義成實例方法安排在對應的類中。其余情況下的數(shù)據(jù)庫操作則可根據(jù)執(zhí)行操作的目的和對象職責的分配分布在適當?shù)念愔小S袝r,將某些數(shù)據(jù)庫操作定義成類作用域方法會使程序具有更大的靈活性。大多數(shù)軟件開發(fā)環(huán)境中,都定義了可重用的數(shù)據(jù)庫訪問控制類,通過這些類,可以很容易地實現(xiàn)數(shù)據(jù)庫的控制和訪問。12.4.2事務(wù)操作關(guān)系數(shù)據(jù)庫中,通常使用事務(wù)機制以解決數(shù)據(jù)操作的一致性和完整性問題。事務(wù)(Transaction)被定義成一組數(shù)據(jù)庫操作構(gòu)成的集合。處理事務(wù)時,可以使一個事務(wù)里的操作要么被完全執(zhí)行,要么完全地不執(zhí)行。正確的事務(wù)處理機制有助于保證事務(wù)性單元內(nèi)的所有操作都成功完成,從而保證了數(shù)據(jù)的完整性和一致性。面向?qū)ο笙到y(tǒng)中,可以通過使用SQL事務(wù)處理語句,將數(shù)據(jù)庫操作封裝成一個完整地事務(wù)。并通過執(zhí)行這些語句實現(xiàn)事務(wù)處理。12.4.3序列化過程與面向流的序列化相比,使用數(shù)據(jù)庫的序列化消除了序列化和反序列化過程之間的耦合。同時,還允許用戶通過隨機訪問的方式修改對象的某個屬性。這有效地提高了系統(tǒng)的工作效率。圖12-13給出了已知的訂單和訂單明細類兩個類的定義,圖12-14給出了訂單類和訂單類的數(shù)據(jù)庫表的結(jié)構(gòu)定義。其中orderid是OrderTable的主鍵,orderid和id是表OrdeItemTable的主鍵,并且orderid是與OrderTable相關(guān)聯(lián)的外鍵。圖12-13訂單和訂單明細類12.4.3序列化過程圖12-14訂單和訂單明細類對應的數(shù)據(jù)表12.4.3序列化過程圖12-15將訂單數(shù)據(jù)添加到數(shù)據(jù)庫的順序圖12.4.3序列化過程圖中出現(xiàn)了Client類、Transaction類、Connection類、Command類、Order類和OrderItem類的對象。其中,Client類是整個過程的客戶類,它負責組織、發(fā)起和控制完成了整個過程。Transaction類、Connection類和Command類分別是數(shù)據(jù)庫事務(wù)類、數(shù)據(jù)庫連接對象類和數(shù)據(jù)庫命令對象類,大多數(shù)的面向?qū)ο箝_發(fā)環(huán)境均提供了這些類。本過程將所有訂單數(shù)據(jù)的插入操作組織成一個數(shù)據(jù)庫事務(wù),以保證訂單數(shù)據(jù)的完整性。Order和OrderItem類分別是訂單類和訂單明細類,是本過程

溫馨提示

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

評論

0/150

提交評論