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

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


咨詢
建站咨詢
