新聞中心
在軟件項(xiàng)目的分析設(shè)計(jì)過(guò)程中,我們首先分析數(shù)據(jù)實(shí)體,例如確定類(lèi),類(lèi)成員變量或者畫(huà)ER圖。再詳細(xì)設(shè)計(jì)UI界面上有哪些輸入框,文本框等,緊接著我們還會(huì)確定方法的參數(shù)個(gè)數(shù)和類(lèi)型。這些過(guò)程緊密地依賴(lài)于數(shù)據(jù)實(shí)體的穩(wěn)定性,比如在數(shù)據(jù)庫(kù)設(shè)計(jì)中,我們需要多少表,每個(gè)表的字段有多少,它們的類(lèi)型是什么等。但是當(dāng)這個(gè)穩(wěn)定性失去了怎么辦?用戶(hù)很有可能說(shuō)目前我只能為我的表大概確定這些字段。項(xiàng)目組是否該等到用戶(hù)確定之后再做?如果用戶(hù)說(shuō)字段的變化就是我的一個(gè)需求,項(xiàng)目該如何開(kāi)發(fā)?即使所有客戶(hù)能確定字段,不同的客戶(hù)確定的字段可能不會(huì)是一樣的。由于不同的客戶(hù)對(duì)字段的需求不是一樣的,項(xiàng)目組有時(shí)不得不不厭其煩地構(gòu)造源代碼的版本數(shù)。本文基于java環(huán)境,分析和實(shí)現(xiàn)了解決這個(gè)問(wèn)題的方案。首先指出j2ee容器管理持久性實(shí)體bean的不足,接著講述了用java實(shí)現(xiàn)這個(gè)需求的技巧,最后是具體地實(shí)現(xiàn)。

成都創(chuàng)新互聯(lián)公司專(zhuān)業(yè)為企業(yè)提供開(kāi)州網(wǎng)站建設(shè)、開(kāi)州做網(wǎng)站、開(kāi)州網(wǎng)站設(shè)計(jì)、開(kāi)州網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、開(kāi)州企業(yè)網(wǎng)站模板建站服務(wù),十多年開(kāi)州做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
固定字段假設(shè)和CMP實(shí)體BEAN類(lèi)機(jī)制
CMP實(shí)體BEAN機(jī)制也就是容器管理持久性實(shí)體bean機(jī)制。CMP實(shí)體bean的提供者提供的bean類(lèi)具有持久性字段(或?qū)傩裕┑某橄骻et/set方法。這兩個(gè)方法與普通java bean的屬性的get/set方法一樣。下面是一個(gè)Personbean實(shí)體bean類(lèi)的name持久性字段的申明。
- Class Personbean extends EntityBean {
- Abstract String getName();
- Abstract String setName(String vname);
- String ebjCreate(String name) { setName(name);};
- ------
- }
- 部署時(shí),一般部署工具會(huì)產(chǎn)生這個(gè)類(lèi)的子類(lèi),子類(lèi)的申明大概如下:
- Class PersonbeanSubClass extends Personbean{
- Private:
- String name;
- Public:
- String getName(){ return name;}
- String setName(String vname){name=vname;}
- ------
- }
至于具體的字類(lèi)實(shí)現(xiàn)機(jī)制可參見(jiàn)《Mastering Enterprise JavaBeans Second Edition》。容器創(chuàng)建的是子類(lèi)的實(shí)例。通過(guò)父子類(lèi)的比較可知,子類(lèi)通過(guò)一個(gè)私有字段和繼承的兩個(gè)屬性get/set方法實(shí)現(xiàn)了一個(gè)實(shí)體bean的持久性屬性。部署工具是根據(jù)java bean的內(nèi)省機(jī)制生成這個(gè)子類(lèi)的。這樣bean提供者只需規(guī)定持久性字段的抽象訪(fǎng)問(wèn)器函數(shù),其他的持久性實(shí)現(xiàn)都有工具輔助完成。但我們必須注意到,為了指定一個(gè)持久性字段,提供者必須硬編碼兩個(gè)訪(fǎng)問(wèn)方法。同樣我們注意到為了創(chuàng)建一個(gè)實(shí)體Bean,我們?yōu)閑jbCreate方法提供了一個(gè)類(lèi)型為String的參數(shù)。這樣的代碼無(wú)疑建立在這個(gè)實(shí)體bean只有一個(gè)持久性字段的前提之下。類(lèi)似假設(shè)下的語(yǔ)句還有訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)時(shí)的Statement語(yǔ)句:
- Statement st = conn.createStatement();
- St.execuate("insert into person (name) value('John')");
廣泛使用類(lèi)似假設(shè)的例子還有Struts的視圖-模型數(shù)據(jù)交換機(jī)制中ActionForm和HTMLTag定制標(biāo)簽處理類(lèi)的數(shù)據(jù)交互。我暫且稱(chēng)這種假設(shè)為固定字段假設(shè),基于這個(gè)假設(shè)的代碼實(shí)現(xiàn)機(jī)制為CMP實(shí)體BEAN類(lèi)機(jī)制,目的在于重視j2ee中的這個(gè)特征。
不定字段假設(shè)和腳本語(yǔ)言類(lèi)技術(shù)
固定字段假設(shè)和CMP實(shí)體BEAN類(lèi)機(jī)制硬編碼持久性字段,把字段的名字,個(gè)數(shù)和類(lèi)型(本文稱(chēng)為持久性字段的三屬性)三個(gè)中至少一個(gè)固定下來(lái)了,使得更改持久性字段的工作必然影響源代碼,這就產(chǎn)生了一系列令人討厭的代碼樹(shù)。不定字段假設(shè)和腳本語(yǔ)言類(lèi)技術(shù)就是要把持久性字段的三屬性和源代碼分開(kāi),最終達(dá)到客戶(hù)可以訂制持久性字段的目的。典型的實(shí)現(xiàn)技術(shù)有XML,動(dòng)態(tài)編譯技術(shù),元數(shù)據(jù)技術(shù),字典集合技術(shù)等。這些技術(shù)有一個(gè)共同點(diǎn)就是不固定持久性字段,有一個(gè)持久性字段的數(shù)據(jù)容器和一部分分析代碼。分析代碼解釋數(shù)據(jù)容器中的持久性字段,最后執(zhí)行數(shù)據(jù)庫(kù)操作。動(dòng)態(tài)編譯技術(shù)是一個(gè)過(guò)渡技術(shù),它可根據(jù)客戶(hù)配置,動(dòng)態(tài)生成源代碼,接著及時(shí)編譯生成字節(jié)代碼,部署到應(yīng)用中。
3.1 XML
XML是一個(gè)非常好的數(shù)據(jù)交換格式,它具有很好的模式定義(DTD),DTD是XML文檔的元數(shù)據(jù),定義了文檔中數(shù)據(jù)的格式和組成。XML文檔中同時(shí)包含了數(shù)據(jù)名稱(chēng)(元素名或?qū)傩悦┖蛿?shù)據(jù)值(元素文本或?qū)傩灾担?。另外JAVA中有很強(qiáng)的XML文檔分析和使用API,包括JAXP,JAXM等。JAXP集合了基于事件分析的簡(jiǎn)單XML編程接口SAX和節(jié)點(diǎn)數(shù)的DOM分析技術(shù)。JAXM則是利用XML進(jìn)行消息發(fā)送接收和消息處理的編程接口。XSLT能很容易地把XML文檔轉(zhuǎn)為其他格式的文檔如HTML,JAVA源代碼等。
3.2 動(dòng)態(tài)編譯技術(shù)
利用XML表達(dá)用戶(hù)配置信息,XSLT把這些信息轉(zhuǎn)換成相應(yīng)的JAVA源代碼,接著是用java.lang.Compiler類(lèi)及時(shí)編譯產(chǎn)生字接代碼。當(dāng)然你也可以生成其他的輔助類(lèi),sql語(yǔ)句等。詳細(xì)描述請(qǐng)參照 http://www.javaworld.com/javaworld/jw-02-2002/jw-0201-xslt.html
3.3 元數(shù)據(jù)技術(shù)
元數(shù)據(jù)技術(shù)把關(guān)于數(shù)據(jù)的描述放在數(shù)據(jù)字典中,使用者訪(fǎng)問(wèn)數(shù)據(jù)字典可以得到關(guān)于數(shù)據(jù)的信息。數(shù)據(jù)字典可以放在xml文檔中,也可以在數(shù)據(jù)庫(kù)服務(wù)器上。在客戶(hù)配置了持久性字段后,開(kāi)發(fā)者訪(fǎng)問(wèn)數(shù)據(jù)字典可以得到客戶(hù)的當(dāng)前持久性字段,并生成正確的代碼。
3.4 字典集合技術(shù)
java中的哈西表等字典類(lèi)集合數(shù)據(jù)結(jié)構(gòu)可以在方法調(diào)用之間傳遞變化的持久性字段。平常我們的方法調(diào)用是表中有多少字段,填充數(shù)據(jù)庫(kù)的函數(shù)一般要接收多少參數(shù),這樣就把持久性字段硬編碼入了源代碼中,持久性字段變化必會(huì)造成源代碼的變動(dòng)。字典集合技術(shù)使這樣的函數(shù)的接口是固定的。
一個(gè)簡(jiǎn)單任務(wù)
為了應(yīng)用上面的分析,具體體現(xiàn)如何實(shí)現(xiàn)與數(shù)據(jù)庫(kù)表字段松散耦合的j2ee應(yīng)用,在這里提出一個(gè)簡(jiǎn)單的任務(wù):做一個(gè)采集人員信息的應(yīng)用程序。
我們粗略分析一下便可得到一個(gè)人員類(lèi),暫且命名為Person,但字段我們確定不了。采用WAF框架來(lái)設(shè)計(jì)。關(guān)于WAF框架可參見(jiàn) http://www.ibm.com/developerworks/cn/java/l-j2eeArch/index.shtml
4.1 設(shè)計(jì)一、字典集合技術(shù)和元數(shù)據(jù)技術(shù)
下面設(shè)計(jì)圖(圖一)表示:客戶(hù)發(fā)出http請(qǐng)求,容器定位到person.jsp,這個(gè)網(wǎng)頁(yè)分成服務(wù)器部分和客戶(hù)端部分,服務(wù)器部分為在容器中運(yùn)行的指令,這些指令會(huì)build在客戶(hù)瀏覽器上顯示頁(yè)面的客戶(hù)端部分,客戶(hù)端部分聚集(包含)了一個(gè)html表單,表單有一個(gè)提交按鈕,客戶(hù)可以點(diǎn)擊此按鈕發(fā)出提交請(qǐng)求。根據(jù)WAF的框架流程,我們?cè)O(shè)計(jì)一個(gè)personHTMLAction的類(lèi)來(lái)處理用戶(hù)的提交請(qǐng)求。下面是這個(gè)關(guān)鍵類(lèi)的設(shè)計(jì)說(shuō)明:字段:
Connection conn 保存了從容器連接池中獲取的數(shù)據(jù)庫(kù)連接;
Hashtable reqHashNameValue 保存了從用戶(hù)提交的表單中提取的名字-值對(duì);
Hashtable targetHashNameType 保存了從數(shù)據(jù)庫(kù)中獲得的關(guān)于數(shù)據(jù)表persion_table的元數(shù)據(jù)--字段名-類(lèi)型對(duì);
Hashtable finalHashNameValue保存了最后插入到數(shù)據(jù)庫(kù)中的名字-值對(duì);
函數(shù)或方法:
Connect getConnect() 從容器的連接池中獲取數(shù)據(jù)庫(kù)連結(jié);
Hashtable getReqHashNameValue() 從用戶(hù)提交的表單中提取名字-值對(duì);
Hashtable getTargetHashNameType() 從數(shù)據(jù)庫(kù)中獲得關(guān)于數(shù)據(jù)表persion_table的元數(shù)據(jù)--字段名-類(lèi)型對(duì);
Hashtable getFinalHashNameValue() 根據(jù)targetHashNameType中的字段過(guò)濾掉reqHashNameValue中過(guò)多的字段,
得到最后插入到數(shù)據(jù)庫(kù)中的名字-值對(duì);
Void insert()根據(jù)targetHashNameType中的類(lèi)型和finalHashNameValue中的名字-值對(duì)構(gòu)造sql語(yǔ)句,操作數(shù)據(jù)庫(kù)。
這些函數(shù)統(tǒng)一由WAF框架中的這個(gè)類(lèi)的父類(lèi)HTMLAction的一個(gè)函數(shù)perform來(lái)調(diào)用。
圖一:字典集合技術(shù)和元數(shù)據(jù)技術(shù)設(shè)計(jì)
圖二表達(dá)了這個(gè)設(shè)計(jì)達(dá)到的松散耦合效果。第一處在表單和處理類(lèi)之間,它們間的數(shù)據(jù)傳遞充分利用了哈西字典類(lèi)。達(dá)到的直接好處是我們可以開(kāi)發(fā)出定制表單的工具讓客戶(hù)自己定制應(yīng)用的輸入界面,客戶(hù)可以增加各種輸入元素到表單上卻不會(huì)影響后臺(tái)的處理類(lèi)。第二處在處理類(lèi)和數(shù)據(jù)庫(kù)表格之間,它們間的數(shù)據(jù)傳遞充分利用了數(shù)據(jù)庫(kù)中的元數(shù)據(jù)信息,達(dá)到的直接好處是我們可以開(kāi)發(fā)出定制數(shù)據(jù)表的工具讓客戶(hù)自己定制數(shù)據(jù)表的多數(shù)字段,客戶(hù)可以增加減少或修改字段卻不會(huì)影響處理類(lèi)。
4.2 設(shè)計(jì)二、xml技術(shù)、哈西技術(shù)和元數(shù)據(jù)技術(shù)
設(shè)計(jì)圖(圖三)于圖二不同的是我們?cè)诳刂茖觾?nèi)部加上了JMS技術(shù),用XML作為數(shù)據(jù)的交換格式。 XMLpersonHTMLAction的類(lèi)來(lái)處理用戶(hù)的提交請(qǐng)求,PersonMDB把數(shù)據(jù)插入到數(shù)據(jù)庫(kù)中去。下面是這兩個(gè)關(guān)鍵類(lèi)的設(shè)計(jì)說(shuō)明:
XMLpersonHTMLAction類(lèi)
函數(shù)或方法:
String getReqXML() 調(diào)用getParameters()獲得客戶(hù)的提交數(shù)據(jù),產(chǎn)生xml文檔;
Void sendXML() 生成一個(gè)臨時(shí)隊(duì)列作為消息的反饋隊(duì)列,利用JMS API把getReqXML()返回的xml文檔作為JMS的消息體發(fā)送出去。
PersonMDB類(lèi)
字段:
Connect conn 保存了從容器連接池中獲取的數(shù)據(jù)庫(kù)連接;
Hashtable XMLHashNamue 保存了從處理類(lèi)的發(fā)送來(lái)的消息中提取的名字-值對(duì);
Hashtable targetHashNameType 保存了從數(shù)據(jù)庫(kù)中獲得的關(guān)于數(shù)據(jù)表persion_table的元數(shù)據(jù)--字段名-類(lèi)型對(duì);
Hashtable finalHashNamue保存了最后插入到數(shù)據(jù)庫(kù)中的名字-值對(duì);
函數(shù)或方法:
Connect getConnect() 從容器的連接池中獲取數(shù)據(jù)庫(kù)連結(jié);
Hashtable getXMLHashNamue() 從處理類(lèi)的發(fā)送來(lái)的消息中提取名字-值對(duì);
Hashtable getTargetHashNameType()從數(shù)據(jù)庫(kù)中獲得關(guān)于數(shù)據(jù)表persion_table的元數(shù)據(jù)--字段名-類(lèi)型對(duì);
Hashtable getFinalHashNamue()根據(jù)targetHashNameType中的字段過(guò)濾掉XMLHashNamue中過(guò)多的字段,得到最后插入到數(shù)據(jù)庫(kù)中的名字-值對(duì);
Void insert()根據(jù)targetHashNameType中的類(lèi)型和finalHashNamue中的名字-值對(duì)構(gòu)造sql語(yǔ)句,操作數(shù)據(jù)庫(kù);
Void sendReply() 發(fā)送反饋消息給處理類(lèi)。
這些函數(shù)統(tǒng)一由EBJ 2.0 中的消息驅(qū)動(dòng)BEAN的onMessage函數(shù)統(tǒng)一調(diào)用。
圖四表達(dá)了這個(gè)設(shè)計(jì)達(dá)到的松散耦合效果。與圖二相比,這個(gè)設(shè)計(jì)增加了一個(gè)松散耦合,從而增強(qiáng)了設(shè)計(jì)的分布特性。
總結(jié)
不能確定數(shù)據(jù)庫(kù)表的字段是一個(gè)普遍的需求不確定性問(wèn)題,本文通過(guò)對(duì)J2EE技術(shù)的分析總結(jié)出兩個(gè)假設(shè):固定字段假設(shè)和不定字段假設(shè)。有好多關(guān)鍵技術(shù)是基于固定字段假設(shè)的如CMP的實(shí)體BEAN技術(shù),眾多框架的視圖-模型數(shù)據(jù)交換技術(shù)。這個(gè)假設(shè)和基于這個(gè)假設(shè)的技術(shù)往往造成項(xiàng)目的需求不確定風(fēng)險(xiǎn),而且往往使項(xiàng)目組生成枝葉繁盛的源代碼版本數(shù)。不定字段假設(shè)把這種不確定性作為一個(gè)需求來(lái)處理,利用了XML技術(shù)、集合技術(shù)、元數(shù)據(jù)技術(shù)甚至動(dòng)態(tài)編譯技術(shù)解決這個(gè)問(wèn)題,達(dá)到數(shù)據(jù)庫(kù)字段和應(yīng)用松散耦合的最終目的。本文還給出了兩個(gè)設(shè)計(jì)方案供參考。
【編輯推薦】
- J2EE開(kāi)發(fā)框架發(fā)展簡(jiǎn)史續(xù)
- J2ee簡(jiǎn)介
- J2EE應(yīng)用服務(wù)器的現(xiàn)狀與發(fā)展趨勢(shì)
- J2EE、J2SE、J2ME是什么意思?
- J2EE的核心技術(shù)之JDBC簡(jiǎn)介篇
本文標(biāo)題:實(shí)現(xiàn)一個(gè)與數(shù)據(jù)庫(kù)表字段松耦合的J2EE應(yīng)用
網(wǎng)站網(wǎng)址:http://m.5511xx.com/article/coidise.html


咨詢(xún)
建站咨詢(xún)
