六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線(xiàn)學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

Java數(shù)據(jù)對(duì)象(JDO)的前世今生

[摘要]1 Java與數(shù)據(jù)庫(kù)應(yīng)用,JDBC   Java發(fā)明以來(lái),在短短的幾年之間,迅速占領(lǐng)了從桌面應(yīng)用(J2SE)到服務(wù)器(J2EE),再到小型設(shè)備嵌入式系統(tǒng)(J2ME)的應(yīng)用開(kāi)發(fā)市場(chǎng),其語(yǔ)言吸取了SmallTalk的一切皆對(duì)象的理念,擺脫了C++的歷史累贅,簡(jiǎn)潔、自由的風(fēng)格贏得了很多開(kāi)發(fā)者的喜愛(ài)。從J...

  1 Java與數(shù)據(jù)庫(kù)應(yīng)用,JDBC

  Java發(fā)明以來(lái),在短短的幾年之間,迅速占領(lǐng)了從桌面應(yīng)用(J2SE)到服務(wù)器(J2EE),再到小型設(shè)備嵌入式系統(tǒng)(J2ME)的應(yīng)用開(kāi)發(fā)市場(chǎng),其語(yǔ)言吸取了SmallTalk的一切皆對(duì)象的理念,擺脫了C++的歷史累贅,簡(jiǎn)潔、自由的風(fēng)格贏得了很多開(kāi)發(fā)者的喜愛(ài)。從JDK1.1開(kāi)始,Java成為實(shí)用的語(yǔ)言,而不是被人觀望的新品秀;再經(jīng)過(guò)JDK1.2的大量增強(qiáng)(尤其是Collection Framework),JDK1.3的虛擬機(jī)效率提升(HotSpot),JDK1.4的融合百家之長(zhǎng)(Logging、RegExp、NewIO等),現(xiàn)在已經(jīng)是成熟穩(wěn)重,頗顯大家風(fēng)范。

  在企業(yè)級(jí)市場(chǎng)上,大部分的應(yīng)用建立在數(shù)據(jù)庫(kù)基礎(chǔ)上,數(shù)據(jù)是企業(yè)的生命,傳統(tǒng)開(kāi)發(fā)語(yǔ)言,包括面向過(guò)程的C、面向?qū)ο蟮腃++、變種Pascal的Delphi(非常棒的語(yǔ)言,我用過(guò)四年),面向數(shù)據(jù)的PowerBuilder等等,先后在數(shù)據(jù)庫(kù)開(kāi)發(fā)的舞臺(tái)上展現(xiàn)風(fēng)姿。Java當(dāng)然不會(huì)放過(guò)這些,于是,出現(xiàn)了JDBC。在JDBC的幫助下,Java也迅速滲入數(shù)據(jù)庫(kù)開(kāi)發(fā)的市場(chǎng),尤其是面向企業(yè)服務(wù)器的應(yīng)用開(kāi)發(fā)。

  今天要談的JDO,與JDBC有非常密切的關(guān)系,盡管JDO并不是只面向JDBC的數(shù)據(jù)對(duì)象包裝規(guī)范。下面先簡(jiǎn)單地介紹一下JDBC。

  1.1 關(guān)系數(shù)據(jù)庫(kù)之百家爭(zhēng)鳴,ODBC

  關(guān)系數(shù)據(jù)庫(kù)的歷史一言難盡,我只能從我的接觸經(jīng)歷和所見(jiàn)所聞,簡(jiǎn)單地?cái)⑹鲆幌隆W钤绲臅r(shí)候,計(jì)算機(jī)還只在一些大型的研究機(jī)關(guān)露面,并不是普羅大眾可以涉及的。蘋(píng)果電腦將個(gè)人電腦引入民間,再隨著IBM的PC標(biāo)準(zhǔn)開(kāi)放,個(gè)人電腦逐步普及開(kāi)來(lái),加上微軟的DOS操作系統(tǒng),以及Borland的Turbo系列語(yǔ)言開(kāi)發(fā)環(huán)境,老百姓發(fā)現(xiàn)原來(lái)電腦可以做這么多事!后來(lái),出現(xiàn)了DBASE,一個(gè)簡(jiǎn)單的關(guān)系數(shù)據(jù)庫(kù)系統(tǒng),和SQL語(yǔ)言。后來(lái),Borland看到了數(shù)據(jù)庫(kù)的市場(chǎng)前景,推出了Paradox(也是當(dāng)今Delphi和C++Builder中仍然使用的Paradox),一舉占領(lǐng)了民用數(shù)據(jù)庫(kù)的大部分江山,之后,Borland干脆收購(gòu)了Dbase,后來(lái)又購(gòu)買(mǎi)了InterBase,將數(shù)據(jù)庫(kù)市場(chǎng)的領(lǐng)先優(yōu)勢(shì)一直保持到Windows3.0出現(xiàn)。這時(shí)候,微軟在Windows1.0和2.0被人痛罵之后頑強(qiáng)地推出3.0,以及更穩(wěn)定的3.1和Win32API,造就了個(gè)人電腦桌面操作系統(tǒng)的霸主地位,在Borland未警覺(jué)的情況下,購(gòu)買(mǎi)了同樣具有類(lèi)Dbase數(shù)據(jù)庫(kù)技術(shù)的Fox公司,并迅速將其易用化,形成了FoxBase,后來(lái)演變成FoxPro,逐漸超過(guò)了Borland,成為個(gè)人電腦數(shù)據(jù)庫(kù)的大戶(hù)。微軟再接再勵(lì),為簡(jiǎn)單易用而低負(fù)荷要求的數(shù)據(jù)庫(kù)應(yīng)用開(kāi)發(fā)了Access,贏得了廣大開(kāi)發(fā)人員的心。當(dāng)然,同期的Oracle、Sybase、Informix等商用數(shù)據(jù)庫(kù)憑專(zhuān)注于企業(yè)級(jí)數(shù)據(jù)庫(kù)技術(shù)成為高端的幾位領(lǐng)軍人物。微軟當(dāng)然也想成為高端數(shù)據(jù)庫(kù)供應(yīng)商之一,于是自行開(kāi)發(fā)一套面向企業(yè)級(jí)應(yīng)用的數(shù)據(jù)庫(kù),不過(guò)很快項(xiàng)目夭折,微軟不甘心,購(gòu)買(mǎi)了Sybase的底層TDS技術(shù),包裝成了SQL Server,憑微軟的高度易用性的特點(diǎn),也占領(lǐng)了不少市場(chǎng)。

  當(dāng)市場(chǎng)上出現(xiàn)眾多的數(shù)據(jù)庫(kù)產(chǎn)品之后,Borland和微軟都發(fā)現(xiàn)自己擁有的數(shù)據(jù)庫(kù)產(chǎn)品挺多,市場(chǎng)也不小,不同的產(chǎn)品給用戶(hù)帶來(lái)不同的配置任務(wù),不利于所有產(chǎn)品的推廣,于是,兩者紛紛開(kāi)始制定數(shù)據(jù)庫(kù)訪問(wèn)的規(guī)范,微軟推出了ODBC,其面向開(kāi)發(fā)人員的親和性,逐步獲得了認(rèn)可,同時(shí),Borland糾集了IBM和Novell也推出了IDAPI數(shù)據(jù)庫(kù)接口規(guī)范,也就是今天BDE的核心,不過(guò)后來(lái)Novell和IBM先后退出,只剩Borland獨(dú)力支撐。不過(guò)Borland是一個(gè)技術(shù)實(shí)力雄厚的公司,其技術(shù)一向領(lǐng)先于微軟,BDE的性能比初期的ODBC不知道要好多少倍,后來(lái)微軟偷師學(xué)藝,把連接池等技術(shù)加到ODBC中,在Delphi3.0及其BDE在市場(chǎng)上風(fēng)光無(wú)限的時(shí)候,逐步趕了上來(lái)并有超過(guò)。直到今天,BDE仍是Borland的產(chǎn)品線(xiàn)上的數(shù)據(jù)庫(kù)訪問(wèn)標(biāo)準(zhǔn),而微軟如果不是將ODBC和多數(shù)數(shù)據(jù)庫(kù)的客戶(hù)端內(nèi)嵌進(jìn)Windows的話(huà),估計(jì)BDE仍是市場(chǎng)的贏家。不過(guò),微軟是玩弄市場(chǎng)的老手,通過(guò)對(duì)操作系統(tǒng)的壟斷,其數(shù)據(jù)庫(kù)產(chǎn)品和ODBC標(biāo)準(zhǔn)終究占據(jù)了多數(shù)開(kāi)發(fā)市場(chǎng)。

  1.2 從optional pack到JDK的標(biāo)準(zhǔn)API

  Java開(kāi)始涉及數(shù)據(jù)庫(kù)應(yīng)用后,Sun就極力制定Java的數(shù)據(jù)庫(kù)規(guī)范,JDBC API就是類(lèi)似ODBC一樣,對(duì)數(shù)據(jù)庫(kù)訪問(wèn)的底層協(xié)議進(jìn)行最基本的包裝,然后形成一套統(tǒng)一的數(shù)據(jù)訪問(wèn)接口,數(shù)據(jù)庫(kù)連接、SQL語(yǔ)句句柄、結(jié)果集,都帶有ODBC的影子。以方便配置為目的,Sun極力推薦完全瘦客戶(hù)端的TYPE 4型JDBC驅(qū)動(dòng),這是一個(gè)不需要安裝數(shù)據(jù)庫(kù)客戶(hù)端的驅(qū)動(dòng)規(guī)范,是現(xiàn)在使用最多的。當(dāng)然,為了保持與舊的數(shù)據(jù)庫(kù)兼容,JDBC規(guī)范中包括了專(zhuān)用于連接ODBC的TYPE 1驅(qū)動(dòng)和需要安裝數(shù)據(jù)庫(kù)客戶(hù)端的TYPE 2驅(qū)動(dòng),以及可以由廠商在數(shù)據(jù)庫(kù)服務(wù)端專(zhuān)門(mén)提供面向JDBC的服務(wù)的TYPE 3驅(qū)動(dòng)。

  JDBC最早出現(xiàn)時(shí),還不屬于標(biāo)準(zhǔn)JDK的一部分,而是作為一個(gè)額外包提供下載。后來(lái),隨著Java編寫(xiě)的數(shù)據(jù)庫(kù)應(yīng)用的的增多,和JDBC規(guī)范本身的逐漸成熟,JDBC終于成為JDK1.1的一部分。

  JDBC目前最新的是3.0版本,還有正在討論中的4.0版本。實(shí)際上,在開(kāi)發(fā)中使用得最多的還是1.0中的API,2.0中主要增加了可雙向滾動(dòng)的結(jié)果集、更新批處理等提高可用性和性能的API,3.0主要增加了連接池、可更新的結(jié)果集等特性。4.0將在可管理性、連接池規(guī)范化等方面再做改進(jìn)。

  2 面向?qū)ο笈c數(shù)據(jù)庫(kù)

  現(xiàn)在的程序員,沒(méi)有不知道面向?qū)ο蟮摹W鳛榻咏鎸?shí)客觀世界的開(kāi)發(fā)概念,面向?qū)ο笫钩绦虼a更易讀、設(shè)計(jì)更合理。在普遍存在的數(shù)據(jù)庫(kù)應(yīng)用領(lǐng)域,開(kāi)發(fā)人員對(duì)面向?qū)ο蟮淖非髲奈赐V惯^(guò)。從八十年代開(kāi)始,就有很多公司和研究機(jī)構(gòu)在進(jìn)行著面向?qū)ο笈c數(shù)據(jù)庫(kù)結(jié)合的研究。

  2.1 SmallTalk、C與C++、Delphi-Object Pascal、Java

  面向?qū)ο蟮恼Z(yǔ)言最早有好幾種雛形,IBM的SmallTalk是其中最為流行的,在SmallTalk中,一切都是對(duì)象,一切都是類(lèi),它將面向?qū)ο蟮母拍畎l(fā)揮到了極致。面向?qū)ο蟮木幊瘫绕饌鹘y(tǒng)的面向過(guò)程的方式挺進(jìn)了一大步,使人們認(rèn)識(shí)到:原來(lái)軟件可以這樣寫(xiě)。不過(guò),由于計(jì)算機(jī)基本結(jié)構(gòu)與底層硬件體系和系統(tǒng)軟件的限制,SmallTalk還不能在理想的性能前提下推廣到普通的應(yīng)用上,這一點(diǎn)暫時(shí)限制了SmallTalk的發(fā)展,接著,C語(yǔ)言的面向?qū)ο蟀鍯++出現(xiàn)了,由于使用C語(yǔ)言的人很多,C++很快成為面向?qū)ο缶幊痰闹髁髡Z(yǔ)言。不過(guò),為了保證與C的兼容,C++保留了很多面向過(guò)程的痕跡,比如惡心的指針、全局變量等等。Pascal的改進(jìn)版Object Pascal相對(duì)來(lái)說(shuō)安全許多,后來(lái)Borland干脆將Object Pascal換了個(gè)名字,叫Delphi,從此開(kāi)創(chuàng)了一片面向?qū)ο缶幊痰男率澜纾?Delphi的嚴(yán)謹(jǐn)語(yǔ)法和快速編譯吸引了眾多的應(yīng)用開(kāi)發(fā)者,加上Borland的完美的VCL組件體系,比起MFC來(lái)方便而容易,另外,Delphi完整的數(shù)據(jù)庫(kù)組件,也將數(shù)據(jù)庫(kù)開(kāi)發(fā)變得簡(jiǎn)單而容易,Delphi再次成為成熟的面向?qū)ο箝_(kāi)發(fā)語(yǔ)言。微軟當(dāng)然不會(huì)放過(guò)這些,通過(guò)將MFC內(nèi)置到操作系統(tǒng)中,微軟的VC++也搶回一些市場(chǎng)。這也是為什么Delphi開(kāi)發(fā)的應(yīng)用程序編譯后會(huì)比VC、VB開(kāi)發(fā)的程序大的原因。

  1995年,Sun的一個(gè)開(kāi)發(fā)小組本來(lái)為了小型嵌入式系統(tǒng)開(kāi)發(fā)OAK語(yǔ)言,結(jié)果無(wú)心插柳柳成蔭,發(fā)展出了Java語(yǔ)言,它是一個(gè)完全擺脫了傳統(tǒng)語(yǔ)言的各種負(fù)擔(dān)的面向?qū)ο蟮恼Z(yǔ)言,當(dāng)然,也保留了一些非面向?qū)ο蟮暮诵模ㄔ碱?lèi)型)以保證速度。現(xiàn)在Java也為最流行的面向?qū)ο笳Z(yǔ)言之一。當(dāng)然,微軟同樣不會(huì)放過(guò)它,擅于模仿的微軟立即弄出一個(gè)C#來(lái)與之競(jìng)爭(zhēng),并在C#中保留了一些變種的指針(指代)以吸引傳統(tǒng)的C開(kāi)發(fā)者。關(guān)于這些語(yǔ)言的各自特點(diǎn),這里就不一一贅述了。

  2.2 數(shù)據(jù)庫(kù)與數(shù)據(jù)對(duì)象化

  數(shù)據(jù)庫(kù)是企業(yè)級(jí)應(yīng)用不可缺少的,因此,在面向?qū)ο罅餍械臅r(shí)候,數(shù)據(jù)庫(kù)廠商也在進(jìn)行著數(shù)據(jù)對(duì)象化的研究。這些研究在上個(gè)世紀(jì)八十年代就初現(xiàn)端倪。

  數(shù)據(jù)庫(kù)的對(duì)象化一般有兩個(gè)方向:一個(gè)是在主流的關(guān)系數(shù)據(jù)庫(kù)的基礎(chǔ)上加入對(duì)象化特征,使之提供面向?qū)ο蟮姆⻊?wù),但訪問(wèn)語(yǔ)言還是基于SQL;另一個(gè)方向就是徹底拋棄關(guān)系數(shù)據(jù)庫(kù),用全新的面向?qū)ο蟮母拍顏?lái)設(shè)計(jì)數(shù)據(jù)庫(kù),這就是對(duì)象數(shù)據(jù)庫(kù)ODBMS。

  2.2.1 關(guān)系數(shù)據(jù)庫(kù)對(duì)象化、SQL99與JDBC3.0

  隨著許多關(guān)系數(shù)據(jù)庫(kù)廠商開(kāi)始提供對(duì)象化服務(wù),各自的接口開(kāi)始互不兼容,在經(jīng)歷一些麻煩之后,關(guān)系數(shù)據(jù)庫(kù)廠商感覺(jué)到規(guī)范化的必要,因?yàn)楫?dāng)初關(guān)系數(shù)據(jù)庫(kù)雄霸天下時(shí)SQL92標(biāo)準(zhǔn)起了很大作用,大家可以按照統(tǒng)一的編程方式來(lái)訪問(wèn)高性能的商用數(shù)據(jù)庫(kù)。

  關(guān)系數(shù)據(jù)庫(kù)廠商集中起來(lái),重新將對(duì)象化服務(wù)規(guī)范起來(lái),形成了SQL99規(guī)范,將其中的對(duì)象結(jié)構(gòu)等內(nèi)容規(guī)范起來(lái),開(kāi)始一個(gè)嶄新的面向?qū)ο蟮年P(guān)系數(shù)據(jù)庫(kù)(ORDBMS)的歷程。

  JDBC3.0就是在這種情況下出臺(tái)的,它將對(duì)關(guān)系數(shù)據(jù)庫(kù)中的對(duì)象服務(wù)的訪問(wèn)API規(guī)范起來(lái),為Java平臺(tái)提供了訪問(wèn)ORDBMS的標(biāo)準(zhǔn)方式。當(dāng)然,JDBC3.0對(duì)傳統(tǒng)的SQL操作也進(jìn)行了很多功能增強(qiáng)。

  Oracle是一個(gè)傳統(tǒng)的關(guān)系數(shù)據(jù)庫(kù)廠商,在對(duì)象化的道路上,Oracle當(dāng)然采取追加對(duì)象化特征的道路,以侵入數(shù)據(jù)對(duì)象化的市場(chǎng),保持Oracle在數(shù)據(jù)庫(kù)領(lǐng)域的領(lǐng)導(dǎo)地位。如果說(shuō)Oracle7.4使Oracle走向全盛的話(huà),從Oracle8開(kāi)始,Oracle就成為關(guān)系數(shù)據(jù)庫(kù)加對(duì)象類(lèi)型的先驅(qū)。在Oracle8中,我們可以定義一些數(shù)據(jù)結(jié)構(gòu)(Record),將普通的類(lèi)型包裝在其中成為數(shù)據(jù)元素,然后可以在客戶(hù)端按Record結(jié)構(gòu)進(jìn)行訪問(wèn),初步提供了面向?qū)ο蟮臄?shù)據(jù)庫(kù)服務(wù)。

  2.2.2 對(duì)象數(shù)據(jù)庫(kù)

  對(duì)象數(shù)據(jù)庫(kù)就是采用全新的面向?qū)ο蟾拍顏?lái)設(shè)計(jì)數(shù)據(jù)庫(kù)的全新數(shù)據(jù)庫(kù)類(lèi)型。在這方面,主要以一些大學(xué)研究機(jī)構(gòu)進(jìn)行設(shè)計(jì)和開(kāi)發(fā),有些也形成了產(chǎn)品,不過(guò)由于市場(chǎng)方面的原因(主要是關(guān)系數(shù)據(jù)庫(kù)的容易上手和市場(chǎng)絕對(duì)領(lǐng)導(dǎo)地位)和ODBMS先天的一些弱點(diǎn)(比如查詢(xún)引擎很難優(yōu)化),使ODBMS沒(méi)有象關(guān)系數(shù)據(jù)庫(kù)那樣流行起來(lái)。

  不過(guò)對(duì)象數(shù)據(jù)庫(kù)的對(duì)象化特點(diǎn)還是令人割舍不下,目前還是有一些很好的產(chǎn)品在市場(chǎng)上,從商用的到免費(fèi)的都用。目前在ODBMS領(lǐng)域占據(jù)領(lǐng)導(dǎo)地位的是Versant、FastObjects和ObjectStore等幾大廠商,并且,市場(chǎng)份額也在逐步擴(kuò)展。免費(fèi)的產(chǎn)品包括C++編寫(xiě)的Ozone、純Java的db4o等等。還有一些研究機(jī)構(gòu)開(kāi)發(fā)一些底層的面向?qū)ο髷?shù)據(jù)庫(kù)引擎,但只提供一些底層的API,不提供管理方面的功能,以及一些算法提供開(kāi)放式接口,讓廠商去選擇和實(shí)現(xiàn)。比如美國(guó)威斯康新大學(xué)計(jì)算機(jī)系數(shù)據(jù)庫(kù)組的SHORE引擎,就是一個(gè)非常出色的面向?qū)ο髷?shù)據(jù)庫(kù)引擎,現(xiàn)在還在積極的更新中,一些其它研究機(jī)構(gòu)和數(shù)據(jù)庫(kù)廠商采用它完成了自己的特別的對(duì)象數(shù)據(jù)庫(kù),比如專(zhuān)用于地理信息的數(shù)據(jù)庫(kù)、專(zhuān)用于宇宙空間數(shù)據(jù)研究的數(shù)據(jù)庫(kù)等等。

  目前對(duì)象數(shù)據(jù)庫(kù)最大的障礙是缺乏統(tǒng)一的規(guī)范,各個(gè)數(shù)據(jù)庫(kù)廠商有各自的訪問(wèn)接口。對(duì)象數(shù)據(jù)庫(kù)比起關(guān)系數(shù)據(jù)庫(kù)來(lái),不只是基本的幾種數(shù)據(jù)類(lèi)型那么簡(jiǎn)單,它還涉及繼承處理、多態(tài)等一大堆面向?qū)ο筇卣鞯膶?shí)現(xiàn),規(guī)范化道路當(dāng)然困難重重。這也是對(duì)象數(shù)據(jù)庫(kù)無(wú)法普及的一個(gè)重要原因。

  也有一些機(jī)構(gòu)提出了一些建議的規(guī)范,比如制定Corba標(biāo)準(zhǔn)的OMG小組的一個(gè)分組ODMG提出的ODMG規(guī)范,目前已經(jīng)是3.0版本,其中的OQL對(duì)象查詢(xún)語(yǔ)言相當(dāng)具有吸引力。還有一些中立的機(jī)構(gòu)提出了其它的一些標(biāo)準(zhǔn)化的對(duì)象訪問(wèn)API,也可算是面向?qū)ο髷?shù)據(jù)庫(kù)的規(guī)范之一。象前面提到的FastObjects和Ozone就是符合ODMG3.0規(guī)范的。

   3 Java對(duì)象映射

  話(huà)說(shuō)回來(lái),在一般的開(kāi)發(fā)人員眼中,數(shù)據(jù)庫(kù)就是指關(guān)系數(shù)據(jù)庫(kù),因此,很多應(yīng)用還是采用簡(jiǎn)單的JDBC來(lái)訪問(wèn)數(shù)據(jù)庫(kù)。在開(kāi)發(fā)的過(guò)程中,大家逐漸感覺(jué)到JDBC的局限性,比如調(diào)用復(fù)雜、容易產(chǎn)生資源泄漏等等,與面向?qū)ο蟮腏ava語(yǔ)言有一段距離,因此,很多開(kāi)發(fā)小組開(kāi)始思考如何將應(yīng)用中的數(shù)據(jù)進(jìn)行對(duì)象化建模,然后再想辦法與JDBC結(jié)合起來(lái),這就是Java數(shù)據(jù)庫(kù)開(kāi)發(fā)中的層出不窮的對(duì)象包裝技術(shù)。

  3.1 對(duì)象包裝技術(shù)

  3.1.1 傳統(tǒng)包裝與演變

  傳統(tǒng)包裝顧名思義,就是最初出現(xiàn)的包裝方式,很多公司都經(jīng)歷過(guò)這一步,產(chǎn)生了很多風(fēng)格各異的包裝方法。當(dāng)然,筆者也有過(guò)還算豐富的嘗試過(guò)程。

  舉例來(lái)說(shuō),如果我們有一個(gè)用戶(hù)類(lèi):


  public class User {
  public int userId;
  public String name;
  public java.util.Date birthday;
  }


  我們可以將其當(dāng)作一個(gè)簡(jiǎn)單的數(shù)據(jù)類(lèi),然后寫(xiě)一些工具方法來(lái)實(shí)現(xiàn)與JDBC的交互。這些方法,我們可以放到一個(gè)另外的工具類(lèi)中,也可以放到User類(lèi)中作為靜態(tài)方法。這些方法包括簡(jiǎn)單的增、刪、改、查(以O(shè)racle為例):


  public class User {
  public int userId;
  public String name;
  public java.util.Date birthday;

  public static User addUser(String name, Date birthday) throws SQLException {
  Connection conn = …; //獲取一個(gè)JDBC連接
  PreparedStatement ps = conn.prepareStatement("…"); // 獲取一個(gè)序列值來(lái)作為用戶(hù)標(biāo)識(shí)
  ResultSet rs = ps.executeQuery();
  rs.next();
  User user = new User();
  user.userId = rs.getInt(1); //讀取序列值為新用戶(hù)標(biāo)識(shí)
  user.name = name;
  user.birthday = birthday;
  ps = conn.prepareStatement("insert into …."); //插入用戶(hù)數(shù)據(jù)記錄的SQL
  ps.setInt(1,user.id);
  ps.setString(2,user.name);
  ps.setDate(3,user.birthday);
  ps.executeUpdate();
  rs.close();
  ps.close();
  conn.close();
  return user;
  }

  public static void deleteUser(int userId) throws SQLException {
  Connection conn = ….;
  //…
  }

  public static User getById(int userId) throws SQLException {
  //…
  }

  //…
  }


  以上就是一個(gè)簡(jiǎn)單的數(shù)據(jù)包裝的基本雛形,我們可以看到,這是一個(gè)非常簡(jiǎn)單的JDBC包裝,一些代碼可以模塊化,以實(shí)現(xiàn)重用。另外,這段代碼還有很大隱患,就是中途如果出現(xiàn)異常的話(huà),就會(huì)使系統(tǒng)出現(xiàn)JDBC資源漏洞,因?yàn)镴DBC分配的資源(conn,ps,rs等)是不能被Java虛擬機(jī)的垃圾回收機(jī)制回收的。因此,我們的addUser方法就需要改成下面的樣子:


  public static User addUser(String name, Date birthday) throws SQLException {
  Connection conn = null;
  PreparedStatement ps = null;
  ResultSet rs = null;
  User user = new User();
  try {
  conn = …; //獲取一個(gè)JDBC連接
  ps = conn.prepareStatement("…"); // 獲取一個(gè)序列值來(lái)作為用戶(hù)標(biāo)識(shí)
  rs = ps.executeQuery();
  rs.next();
  user.userId = rs.getInt(1); //讀取序列值為新用戶(hù)標(biāo)識(shí)
  user.name = name;
  user.birthday = birthday;
  ps = conn.prepareStatement("insert into …."); //插入用戶(hù)數(shù)據(jù)記錄的SQL
  ps.setInt(1,user.id);
  ps.setString(2,user.name);
  ps.setDate(3,user.birthday);
  ps.executeUpdate();
  } finally {
  //這里注意一定要按照創(chuàng)建的順序關(guān)閉JDBC資源:
  if(rs != null) try { rs.close(); } catch(SQLException ex) { ex.printStackTrace(); }
  if(ps != null) try { ps.close(); } catch(SQLException ex) { ex.printStackTrace(); }
  if(conn != null) try { conn.close(); } catch(SQLException ex) { ex.printStackTrace(); }
  }
  return user;
  }


  所有的數(shù)據(jù)庫(kù)訪問(wèn)方法都必須進(jìn)行這樣的包裝,當(dāng)我們的數(shù)據(jù)類(lèi)達(dá)到一定的數(shù)量后(比如十幾個(gè),幾十個(gè)),這些方法占據(jù)了大量的代碼,維護(hù)困難、出現(xiàn)BUG機(jī)會(huì)增多,并且不易排錯(cuò),尤其是資源漏洞這種容易引起服務(wù)器穩(wěn)定性問(wèn)題的BUG。

  為了保持?jǐn)?shù)據(jù)類(lèi)的純潔,我們可以將JDBC操作方法集中到一個(gè)公共工具類(lèi)中去完成,這樣,這個(gè)工具類(lèi)會(huì)非常龐大,但每個(gè)數(shù)據(jù)類(lèi)會(huì)變得很簡(jiǎn)單,這種方式,可以稱(chēng)作是DataAccessObject模式,相當(dāng)于EJB中的ValueObject,是脫離數(shù)據(jù)庫(kù)細(xì)節(jié)的純對(duì)象模型。

  這些都是最基本的存儲(chǔ)處理,在基本增刪改查(這里的查指按關(guān)鍵字查找對(duì)象)的基礎(chǔ)上,我們還需要進(jìn)行復(fù)雜的匹配查詢(xún)(SQL),這使得我們的存儲(chǔ)處理代碼進(jìn)一步復(fù)雜化。簡(jiǎn)單地,我們可以寫(xiě)一個(gè)類(lèi)似的方法:


  public static Collection findBy(String sql) throws SQLException {
  //… (這里獲取JDBC連接)
  Collection col = new Vector();
  ps = conn.prepareStatement(sql);
  rs = ps.executeQuery();
  while(rs.next()) {
  User user = new User();
  user.userId = rs.getInt(1);
  user.name = rs.getString(2);
  user.birthday = rs.getDate(3);
  col.add(user);
  }
  return col;
  //… (同前,這里是清理JDBC資源的代碼)
  }


  這就是一個(gè)查詢(xún)接口的基本定義,查詢(xún)采用的語(yǔ)言仍是SQL。

  如果我們需要將參數(shù)從SQL串中獨(dú)立出來(lái)以節(jié)省數(shù)據(jù)庫(kù)的解析時(shí)間并規(guī)范化,我們還需要將查詢(xún)條件作為參數(shù)傳遞到這個(gè)方法中去,方法的接口改為:


  public static Collection findBy(String sql, Object[] params) throws SQLException {
  //…
  ps = conn.prepareStatement(sql);
  for(int i = 0; i < params.length; i++) ps.setObject(i+1,params[i]);
  //…
  }


  調(diào)用的時(shí)候sql參數(shù)中會(huì)包含一些"?"號(hào),如:


  select ID,NAME,BIRTHDAY from USER where … = ? and … > ? and …


  當(dāng)然,也有一些開(kāi)發(fā)團(tuán)隊(duì)喜歡將所有可能的查詢(xún)都寫(xiě)死成一個(gè)個(gè)的專(zhuān)用查詢(xún)方法,在其中完成對(duì)應(yīng)的SQL操作,這一點(diǎn)類(lèi)似于EJBQL,只不過(guò)是將EJBQL中容器實(shí)現(xiàn)的功能通過(guò)手工編碼來(lái)實(shí)現(xiàn)。這樣做使得查詢(xún)受到限制,但可以提供更保險(xiǎn)的接口。
   還有一些開(kāi)發(fā)人員看到每個(gè)類(lèi)中寫(xiě)這樣一些查詢(xún)方法使得這個(gè)類(lèi)的代碼變得龐大,維護(hù)麻煩,便將所有的查詢(xún)方法放到一個(gè)公共的工具類(lèi)中去,只是在方法中再加入一個(gè)參數(shù):Class cls來(lái)表示需要查詢(xún)哪個(gè)對(duì)象,使得每個(gè)數(shù)據(jù)類(lèi)變得緊湊一些。當(dāng)然,這樣的結(jié)果是那個(gè)公共類(lèi)變得異常龐大,誰(shuí)維護(hù)誰(shuí)倒霉,可以說(shuō)是犧牲一人,幸福團(tuán)隊(duì)。不過(guò)如果這個(gè)人心理素質(zhì)不夠好、壓力承受能力不強(qiáng)的話(huà),一些對(duì)數(shù)據(jù)類(lèi)的改動(dòng)可能會(huì)受到他的阻礙,這時(shí)候就是"一夫當(dāng)關(guān),萬(wàn)夫莫開(kāi)"。

  現(xiàn)在,我們已經(jīng)實(shí)現(xiàn)了基本對(duì)象的包裝,現(xiàn)在才能開(kāi)始考慮更多的問(wèn)題。首先,我們可能會(huì)從規(guī)范化的角度出發(fā),給每一個(gè)屬性加上讀寫(xiě)訪問(wèn)器getter/setter,在前面的User類(lèi)中,可能我們會(huì)將基本屬性部分寫(xiě)為:


  public class User {
  private int userId;
  private String name;
  private Date birthday;

  //以下是針對(duì)以上屬性的getter/setter,一般可以用IDE工具生成
  public int getUserId() { return userId; }
  public void setUserId(int value) { userId = value; }
  public String getName() { return name; }
  public void setName(String value) { name = value; }
  public Date getBirthday() { return birthday; }
  public void setBirthday(Date value) { birthday = value};

  //…
  }


  這樣,一個(gè)比較規(guī)范的數(shù)據(jù)類(lèi)包裝就算完成了。

  另外,我們知道,面向?qū)ο蟾拍钪校粋(gè)屬性可以是另一個(gè)對(duì)象,也就是說(shuō),對(duì)象之間是存在著引用關(guān)系的,這種關(guān)系還分為一對(duì)一、一對(duì)多、多對(duì)多等幾種情況。從一個(gè)既定對(duì)象出發(fā),其某個(gè)屬性可以是另一個(gè)對(duì)象,也可以是包含另一組對(duì)象的集合。那么,在我們的數(shù)據(jù)包裝里面,當(dāng)然最好也能方便地處理對(duì)象之間的關(guān)系。假定現(xiàn)在我們又有一個(gè)數(shù)據(jù)類(lèi)Group:


  public class Group {
  public int grouId;
  public String groupName;
  public Set users; //set of User
  }


  這里為了簡(jiǎn)單表明含義,暫不采用getter/setter。

  而User對(duì)所屬的Group有一個(gè)引用:


  public Group belongTo;


  在這里,User.belongTo和Group.users就是一個(gè)一對(duì)多的關(guān)系。

  在我們的數(shù)據(jù)類(lèi)中,如何才能實(shí)現(xiàn)數(shù)據(jù)庫(kù)的存取呢?就算是不考慮Group.users這個(gè)反向關(guān)系,光是User.belongTo就是一件頭疼的事。如果我們?cè)谌〕鲆粋(gè)User對(duì)象時(shí)同時(shí)將其Group對(duì)象也取出來(lái),可以保證不會(huì)在訪問(wèn)某個(gè)用戶(hù)的組時(shí)得到一個(gè)null。不過(guò)這樣有幾個(gè)缺點(diǎn):

  1. 數(shù)據(jù)類(lèi)的存取處理(JDBC)變得復(fù)雜,需要執(zhí)行很多SQL讀取才行,有時(shí)候只需要訪問(wèn)User的基本屬性時(shí)浪費(fèi)時(shí)間和資源;尤其是對(duì)集合型屬性的預(yù)讀取,更加可怕

  2. 如果按這個(gè)邏輯,雙向的關(guān)系處理變得危險(xiǎn),很容易陷入死循環(huán),如果要避免,必須在類(lèi)代碼中加入一些特別的機(jī)制,也是很麻煩的事

  3. 如果對(duì)象之間的關(guān)系是更復(fù)雜的情況下,比如三個(gè)、四個(gè)對(duì)象之間互相關(guān)聯(lián),那就是一場(chǎng)噩夢(mèng),對(duì)代碼的編寫(xiě)和維護(hù)都異常艱難

  于是,很多開(kāi)發(fā)人員自然而然地退后一步,在User類(lèi)中只保留一個(gè)groupId,并不保存Group對(duì)象,這樣,可以將User.belongTo屬性變成int類(lèi)型,而另外寫(xiě)一個(gè)getter方法:


  public Group getBelongTo() {
  return Group.findById(belongTo);
  }


  而在Group類(lèi)中,干脆將users屬性去掉,只保留一個(gè)方法:


  public Set getUsers() {
  return new HashSet(User.findBy("select … from USER where BELONG_TO=?",new Object[]{ new Integer(groupId) }));
  }


  也許細(xì)心一點(diǎn)的讀者已經(jīng)看出來(lái)了,這里的幾個(gè)方法都沒(méi)有將SQLException捕捉,也沒(méi)有在方法中聲明,也就是說(shuō)是有語(yǔ)法錯(cuò)誤的,因?yàn)镾QLException不是一個(gè)RuntimeException。不錯(cuò),確實(shí)是這樣,不過(guò)我們這里為了簡(jiǎn)單明了起見(jiàn),省掉這些處理,以更直接清楚地表達(dá)意思。

  這樣,實(shí)際上,我們的對(duì)象關(guān)系包裝已經(jīng)名存實(shí)亡,在類(lèi)的內(nèi)部有很多用于訪問(wèn)所引用對(duì)象的復(fù)雜代碼,這些已經(jīng)違背了我們將對(duì)象關(guān)系保持的初衷。有些開(kāi)發(fā)人員甚至不在類(lèi)中保留訪問(wèn)關(guān)系對(duì)象的方法,而是在客戶(hù)調(diào)用時(shí)再去訪問(wèn)另一對(duì)象類(lèi)的讀取方法,如:


  …

  User user = User.getById(…);
  //對(duì)user對(duì)象進(jìn)行一些訪問(wèn),如顯示其姓名等等
  Group group = Group.findById(user.belongTo);
  //對(duì)group對(duì)象進(jìn)行一些訪問(wèn),如顯示組名等等
  …


  在這樣的代碼里,實(shí)際上我們已經(jīng)從根本上退回了關(guān)系數(shù)據(jù)庫(kù)的出發(fā)點(diǎn),這與直接訪問(wèn)數(shù)據(jù)表有多大區(qū)別呢?只不過(guò)是在表上面套了一層貌似面向?qū)ο蟮钠ざ选2恍业氖牵@種方式還存在于很多應(yīng)用之中。

  從前面提到的這些面向?qū)ο蟀b的細(xì)節(jié)問(wèn)題,我們可以看到這種傳統(tǒng)包裝方式的一些主要的缺陷:

  3.1.1.1 數(shù)據(jù)庫(kù)命名與對(duì)象設(shè)計(jì)命名的一致性問(wèn)題

  很多時(shí)候,我們興致勃勃地設(shè)計(jì)好一個(gè)類(lèi)圖,并且經(jīng)過(guò)評(píng)審之后,開(kāi)始對(duì)它進(jìn)行數(shù)據(jù)庫(kù)包裝,這時(shí)候,發(fā)現(xiàn)有些屬性名在具體的數(shù)據(jù)庫(kù)中與該數(shù)據(jù)庫(kù)的關(guān)鍵字沖突,不能用作表名或字段名,必須在數(shù)據(jù)表設(shè)計(jì)時(shí)采用另外的名稱(chēng),或者很麻煩地加上引號(hào)來(lái)使用。于是,寫(xiě)數(shù)據(jù)庫(kù)處理代碼的人有意見(jiàn)了,他必須很清楚地記得一個(gè)屬性在類(lèi)中是什么屬性名,在表中又是什么字段名,在編寫(xiě)的類(lèi)逐漸增多后,尤其是一個(gè)類(lèi)經(jīng)過(guò)歷次變動(dòng)之后,或者經(jīng)過(guò)很長(zhǎng)時(shí)間又需要改動(dòng),并去處理這些JDBC代碼時(shí),代碼維護(hù)人員簡(jiǎn)單要發(fā)瘋了!

  3.1.1.2 對(duì)象的查詢(xún)?nèi)跃窒抻赟QL

  這一點(diǎn)也是這種簡(jiǎn)單的包裝方法最不能擺脫關(guān)系數(shù)據(jù)庫(kù)的地方。上面也已經(jīng)說(shuō)過(guò),一些命名沖突帶來(lái)了很多維護(hù)工作量,代碼中必須還保留數(shù)據(jù)表的命名體系,而不是對(duì)象類(lèi)的命名體系。這將使調(diào)用人員仍需要清楚記得兩套命名體系,無(wú)論時(shí)間經(jīng)過(guò)多久,或者開(kāi)發(fā)人員是否有流動(dòng)。

  此外,對(duì)于普遍需要用到的連表查詢(xún),也給應(yīng)用開(kāi)發(fā)帶來(lái)困難,這些地方仍不能突破SQL的限制。

  3.1.1.3 SQL資源占用多

  在處理對(duì)象集合訪問(wèn)或者處理集合類(lèi)型屬性時(shí),往往我們只能在同一個(gè)Connection中處理一切事務(wù),這就要求一次性地將集合中的對(duì)象全部讀入,如果集合很大的話(huà),容易造成數(shù)據(jù)庫(kù)擁塞,使得性能大打折扣,適得其反。這方面的優(yōu)化也是很多開(kāi)發(fā)人員一直在努力改進(jìn)的。

  3.1.1.4 對(duì)象關(guān)系處理復(fù)雜

  前面提過(guò),對(duì)象之間的關(guān)系處理上,普通的包裝技術(shù)是一種表面上的處理,在訪問(wèn)時(shí)調(diào)用者仍需要用大量的代碼進(jìn)行處理,并且,這還只是讀取,在寫(xiě)入關(guān)系屬性時(shí)會(huì)有更多的細(xì)節(jié)問(wèn)題需要處理。

  3.1.1.5 面向?qū)ο筇厣荒軕?yīng)用一小部分

  面向?qū)ο蟮陌b到前面所說(shuō)的為止,都還只是很基本的處理,而面向?qū)ο蟮木A:繼承和多態(tài),在這里得不到任何幫助。我們放棄了很多合理的設(shè)計(jì)來(lái)遷就數(shù)據(jù)庫(kù)的包裝。

  以上就是基本數(shù)據(jù)包裝的主要缺陷,還有更多的小問(wèn)題也需要額外的處理。

  不過(guò),有責(zé)任心的開(kāi)發(fā)人員當(dāng)然不會(huì)就此善罷甘休,他們冥思苦想,可能會(huì)用更好的方式來(lái)實(shí)現(xiàn)對(duì)象之間關(guān)系的處理,而且還會(huì)加入一些延遲訪問(wèn)的機(jī)制,將對(duì)象之間的引用在需要用的時(shí)候才去連接數(shù)據(jù)庫(kù)取數(shù)據(jù),另外,在類(lèi)的繼承上,他們也試圖去在數(shù)據(jù)庫(kù)包裝上得到體現(xiàn)。

  值得感謝的是,一些富有經(jīng)驗(yàn)的團(tuán)隊(duì)在經(jīng)歷若干改進(jìn)之后,毫不吝惜將他們的成果貢獻(xiàn)出來(lái),并將其獨(dú)立化,成為可復(fù)用的組件。這也就是后來(lái)出現(xiàn)的對(duì)象包裝產(chǎn)品,包括商用的和免費(fèi)的。

  3.1.2 產(chǎn)品化包裝中間件

  面向?qū)ο蟮陌b產(chǎn)品化后,逐步推廣開(kāi)來(lái),稱(chēng)作關(guān)系/對(duì)象映射:O/R Mapping。并且,在產(chǎn)品化的過(guò)程中,產(chǎn)品提供者在產(chǎn)品中逐漸提供了更多的功能。先是一些自動(dòng)命名轉(zhuǎn)換器得以應(yīng)用,將客戶(hù)代碼中的類(lèi)名、屬性名在內(nèi)部處理的時(shí)候自動(dòng)地轉(zhuǎn)換到對(duì)應(yīng)的數(shù)據(jù)庫(kù)結(jié)構(gòu)命名空間上,這樣,應(yīng)用開(kāi)發(fā)的時(shí)候不再關(guān)心具體的數(shù)據(jù)庫(kù)結(jié)構(gòu),不再需要記憶不同地命名體系,只需要一心一意地根據(jù)類(lèi)圖來(lái)進(jìn)行開(kāi)發(fā)。在此之后,這些O/R Mapping產(chǎn)品的開(kāi)發(fā)團(tuán)隊(duì)又向前邁了一大步:引入了詞法分析器,提供面向?qū)ο蟮牟樵?xún)語(yǔ)言!很多對(duì)象關(guān)系的查詢(xún)使應(yīng)用開(kāi)發(fā)變得非常方便,使O/R Mapping產(chǎn)品上了一個(gè)新的臺(tái)階。

  3.1.2.1 TopLink

  TopLink是一個(gè)非常早期的產(chǎn)品,最初面向C++,后來(lái)也實(shí)現(xiàn)了Java的映射。TopLink性能優(yōu)異,功能強(qiáng)大,并且提供了獨(dú)特的查詢(xún)過(guò)濾器機(jī)制,以及對(duì)關(guān)系的處理和查詢(xún)都非常有效,于是,TopLink逐漸從商用化O/R Mapping產(chǎn)品中勝出,成為市場(chǎng)上的最出色的映射產(chǎn)品。也正因?yàn)檫@一點(diǎn),最大的關(guān)系數(shù)據(jù)庫(kù)廠商O(píng)racle將其收購(gòu),成為提供最強(qiáng)數(shù)據(jù)庫(kù)和最強(qiáng)對(duì)象映射中間件的廠商。

  3.1.2.2 Castor、Hibernate

  TopLink雖然強(qiáng)大,但太強(qiáng)大的東西免不了得意忘形,TopLink開(kāi)始將用戶(hù)鎖死到自己的產(chǎn)品上,查詢(xún)方式是最突出的。它的查詢(xún)體系含有很多別扭的概念(在我看來(lái)是如此),但為達(dá)到一般O/R產(chǎn)品不能達(dá)到的功能,開(kāi)發(fā)者只能接受這些。慢慢地,也產(chǎn)生積怨,再加上其高昂的價(jià)格,讓很多新老用戶(hù)望而卻步。于是,免費(fèi)的產(chǎn)品開(kāi)始崛起。

  免費(fèi)的O/R Mapping工具有很多種,這里只提其中最有影響力的兩種:Castor和Hibernate。

  Castor是Exolab組織開(kāi)發(fā)的面向Java的包裝工具,它最大的特色就是實(shí)現(xiàn)了大部分的ODMG OQL規(guī)范,在查詢(xún)上,可以象完全使用一個(gè)對(duì)象數(shù)據(jù)庫(kù)一樣類(lèi)圖進(jìn)行查詢(xún)(后面會(huì)有介紹)。它的原理是通過(guò)Java反射API去實(shí)現(xiàn)屬性的設(shè)置和讀取。不過(guò)由于各種原因,Castor后來(lái)的版本更新越來(lái)越慢,最終停步在1.0之前,成為至今未出到1.0正式版的O/R Mapping產(chǎn)品。不管怎么樣,它還是一個(gè)相當(dāng)不錯(cuò)的產(chǎn)品。
  Hibernate是一個(gè)現(xiàn)在很火熱的O/R Mapping產(chǎn)品,目前已經(jīng)出到2.0版,它功能一樣強(qiáng)大,同樣使用Java反射API進(jìn)行對(duì)象的設(shè)置,但它的查詢(xún)語(yǔ)言就是一套比較獨(dú)特的體系,這一點(diǎn)有點(diǎn)類(lèi)似TopLink,但Hibernate更具有親和力,對(duì)關(guān)系的查詢(xún)更方便,只不過(guò)比起Castor來(lái),在方便性和規(guī)范性上還是稍遜一籌。就目前狀況而言,Hibernate的用戶(hù)量和技術(shù)支持要強(qiáng)一些。
   3.2 面向?qū)ο蟮臄?shù)據(jù)庫(kù)查詢(xún)

  在對(duì)數(shù)據(jù)庫(kù)進(jìn)行面向?qū)ο笱芯康倪^(guò)程中,軟件世界的開(kāi)發(fā)人員和設(shè)計(jì)人員們發(fā)現(xiàn):對(duì)數(shù)據(jù)庫(kù)能夠進(jìn)行對(duì)象化的查詢(xún),才是對(duì)數(shù)據(jù)庫(kù)進(jìn)行徹底的面向?qū)ο蠡_@體現(xiàn)在我們使用一種全新的數(shù)據(jù)庫(kù)查詢(xún)語(yǔ)言,能夠很簡(jiǎn)潔易懂地對(duì)數(shù)據(jù)庫(kù)中的對(duì)象進(jìn)行查詢(xún)。一個(gè)典型的例子如下:
  假設(shè)我們已經(jīng)有前面提到的兩個(gè)數(shù)據(jù)類(lèi):User和Group,它們之間有一對(duì)多的關(guān)系:User.belongTo和Group.users。在數(shù)據(jù)庫(kù)中已經(jīng)存在很多這兩個(gè)類(lèi)的實(shí)例,以及相互之間的關(guān)系。我們可以使用下面的對(duì)象式查詢(xún)語(yǔ)言來(lái)查詢(xún)符合條件的User對(duì)象:

  select * from User where User.belongTo.name='GROUP1'
  
  或者

  select userId,name from User where User.belongTo.name='GROUP2'

  等等。從中我們可以看出,通過(guò)使用面向?qū)ο笾械某蓡T屬性指定符".",可以讓我們達(dá)到SQL中的連表的效果,實(shí)際上,第一個(gè)句查詢(xún)的SQL等價(jià)版本是:

  select a.* from USER a, GROUP b
  where a.BELONG_TO = b.GROUP_ID
  and b.NAME = 'GROUP1'

  由此可見(jiàn),對(duì)象式的查詢(xún)語(yǔ)言,比起實(shí)現(xiàn)同樣功能的SQL語(yǔ)言來(lái)說(shuō),簡(jiǎn)單了很多,意義也更明確,更符合使用者的思維習(xí)慣。在類(lèi)圖比較復(fù)雜、查詢(xún)涉及的類(lèi)又比較多的時(shí)候,這種新型的查詢(xún)語(yǔ)言體現(xiàn)出絕對(duì)的優(yōu)勢(shì)。

  3.2.1 ODMG,OQL,Java Binding

  在面向?qū)ο笫讲樵?xún)語(yǔ)言的研究過(guò)程中,開(kāi)發(fā)人員們逐漸實(shí)現(xiàn)了相似的查詢(xún)語(yǔ)言,然后互想取長(zhǎng)補(bǔ)短,最終在ODMG組織(www.odmg.org)的統(tǒng)一下,形成了規(guī)范化的語(yǔ)言:ODMG OQL,這是一種完全面向?qū)ο蟮臄?shù)據(jù)庫(kù)查詢(xún)語(yǔ)言,語(yǔ)法與前面提到的類(lèi)似,不過(guò)考慮了更廣泛的情況,語(yǔ)句更加簡(jiǎn)潔而嚴(yán)謹(jǐn)。

  OQL并不是針對(duì)某種語(yǔ)言的,它可以被應(yīng)用到很多種開(kāi)發(fā)語(yǔ)言中,它不象SQL那樣只是純字符串式的查詢(xún)語(yǔ)句,因?yàn)槊嫦驅(qū)ο蟛樵?xún)中還必須提供相關(guān)類(lèi)的信息,所以O(shè)QL需要在編程語(yǔ)言中實(shí)現(xiàn)一些特定的API。

  目前,ODMG的OQL已經(jīng)被規(guī)范化地應(yīng)用到SmallTalk、Java、C++這些面向?qū)ο蟮某绦蛟O(shè)計(jì)語(yǔ)言當(dāng)中,在ODMG的規(guī)范中,這幾個(gè)模塊被稱(chēng)作SmallTalk Binding、Java Binding和C++ Binding。

  不過(guò),由于歷史原因,ODMG并沒(méi)有象想象中地那樣得到廣泛應(yīng)用,現(xiàn)有的十幾個(gè)面向?qū)ο髷?shù)據(jù)庫(kù)中,采用ODMG OQL規(guī)范的少之又少,目前也只有FastObjeccts、Ozone這些產(chǎn)品采納了這個(gè)規(guī)范,而象Versant這樣的大廠商還沒(méi)有采取OQL來(lái)查詢(xún)數(shù)據(jù)庫(kù),而是自己定義了自己的一套API,稱(chēng)作VQL(Versant Query Lanaguage)。

  在JDO之前的O/R Mapping產(chǎn)品中,也有一些產(chǎn)品使用OQL(有時(shí)候是其子集),比如Castor、Apache的Jakarta小組開(kāi)發(fā)的OJB等等。

  3.2.2 第三方協(xié)議

  軟件世界是一個(gè)多姿多彩的世界,總有那么一些好事之士不斷地冒出新奇的想法。還有一些開(kāi)發(fā)面向?qū)ο髷?shù)據(jù)庫(kù)的組織制定了自己的一套對(duì)象式數(shù)據(jù)庫(kù)查詢(xún)語(yǔ)言,自己的規(guī)范。

  不過(guò)這些規(guī)范相對(duì)來(lái)說(shuō),影響力小得多。比起ODMG來(lái),可以說(shuō)應(yīng)用范圍太小,更不用說(shuō)與SQL這樣廣泛應(yīng)用的標(biāo)準(zhǔn)進(jìn)行比較了。

  3.2.3 EJBQL

  Sun為了使Java應(yīng)用在企業(yè)級(jí)數(shù)據(jù)庫(kù)應(yīng)用中,不遺余力地推廣J2EE,在2001年的時(shí)候,推出了EJB2.0規(guī)范,其中包含了富有特色的面向CMP方式的EntityBean的查詢(xún)語(yǔ)言:EJBQL,功能類(lèi)似于ODMG OQL,只不過(guò)只能在EJB發(fā)布時(shí)靜態(tài)地存在于應(yīng)用描述符中,不能在程序中動(dòng)態(tài)地使用。這是EJBQL最大的弱點(diǎn),也許EJB3.0規(guī)范會(huì)將其動(dòng)態(tài)化,但到了那一天,世界多半已經(jīng)不是現(xiàn)在的樣子了。

  3.2.4 JDO

  JDO中有最近規(guī)定的一個(gè)對(duì)象式查詢(xún)語(yǔ)言規(guī)范,稱(chēng)作JDOQL,比起OQL來(lái),JDOQL將查詢(xún)語(yǔ)言中的很多元素與Java語(yǔ)言緊密地結(jié)合在一起,有的人覺(jué)得麻煩,有些人覺(jué)得規(guī)范,評(píng)論各不相同。從筆者個(gè)人的角度來(lái)看,這樣有利于沒(méi)寫(xiě)過(guò)數(shù)據(jù)庫(kù)應(yīng)用、沒(méi)用過(guò)SQL的新手很快地習(xí)慣JDOQL,但實(shí)際上,有多少人會(huì)在沒(méi)寫(xiě)過(guò)SQL,沒(méi)了解過(guò)關(guān)系數(shù)據(jù)庫(kù)的情況下去用JDO寫(xiě)數(shù)據(jù)庫(kù)應(yīng)用呢?畢竟市場(chǎng)說(shuō)明了一切。個(gè)人認(rèn)為,JDO中對(duì)數(shù)據(jù)庫(kù)對(duì)象的查詢(xún)多少顯得有些累贅,如果能更簡(jiǎn)化一點(diǎn),那將更吸引使用傳統(tǒng)SQL的開(kāi)發(fā)人員。

  4 JDO歷程與主要產(chǎn)品

  說(shuō)起JDO,其來(lái)由還有一段特殊的背景。Java語(yǔ)言在JDK1.1達(dá)到比較實(shí)用的目的后,企業(yè)級(jí)數(shù)據(jù)庫(kù)應(yīng)用也正是軟件開(kāi)發(fā)市場(chǎng)中的重要組成部分,Sun看到這一點(diǎn)后,也希望通過(guò)Java這個(gè)強(qiáng)大的武器在數(shù)據(jù)庫(kù)開(kāi)發(fā)市場(chǎng)攻占市場(chǎng)份額。JDK1.2推出后,Sun同時(shí)推出了面向企業(yè)應(yīng)用的EJB,對(duì)基于java的中間件服務(wù)器框架進(jìn)行了規(guī)范化定義,這就是J2EE。不過(guò)在JDK1.2時(shí),Java的速度還是不能與傳統(tǒng)的C/C++和Delphi這樣一些應(yīng)用開(kāi)發(fā)語(yǔ)言相比。為了防止業(yè)界對(duì)Java的激情因此而消退,Sun宣布將在JDK中加入強(qiáng)大的虛擬機(jī)技術(shù)HotSpot,其中包含更先進(jìn)的垃圾收集算法和更優(yōu)化的Java字節(jié)代碼再編譯技術(shù)(相當(dāng)于JIT,Java即時(shí)編譯技術(shù))。HotSpot引起了Java關(guān)注者的極大興趣,但Sun的HotSpot一拖再拖,最后包含在JDK1.3中出來(lái)時(shí),性能也沒(méi)有象預(yù)期的那樣好,比起C++編譯生成的代碼來(lái)還是有一段距離。

  這個(gè)時(shí)候,大家開(kāi)始對(duì)Sun心存懷疑,而Sun深知這一點(diǎn),于是將公眾的注意力趕緊轉(zhuǎn)移到EJB上,從EJB1.0到EJB1.1,再到EJB2.0,業(yè)界又開(kāi)始關(guān)注J2EE中間件技術(shù)上來(lái)。很快,開(kāi)發(fā)人同發(fā)現(xiàn)用EJB來(lái)編寫(xiě)數(shù)據(jù)庫(kù)應(yīng)用還是有很大的難度,雖然在分布式技術(shù)上EJB確實(shí)有很大的價(jià)值。在這個(gè)時(shí)候,Sun決定推出JDO技術(shù)作為輕量級(jí)的Java數(shù)據(jù)庫(kù)訪問(wèn)規(guī)范,而這一點(diǎn)也受到很多傳統(tǒng)O/R Mapping市場(chǎng)的歡迎。為了與傳統(tǒng)O/R Mapping有所區(qū)別,Sun一開(kāi)始就高姿態(tài)地將JDO定位成不只是面向關(guān)系數(shù)據(jù)庫(kù)的Java規(guī)范,而是針對(duì)所有的存儲(chǔ)技術(shù),包括面向?qū)ο髷?shù)據(jù)庫(kù)和其它類(lèi)型的存儲(chǔ)體系(如文件),就象EJB EntityBean一樣,雖然。就筆者的角度,這個(gè)做法使第一版的JDO拋棄了很多傳統(tǒng)O/R Mapping提供的面向關(guān)系數(shù)據(jù)庫(kù)的功能,可以算是一個(gè)失策。

  4.1 規(guī)范提出、JSR

  JDO最早是由Sun召集眾多的O/R Mapping開(kāi)發(fā)團(tuán)隊(duì)集中起來(lái)共同提出的,首先是通過(guò)會(huì)議確定了JDO需要包括的內(nèi)容,然后正式提出一個(gè)Java規(guī)范請(qǐng)求(JSR-12),正式開(kāi)始了JDO規(guī)范的制定。下面是主要的進(jìn)展里程碑。

  JSR #000012 approved in July 1999

  1999-8組建的專(zhuān)家小組:包括Sun、Apple、BEA、IBM、Oracle、SAP、WebGain等

  2000-5 完成公開(kāi)評(píng)論草案
  2000-6 在JavaOne上引入
  2001-3 最終草案0.93
  2001-5 最終草案0.96公布
  2001-6 在JavaOne上啟動(dòng)
  2001-11 最終草案0.98
  2002-4 1.0版正式公布
  2002-8 1.0.1修正版
  2003-8 2.0規(guī)范啟動(dòng)
  …

  4.2 Oracle與JDO

  作為JDO專(zhuān)家組的重要成員,同時(shí)作為最大的關(guān)系數(shù)據(jù)庫(kù)廠商的Oracle地位顯然非同一般。在JDO規(guī)范中,Oracle也可說(shuō)是立下汗馬功勞,很多API的形成,Oracle都提供了很重要的參考意見(jiàn),最終的投票O(jiān)racle也是毫不猶豫。

  可是,世間的事總是變化莫測(cè)的,就在JDO1.0快出臺(tái)之時(shí),Oracle收購(gòu)了TopLink,這一點(diǎn)使Oracle的身份變得特殊而復(fù)雜。TopLink是一個(gè)商業(yè)產(chǎn)品,是以商業(yè)利益為目標(biāo)的,而Oracle也是追求利益最大化的典型商家,這一點(diǎn)與JDO的開(kāi)放精神背道而馳。因此,我們看到后期Oracle對(duì)JDO的不積極態(tài)度,甚至在前一陣的JavaOne大會(huì)上有人從Oracle的角度非正式地攻擊JDO。

  4.3 主要產(chǎn)品以及各自特點(diǎn)

  在JDO規(guī)范制定的同時(shí),出現(xiàn)了幾個(gè)主要的JDO產(chǎn)品,有美國(guó)的基于對(duì)象數(shù)據(jù)庫(kù)的FastObjects j1、法國(guó)的支持Versant對(duì)象數(shù)據(jù)庫(kù)、文件數(shù)據(jù)庫(kù)、主流RDBMS的LiDO、南非的JDOGenie、德國(guó)的JRelay等等,這些都是很不錯(cuò)的JDO產(chǎn)品。下面列舉一下我對(duì)主要的幾個(gè)產(chǎn)品的印象:

  LiDO(法國(guó)LibeLis公司)

  我對(duì)JDO的認(rèn)識(shí)主要是通過(guò)LiDO這個(gè)產(chǎn)品,它在2002年3月的一份圖文并茂的教程中簡(jiǎn)要解說(shuō)了JDO的使用和優(yōu)點(diǎn)。這個(gè)教程可以在這里下載:http://www.objectweb.org/conference/JDO.pdf。LiDO的特色是大而全,支持文件型數(shù)據(jù)庫(kù)、RDBMS、ODBMS,甚至是XML數(shù)據(jù)庫(kù)。不過(guò)配置較麻煩。最新版本是2.0RC。

  KodoJDO(美國(guó)SolarMetrics公司)

  Kodo是JDO的中流砥柱之一,在JDO1.0還未最后通過(guò)的時(shí)候,它就是一個(gè)比較成熟的產(chǎn)品了,其特點(diǎn)是注重性能和穩(wěn)定性,目前最新版本是2.5.0,是客戶(hù)最多的產(chǎn)品。

  JDOGenie(南非HemSphere公司)

  這是目前我最推薦的產(chǎn)品,最新版本是1.4.7,性能也不錯(cuò),穩(wěn)定性還有待驗(yàn)證,但它有一個(gè)最大的特點(diǎn):集成性好,最易學(xué),其公司的CTO David Tinker也是一個(gè)善解人意的年輕人,采納了很多網(wǎng)友的意見(jiàn)對(duì)產(chǎn)品進(jìn)行改進(jìn),主要是在配置上非常方便,有一個(gè)專(zhuān)門(mén)的圖形界面工具,可以進(jìn)行配置、數(shù)據(jù)庫(kù)生成、對(duì)象查詢(xún)等等很實(shí)用的功能。

  JRelay(德國(guó)ObjectIndustries公司)

  這也是一個(gè)出現(xiàn)得比較早的產(chǎn)品,也有一個(gè)GUI工具用于配置,曾幾何時(shí),這個(gè)工具還是相對(duì)很方便的,但一年多過(guò)去了,好象沒(méi)什么進(jìn)展,最新版本是2.0,我試過(guò)一段時(shí)間,后來(lái)就沒(méi)有再跟進(jìn)了。

  FrontierSuite for JDO (美國(guó)ObjectFrontier)

  這個(gè)產(chǎn)品與JRelay、Kodo一起,可算是早期的JDO三個(gè)主要產(chǎn)品,它支持正向開(kāi)發(fā)和反向開(kāi)發(fā)(Reverse Engineer)。它的特色是反向工程(從表結(jié)構(gòu)生成數(shù)據(jù)類(lèi))比較方便,與UML的結(jié)合也很強(qiáng),不過(guò)真正運(yùn)行起來(lái)的時(shí)候,配置復(fù)雜。

  TJDO(一群跨國(guó)界的有志之士)

  這是一個(gè)在Sun提供的參考產(chǎn)品(Reference Implementation)的基礎(chǔ)上加入一些擴(kuò)展功能而形成的一個(gè)免費(fèi)產(chǎn)品,目前最新版本是2.0beta3,不過(guò)進(jìn)展也緩慢,這個(gè)版本已經(jīng)出現(xiàn)好幾個(gè)月了沒(méi)有進(jìn)一步的更新。

  5 目前狀況與未來(lái)展望

  從2002年4月JDO1.0規(guī)范正式公布以來(lái),各個(gè)產(chǎn)品層出不窮,從商業(yè)到免費(fèi)的層次,都有不錯(cuò)的產(chǎn)品推出。象Kodo、Lido、JDOGenie等產(chǎn)品都已經(jīng)比較成熟,可以考慮投入開(kāi)發(fā)使用。在2002年8月,JDO又推出1.0.1修正版,修正了1.0版規(guī)范中的一些文字錯(cuò)誤,以及輕微地改進(jìn)了部分異常定義,不過(guò)改動(dòng)都不大。從現(xiàn)在的情形來(lái)看,除了Kodo有一些大學(xué)的項(xiàng)目用到外,好象還沒(méi)看到多少使用JDO作開(kāi)發(fā)的應(yīng)用。

  JDO畢竟是一個(gè)新技術(shù),從概念上到實(shí)際應(yīng)用上對(duì)其掌握的用戶(hù)還不多,而這些產(chǎn)品在配置、使用上的方便性易用性還有待大幅度改進(jìn),因此,真正用JDO來(lái)開(kāi)發(fā)項(xiàng)目的用戶(hù)還廖廖無(wú)幾,至少我還不知道有哪些項(xiàng)目使用了JDO。我自己也嘗試使用JDO來(lái)開(kāi)發(fā)項(xiàng)目,但由于一些JDO1.0版本中還不夠完善的一些硬傷(比如不支持關(guān)系數(shù)據(jù)庫(kù)統(tǒng)計(jì)功能),使我對(duì)JDO仍處于觀望階段。

  在八月中旬進(jìn)行的JDO2.0規(guī)劃會(huì)議中,來(lái)自各國(guó)的各個(gè)JDO產(chǎn)品廠商、JDO技術(shù)咨詢(xún)公司、JDO研究機(jī)構(gòu)的代表匯聚一堂,將各自收集到的用戶(hù)對(duì)JDO2.0的需求總結(jié)起來(lái),提出一個(gè)個(gè)的新的議題,并且確定了每個(gè)議題的JDO規(guī)范撰寫(xiě)負(fù)責(zé)人,比如高級(jí)fetchGroup特性由目前實(shí)現(xiàn)得最好的JDOGenie的CTO David Tinker負(fù)責(zé),關(guān)于managed-relationship特性由Kodo的產(chǎn)品總監(jiān)負(fù)責(zé),用戶(hù)要求最多的JDO對(duì)象與PersistenceManager的脫鉤/重掛鉤特性由Sun的Craig Russell親自操刀,等等。

  最具有吸引力的JDO2.0議題,筆者個(gè)人認(rèn)為是專(zhuān)門(mén)為關(guān)系數(shù)據(jù)庫(kù)設(shè)立的子規(guī)范JDO/R,這也是我一直以來(lái)最關(guān)心的,這將使目前JDBC的開(kāi)發(fā)將可以被JDO完全取代,并且保證開(kāi)發(fā)過(guò)程保持面向?qū)ο蟮奶厣_有一些將一個(gè)類(lèi)映射到多個(gè)表之類(lèi)的特性也在規(guī)范化的列表上,這將有利于DBA在不影響應(yīng)用開(kāi)發(fā)的前提下根據(jù)需要更改數(shù)據(jù)表結(jié)構(gòu),實(shí)現(xiàn)更好的性能。類(lèi)似的新特性還有很多,粗略地看,這些都規(guī)范化起來(lái)后,真不知道各個(gè)廠商還能做什么樣的擴(kuò)展特性,也許以后廠商之間拼的只能是技術(shù)支持服務(wù)和產(chǎn)品性能了,當(dāng)然,最后還有價(jià)格的競(jìng)爭(zhēng)。

  說(shuō)了這么多,我想大家關(guān)心的還是JDO2.0到底什么時(shí)候能出來(lái),我們什么時(shí)候可以用上它,什么時(shí)候有中文版產(chǎn)品,價(jià)格到底如何。這些問(wèn)題目前筆者還無(wú)法一一回答,只能根據(jù)筆者所掌握的信息初步解釋一下。據(jù)前幾天的JDO2.0啟動(dòng)大會(huì)上David Jordan的預(yù)期,JDO2.0正式版將在18個(gè)月后正式完成。那正式完成后廠商什么時(shí)候才能提供符合規(guī)范的產(chǎn)品呢?這個(gè)問(wèn)題不用擔(dān)心,因?yàn)橐?guī)范在制定的過(guò)程中會(huì)不斷地公布公眾預(yù)覽版(Public Review),這樣,廠商可以先實(shí)現(xiàn)其中的功能,等規(guī)范正式完成后,也不會(huì)有太大的變化,廠商也不會(huì)需要太多時(shí)間來(lái)跟進(jìn)最終規(guī)范。所以,我估計(jì)一年之后,我們就可以在JDO2.0上進(jìn)行開(kāi)發(fā)了。至于價(jià)格如何,1.0規(guī)范的產(chǎn)品初步印象是每個(gè)開(kāi)發(fā)人員需要一個(gè)License,一個(gè)License大概2000美元。如果JDO2.0產(chǎn)品的價(jià)格還保持這么貴的話(huà)(至少對(duì)中國(guó)用戶(hù)來(lái)說(shuō)),我們也還有很多免費(fèi)(如JPOX,TJDO)或半免費(fèi)(如JCredo)產(chǎn)品可以選擇。最后一個(gè)關(guān)于中文版的問(wèn)題,有待于廠商對(duì)中國(guó)市場(chǎng)的考察,或者看看是否有國(guó)內(nèi)的JDO產(chǎn)品了。不過(guò),在JDO2.0規(guī)范制定的同時(shí),我們可以先集眾人之力將其普及,使廣大的使用Java語(yǔ)言進(jìn)行數(shù)據(jù)庫(kù)開(kāi)發(fā)的開(kāi)發(fā)人員都來(lái)認(rèn)識(shí)JDO,了解JDO,甚至將其用到項(xiàng)目開(kāi)發(fā)之中。

  也許,JDO的目標(biāo)已經(jīng)吸引了Java世界以外的人,微軟發(fā)現(xiàn)了這一點(diǎn),也立即計(jì)劃在.NET體系中加入一個(gè)仿照J(rèn)DO的中間件,具體是采用ObjectStore的產(chǎn)品,ObjectStore是一個(gè)同時(shí)做JDO和.NET-DO(姑且使用這個(gè)名稱(chēng))的公司。

  在這里,筆者可以大膽地預(yù)測(cè),在未來(lái)的一兩年內(nèi),JDO將在Java世界大放光彩!

  5.1 一點(diǎn)花絮

  在2003年6月舉行的JavaOne大會(huì)上,JDO備受矚目,很多開(kāi)發(fā)者或開(kāi)發(fā)組織對(duì)其產(chǎn)生了極大的興趣,在各大網(wǎng)站媒體上也頻頻曝光,大多對(duì)其評(píng)價(jià)不錯(cuò),當(dāng)然,也有一些負(fù)面的評(píng)價(jià)。

  不過(guò),網(wǎng)站上的報(bào)道也不可盡信,比如服務(wù)器領(lǐng)域的權(quán)威網(wǎng)站TheServerSide.com上介紹JavaOne大會(huì)第二天關(guān)于JDO的一次會(huì)議的報(bào)道就有誤導(dǎo)之嫌,從報(bào)道的內(nèi)容來(lái)看,好象會(huì)議用來(lái)答疑與交流的的最后五分鐘全被一個(gè)好事者占據(jù),這個(gè)人拼命鼓吹Oracle的TopLink解決方案和一些易用性的改進(jìn),從而攻擊JDO的市場(chǎng)前景。后來(lái),我就這一信息與參加會(huì)議的JDO專(zhuān)家組的David Jordan交流時(shí),他糾正了我的錯(cuò)誤理解,實(shí)際情形是:那個(gè)好事者是一個(gè)積極的JDO擁護(hù)者,他花了超過(guò)五分鐘時(shí)間向大家揭露Oracle的TopLink改進(jìn)實(shí)際上也是抄襲JDO的概念而進(jìn)行的一些API改動(dòng)!不過(guò)有一點(diǎn)是相同的,這個(gè)好事者占據(jù)了大家的提問(wèn)時(shí)間,使這次會(huì)議在意猶未盡中結(jié)束。




主站蜘蛛池模板: 伊人影院综合 | 日本韩国中文字幕 | 性色午夜视频免费男人的天堂 | 亚洲欧美一区二区三区久久 | 日本亚州视频在线八a | 日本不卡视频免费 | 四虎4hu永久免费国产精品 | 亚洲三级一区 | 亚洲专区路线一路线二 | 日本mv精品中文字幕 | 天天躁日日躁狠狠躁欧美日韩 | 午夜5060网 | 亚洲精品在看在线观看 | 视频在线一区二区 | 亚洲天堂免费在线视频 | 天天干夜夜躁 | 欧美透逼视频 | 日韩理论片在线观看电视 | 日本不卡高清视频 | 日本亚洲高清 | 日韩毛片在线免费观看 | 天天躁夜夜躁狠狠躁2024 | 欧美在线 | 亚洲 | 色香天天 | 性刺激欧美三级在线观看 | 午夜片在线| 特一级黄色 | 伊人色在线 | 日韩欧美伊人久久大香线蕉 | 亚洲人成网男女大片在线播放 | 视频二区在线观看 | 伊人网在线视频观看 | 日韩精品无码一区二区三区 | 天堂资源中文官网 | 色综合天天综合网国产成人网 | 在线你懂得 | 午夜激情在线观看 | 亚洲日本欧美 | 日日爱夜夜操 | 亚洲三级欧美 | 日本三级午夜 |