《電子技術應用》
您所在的位置:首頁 > 其他 > 业界动态 > Java类封装关系数据库中数据访问的通用方案

Java类封装关系数据库中数据访问的通用方案

2008-12-19
作者:彭德云* 王嘉祯* 陈卫**

1?引言?

??? 目前的數據庫管理系統" title="管理系統">管理系統(DBMS)中基本上是關系型數據庫(RDBMS)占據著主導地位。從形式上來說,關系數據庫" title="關系數據庫">關系數據庫是一系列行列規整的表的集合,但邏輯上數據庫中數據是對現實世界中事物的抽象描述。而面向對象" title="面向對象">面向對象建模的過程也是對事物的抽象過程。所以關系數據庫中的數據和對象二者間存在一種以其共同描述的現實世界中的事物為紐帶的聯系。利用面向對象思想對關系數據庫中的數據訪問" title="數據訪問">數據訪問進行抽象和封裝,可以有效地提高系統性能、降低開發成本。本文對傳統的數據庫訪問技術的用Java類進行了面向對象的抽象和封裝,并就其中目前廣泛存在的問題" title="存在的問題">存在的問題提出了一種通用的解決方案,極大地提高了開發效率。

2?基本的面向對象的封裝方法?

??? 面向對象思想是目前最為流行的設計思想。充分利用面向對象的思想,對數據庫數據訪問進行抽象和封裝,將帶來以下幾個好處:①對數據和過程進行抽象封裝,提高了系統的模塊獨立性,降低了系統的耦合度;②對相關實體的封裝,有利于構件復用;③信息隱蔽,減少發生錯誤時副作用的傳播;④繼承性使得對超類的修改可以立即作用到所有子類。?

2.1 實體類?

??? 關系數據庫數據訪問操作,可以利用面向對象的思想進行封裝,可以建立“表(或視圖等)—對象”的對應關系,把數據的取、增、刪、改操作封裝成類方法。

??? 在數據庫中,大量的數據訪問許多是對表最基本的數據庫操作(對記錄的取、增、刪、改操作)或這些操作的組合。關系數據庫中的表可以映射為類,表的字段可以映射成類的屬性,對表的操作可以映射成類的方法,表的記錄(行)可以映射成類的對象。現在以一個簡化的學校信息管理系統為例說明數據的訪問過程。圖1中每個方框表示一個實體,在數據庫中每個實體用一個表表示(見圖2)。

??? 如上述的學校管理系統中就可以建立學校類、學生類、教師類、課程類等。一個實體類的屬性通常以對應的表的字段命名;其方法通常是以對某個字段信息的操作命名。比如學生類有學生編號、姓名、性別等屬性,有取編號、設置編號等以getXX和setXX的方法(XX對應于某一屬性)。

2.2實體管理類?

??? 在對“實體”(比如學生Student)抽象和包裝的過程中,往往需要一個對應的“實體管理類”負責對實體的管理工作。因為“實體對象”本身側重于對單個實體的描述,而數據庫訪問通常是對一組滿足特定條件的記錄(對應于一組實體對象)進行操作,所以需要在“YY實體” 層(YY表示某類實體名)之上有一具有對應管理功能的類層次,稱之為“YY實體管理類”。比如“學生類”(Student)的管理類為“學生管理類”(StudentManage)。實體管理類主要的方法對應于相應實體的查找、增加、刪除、修改、列表等操作。一個實體管理類的方法通常是一組有getYY、addYY、deleteYY、editYY、listYY特征的成員函數。

??? 假設現需查詢在特定成績段的學生,就可以調用學生管理類的以成績段為參數的類方法得到所有滿足查詢條件的學生,如果想得到這些學生的信息,則可以調用學生對象的“getXX”方法實現。下面以學校管理系統的學生實體為例進行抽象和封裝。

public abstract class Student{//學生類?

? String id = null;//學生編號?

? String name = null;//學生姓名?

? …?

? public abstract void setId(String _id);//設置學生實體編號?

? public abstract String getId();//取學生實體編號?

? ...?

}?

下面這個類是相應的一個學生管理類的代碼: ?

public class StudentManage{//學生管理類?

? public Student findStudentById(String _id) {…}//查找某一編號的學生?

public boolean deleteStudentById(String _id) {…}//刪除某一編號的學生?

? ...?

}?

2.3 存在問題?

??? 可以看出,通過以上的對學生信息相關操作的封裝,對學生信息的程序處理邏輯上更加清晰,同時也提高了軟件的復用程度,降低了系統的偶合度。但是該模式也有明顯的弊端:①由于實際系統中大量表的存在,要編寫大量相應的封裝類(實體類和相應實體的管理類),封裝類的個數隨著表的數量(N)成約為N*2的比率增長; ②封裝類的大小(主要是成員變量和成員函數的個數)隨著表的字段個數(M)的增加成約為M*λ(λ為封裝類的平均成員函數個數)的比率增長;③對數據庫中表結構的變動會傳播到類的定義上來。?

3?通用解決方案?

3.1解決思路?

??? 上面所提出的抽象和封裝方案問題在于實體的特征和功能(對應于類的屬性和方法)是靜態的:實體的特征和功能在類的定義時就確定下來了(以字段命名),在程序的運行過程中也無法動態改變或更新。這樣就必須把幾乎所有的字段及其操作都對應成類的屬性和方法。通用解決方案就是試圖找到一條能夠克服以上弊端的途徑。其核心思想是將數據庫表及其字段信息存儲在數據庫中,動態地創建實體。該實體類的定義不與特定的表關聯,但能與某個表動態關聯并執行特定的功能。

??? 該方案的實現有兩個問題必須解決:

①動態創建邏輯實體。動態創建邏輯實體需要在給定實體名的條件下能獲得該實體在特定條件下所擁有的特征。實體特征實際上是一個<表名,字段名>的二元組。目前的解決方法是在庫中預先創建一個實體特征表,有三個基本字段:表名、字段名、字段類型。

②動態賦予邏輯實體的特征和功能。目前的解決方法是把實體的特征和特征類型用哈希表(Hashtable)的形式存儲在類中。實體特征的增、刪可以通過對哈希表的操作(put和remove)實現。一個實體屬性一般有兩個實體方法與之對應,即取、設置該屬性值的操作。如果把屬性名稱作為實體方法的參數以標識對某個屬性值的操作,這樣就可以避免為每個屬性值都要編寫對應的方法(getXX和setXX)。

??? 下面就以在學校信息系統中的應用進行說明。在庫中建立一實體特征表UNIT_ATTR,有三個字段:實體名(TABLE_NAME),實體屬性(ATTRIBUTE_NAME),屬性類型(ATTRIBUTE_TYPE)。定義兩個類GerneralUnit和GerneralUnitManage。

3.2通用實體類?

??? 下面是對通用實體類的定義:?

public abstract class GerneralUnit {//通用實體類?

? protected Hashtable attributes = null;//實體的特征(屬性-屬性值)存儲在哈希表中?

? protected String unitName = null;//實體(表)名?

? protected Hashtable field_type =null;//(屬性—屬性類型)?

? public abstract String getStringAttribute(String fieldName);//取某個String類型的屬性值,屬性名作為方法的參數?

? public abstract void setStringAttribute(String fieldName,String value);//設置某個String類型的屬性值,屬性名作為方法的參數?

? ...?

}?

??? 通過這種方式,可以將實體的方法與數據庫的表的字段名動態地關聯起來,其中一個好處就是避免了2節中的問題②③,實體的方法不會隨著關系表的增長而增長,其變動對實體類的定義沒有影響。更重要的一個好處是這種動態關聯使得該實體類成為通用的實體類,這個通用實體類可以隨關系表的不同,可能代表“學生類”、“教師類”、“課程類”、“工資類”等等,解決了問題①。?

3.3通用實體管理類?

??? 下面是對通用實體管理類的定義:?

public class GerneralUnitManage {//通用實體管理類?

? //通過實體主特征查找實體,并返回動態創建的實體對象?

? public GerneralUnit[] getUnits(String unitName,Hashtable mainAttribute){…}?

? public deleteUnit(String _UnitName,Hashtable mainAttribute){…}?

...?

}?

??? 在實體管理類的方法中,對數據庫的操作基本上分為兩種情況:一種是從數據庫關系表中取數據,并根據這些數據為實體屬性賦值;另一種是根據實體的屬性值對關系表的記錄進行添加、修改或刪除。通用性是通過獲取數據庫中表及其字段的相應信息,并根據這些信息動態賦予實體相應屬性值(或根據動態賦予實體的屬性值來進行相應的數據庫操作)來實現的。下面以GerneralUnitManage類中的查找實體方法getUnit為例進行說明:?

public GerneralUnit[] getUnits(String unitName,Hashtable mainAttribute) {//參數:實體名、關鍵特征?

…?

? String strSQL = "select ZDMC, SJLX, ZDHY from VVVV where BMCV='" + unitName + "'";//查找關系表的所有字段?

? while(rs.next()) {?

??? String key = rs.getString("ZDMC");//將實體與關系表關聯起來?

??? …?

??? info.setAttributeType(key,dataType);?

??? …?

}?

String findSQL =…//根據查找實體屬性生成SQL語句?

ResultSet rs = stmt.executeQuery(findSQL);//執行生成的SQL語句,根據結果集生成相應實體?

while(rs.next()){?

? ??…?

??? for (i = 0; i < count; i ++ ) {//為實體賦予屬性值?

????????????? key = keysInDb.get(i).toString();?

????????????? unit.setAttribute(key, rs.getObject(key));?

??????????????????????? ? units.add(unit);?

??? }?

}?

… ?

if(bSuccessToGet)return units;?

else return null;?

}?

??? 因為能將實體和關系表動態關聯,該實體管理類具有通用性。通過對其方法中的參數設置將不同的關系表與通用實體類關聯起來,從而避免了2節中提到的類的數量隨數據庫中關系表的數量正比增長的問題。?

該方案是針對一般情況而設計的。對于某些特殊應用,可以將上述通用方案的某些方法進行重載以滿足部分特殊需求。?

4?結束語?

??? 本文針對面向對象的關系數據庫數據訪問實現中存在的問題,提出了一種新的通用方案。應用該方案可以一次性編寫兩個通用的類代替原來的諸多實體類和實體管理類,代碼量大大減少。并且這兩個類可以幾乎無需修改地應用到其他系統中。該方案已經在多個軍隊自動化系統的開發中得到實際應用。雖然本文是以三層結構模型下的信息系統開發為例進行說明的,但是該方案對兩層結構模型下的開發也有一定的借鑒意義。

參考文獻?

1、? 唐潛、楊德華,用JAVA類封裝RDB庫表──在關系數據庫上運用OO技術探討,計算機應用研究,1999.11

2、? Scott W. Ambler,Mapping objects to relational databases,http://www-900.ibm.com/developerWorks/cn/components/mapping-to-rdb/index_eng.shtml,2000.7

3、? 王建華等譯,最新Java2核心技術(卷Ⅱ:高級性能),機械工業出版社,2003.1

本站內容除特別聲明的原創文章之外,轉載內容只為傳遞更多信息,并不代表本網站贊同其觀點。轉載的所有的文章、圖片、音/視頻文件等資料的版權歸版權所有權人所有。本站采用的非本站原創文章及圖片等內容無法一一聯系確認版權者。如涉及作品內容、版權和其它問題,請及時通過電子郵件或電話通知我們,以便迅速采取適當措施,避免給雙方造成不必要的經濟損失。聯系電話:010-82306118;郵箱:aet@chinaaet.com。
主站蜘蛛池模板: 国产欧美久久久久| 国产精品免费久久久久久| 91久久久久久久久久久| 欧美精品中文字幕一区| 日韩一级免费在线观看| 欧美乱人伦中文字幕在线| 国产日韩欧美在线| 国产精品美女网站| 国产精品91久久久| 欧美精品七区| 99在线精品免费视频| 欧美中日韩一区二区三区| 国产中文字幕免费观看| 日韩在线视频观看| 国产日产欧美视频| 激情六月丁香婷婷| 精品麻豆av| 蜜桃视频一区二区在线观看| 欧美日韩国产不卡在线看| 国产精品激情av电影在线观看| 欧美亚洲国产日本| 91免费国产网站| 成人国产精品av| 亚洲永久激情精品| 国产精品美女xx| 日韩国产精品毛片| 国产精品入口福利| 精品久久久三级| 日韩av在线综合| 久久久久天天天天| 久久精品国产视频| 欧美在线观看日本一区| 久久99久久99精品| 国产在线观看福利| 国产精品美女久久久免费| 欧美一区二视频在线免费观看| 日本国产中文字幕| 久久久久99精品久久久久| 日本在线观看天堂男亚洲| 国产一区二区视频在线观看| 欧美日韩国产91|