在企業(yè)級(jí)的Java應(yīng)用中,訪問(wèn)數(shù)據(jù)庫(kù)是一個(gè)必備的環(huán)節(jié)。數(shù)據(jù)庫(kù)作為數(shù)據(jù)資源的集散地,往往位于企業(yè)級(jí)軟件體系的后方,供前方的應(yīng)用程序訪問(wèn)。在Java技術(shù)的體系中,應(yīng)用程序是通過(guò)JDBC(Java Database Connectivity)接口來(lái)訪問(wèn)數(shù)據(jù)庫(kù)的,JDBC支持"建立連接、SQL語(yǔ)句查詢、處理結(jié)果"等基本功能。在應(yīng)用JDBC接口訪問(wèn)數(shù)據(jù)庫(kù)的過(guò)程中,只要根據(jù)規(guī)范來(lái)操作,這些功能的實(shí)現(xiàn)不會(huì)出差錯(cuò)。但是,有些時(shí)候進(jìn)行數(shù)據(jù)查詢的效率著實(shí)讓開(kāi)發(fā)人員懊惱不已,明明根據(jù)規(guī)范編寫(xiě)的程序,卻得不到預(yù)期的運(yùn)行效果,造成了整個(gè)軟件的執(zhí)行效率不高。
起初,我們把問(wèn)題歸結(jié)于Java字節(jié)碼加載和執(zhí)行速度的緩慢,緊接著硬件的功能普遍得到了增強(qiáng),證明這樣的想法些許是錯(cuò)誤的,還沒(méi)有抓到真正的根本原因。本文將逐步解剖JDBC訪問(wèn)數(shù)據(jù)庫(kù)的機(jī)制,深層分析造成這種速度瓶頸問(wèn)題的原因,并提出在現(xiàn)有的Java技術(shù)框架下解決這個(gè)速度瓶頸問(wèn)題的思路和方法。
JDBC訪問(wèn)數(shù)據(jù)庫(kù)的機(jī)制
????????????????
圖1????????????????????????????????????????????????圖2
圖1和圖2描述了Java應(yīng)用程序通過(guò)JDBC接口訪問(wèn)數(shù)據(jù)庫(kù)的4種驅(qū)動(dòng)模式,也就是底層實(shí)現(xiàn)JDBC接口的模式。對(duì)于這些模式,我們逐一介紹:
模式4:圖1左邊的分支稱為模式4,它一般是數(shù)據(jù)庫(kù)廠商才能實(shí)現(xiàn)的純Java的基于本地協(xié)議的驅(qū)動(dòng),直接調(diào)用DBMS(數(shù)據(jù)庫(kù)管理系統(tǒng))使用的網(wǎng)絡(luò)協(xié)議,對(duì)于企業(yè)內(nèi)部互聯(lián)網(wǎng)來(lái)說(shuō),是一個(gè)實(shí)用的解決方案。
模式3:圖1右邊的分支稱為模式3,它同樣是一個(gè)純Java驅(qū)動(dòng),不同于模式4的是基于網(wǎng)絡(luò)協(xié)議。它的機(jī)制是將JDBC調(diào)用轉(zhuǎn)換為中間網(wǎng)絡(luò)協(xié)議,然后轉(zhuǎn)換為DBMS協(xié)議。中間網(wǎng)絡(luò)協(xié)議層起到一個(gè)讀取數(shù)據(jù)庫(kù)的中間件的作用,能夠連接許多類型的數(shù)據(jù)庫(kù),因而是最靈活的JDBC模式。這種模式的產(chǎn)品比較適用于企業(yè)內(nèi)部互聯(lián)網(wǎng),如若支持國(guó)際互聯(lián)網(wǎng),還需添加對(duì)安全、穿過(guò)防火墻訪問(wèn)等的支持。
模式1:圖2左邊的分支稱為模式1,即通常由Sun公司提供的JDBC-ODBC橋接器。它提供了經(jīng)由一種或多種ODBC驅(qū)動(dòng)進(jìn)行訪問(wèn)的JDBC接口,而ODBC驅(qū)動(dòng),在很多情況下也即數(shù)據(jù)庫(kù)的客戶端,必須加載到客戶機(jī)。因而,它適用于下載和自動(dòng)安裝Java程序不重要、實(shí)驗(yàn)用途或者沒(méi)有其它JDBC驅(qū)動(dòng)可用的情況下。
模式2:圖2右邊的分支成為模式2,類似于JDBC-ODBC橋接器,需要加載到客戶機(jī),卻是一個(gè)部分用Java實(shí)現(xiàn)的驅(qū)動(dòng)接口。它將JDBC調(diào)用轉(zhuǎn)換為對(duì)數(shù)據(jù)庫(kù)(Oracle、Sybase、Informix、DB2等)客戶端接口的調(diào)用。
不同模式的JDBC接口的選擇
以上闡述的JDBC接口的模式不同,讓我們可以把JDBC接口按照實(shí)現(xiàn)的模式分為四類。有些同仁可能有這樣的體會(huì),選擇不同的JDBC接口會(huì)有不同的訪問(wèn)速度,為何會(huì)出現(xiàn)這樣的情況?這個(gè)問(wèn)題的答案是,不同的應(yīng)用需要不同模式的JDBC接口,因而我們?cè)诿鎸?duì)一個(gè)應(yīng)用時(shí),要慎重選擇JDBC接口。
通常的DBMS都支持微軟提出的ODBC規(guī)范,因而模式1可當(dāng)作您在設(shè)計(jì)和實(shí)現(xiàn)軟件時(shí)的選擇,它易于配置的特性能夠讓你把選擇JDBC等煩惱的問(wèn)題暫且拋在一邊,讓自己的Java程序能夠及早地正常工作起來(lái)。
一般說(shuō)來(lái),商業(yè)DBMS的提供者往往會(huì)為自己的數(shù)據(jù)庫(kù)提供一個(gè)JDBC接口,應(yīng)用的是模式4。這種模式的優(yōu)勢(shì)在于和數(shù)據(jù)庫(kù)本身結(jié)合比較緊密,而且是純Java的實(shí)現(xiàn),在企業(yè)級(jí)的軟件應(yīng)用中,應(yīng)該是首選。例如,對(duì)于Oracle數(shù)據(jù)庫(kù)來(lái)說(shuō),有Oracle、SilverStream、DataDirect等公司提供這種類型的驅(qū)動(dòng),其性能往往被評(píng)價(jià)為最高效的、最可靠的驅(qū)動(dòng)程序。但偶爾也有比較麻煩的情況,例如微軟就不會(huì)提供MS SQL的JDBC接口,這時(shí)就需要到Sun的網(wǎng)站(http://industry.java.sun.com/products/jdbc/drivers)查找相關(guān)的模式4驅(qū)動(dòng),上面提到的DataDirect公司(http://www.datadirect-technologies.com/jdbc/jdbc.asp)就提供了支持MS SQL的模式4驅(qū)動(dòng),只是你需要支付750$購(gòu)買這個(gè)JDBC驅(qū)動(dòng)。
同樣是純Java實(shí)現(xiàn)的模式3,與模式4相比,優(yōu)勢(shì)在于對(duì)多種數(shù)據(jù)庫(kù)的支持,體現(xiàn)了其靈活性。在大型的企業(yè)級(jí)的軟件應(yīng)用中,后臺(tái)數(shù)據(jù)庫(kù)往往不是一個(gè),而且是由不同的廠商支持的。不過(guò),模式3的JDBC驅(qū)動(dòng)往往提供許多企業(yè)級(jí)的特征,例如SSL安全、支持分布式事務(wù)處理和集中管理等,因而會(huì)對(duì)你特殊的用途有很大的幫助。是否選用,還在于你對(duì)擴(kuò)展應(yīng)用是否有需求以及對(duì)多DBMS的支持。
談到這兒,我對(duì)模式3和模式4作一個(gè)總結(jié):兩者都是純Java實(shí)現(xiàn)的驅(qū)動(dòng),因而不需要數(shù)據(jù)庫(kù)廠商提供附加的軟件,就可以運(yùn)行在任何標(biāo)準(zhǔn)的Java平臺(tái),性能上比較高效、可靠。
了解上述3種JDBC的實(shí)現(xiàn)模式之后,模式2就更容易闡釋了,你可以理解它為前三者利弊平衡的妥協(xié)產(chǎn)物:
1. 借鑒模式1利用客戶機(jī)本地代碼庫(kù),加速數(shù)據(jù)訪問(wèn)的執(zhí)行,但卻摒除ODBC標(biāo)準(zhǔn),而是支持廠商自己指定的性能擴(kuò)展
2. 借鑒模式3利用多層結(jié)構(gòu),上層用Java實(shí)現(xiàn),利于跨平臺(tái)應(yīng)用和支持多數(shù)據(jù)庫(kù),但下層卻改為本地代碼,加速執(zhí)行速度
3. 借鑒模式4和數(shù)據(jù)庫(kù)結(jié)合緊密的優(yōu)點(diǎn),部分用Java實(shí)現(xiàn),更是對(duì)數(shù)據(jù)庫(kù)性能有很大的擴(kuò)展
這種開(kāi)放和高性能的特征得到了業(yè)界的肯定,因而被主要的數(shù)據(jù)庫(kù)廠商強(qiáng)烈推薦。盡管它需要你下載本地代碼庫(kù)到客戶機(jī),但相對(duì)于你訪問(wèn)數(shù)據(jù)庫(kù)速度的提高,這些應(yīng)該只是舉手之勞了。下面對(duì)4種實(shí)現(xiàn)JDBC的模式選擇,歸納一下選擇的順序(當(dāng)然是指你有選擇余地的時(shí)候,不存在的話向后推延):
編號(hào) | 選擇過(guò)程分析 | 選擇順序 |
1 | 實(shí)驗(yàn)性環(huán)境下,盡可能選擇易于配置的驅(qū)動(dòng),利于Java程序的開(kāi)發(fā),后期可在對(duì)應(yīng)用環(huán)境進(jìn)行判斷后,再對(duì)JDBC模式進(jìn)行選擇 | 1>2>3>4 |
2 | 小型企業(yè)級(jí)環(huán)境下,不需要對(duì)多數(shù)據(jù)庫(kù)的支持,因而模式2和3的有些優(yōu)點(diǎn)并不能體現(xiàn)出來(lái),強(qiáng)烈推薦你選擇模式4的JDBC驅(qū)動(dòng) | 4>2=3>1 |
3 | 大型企業(yè)級(jí)環(huán)境下,需要對(duì)多數(shù)據(jù)庫(kù)的支持,模式2和3各有千秋,但是更多情況下是你會(huì)選擇速度較快的模式2 | 2>3>4>1 |
對(duì)于不同廠商提供的但應(yīng)用相同模式的JDBC接口,理論上比較不出效率的高低,你只有通過(guò)一定的工具,例如Benchmark等,對(duì)它們進(jìn)行比較才能更有利于你的選擇。因?yàn)闀簳r(shí)不存在第三方提供的數(shù)據(jù)比較結(jié)果,所以這些問(wèn)題需要你對(duì)上述內(nèi)容有了透徹理解之后自行解決。
Java程序中SQL語(yǔ)句格式的優(yōu)化
這個(gè)時(shí)候,你也許還在為找不到合適的JDBC驅(qū)動(dòng)而一籌莫展,也許為自己在凌晨3點(diǎn)下載的JDBC驅(qū)動(dòng)通過(guò)了測(cè)試而欣喜若狂,但是并不說(shuō)明你對(duì)程序的優(yōu)化工作已經(jīng)無(wú)關(guān)緊要了。切記,對(duì)整個(gè)軟件系統(tǒng)的優(yōu)化,包括每個(gè)環(huán)節(jié)的優(yōu)化,要不有可能你會(huì)前功盡棄。我在這兒不和大家討論Java程序的算法,而是簡(jiǎn)單闡述一下選擇SQL語(yǔ)句格式的必要和如何選擇對(duì)自己有利的SQL語(yǔ)句格式。看下面兩段程序片斷:
Code Fragment 1:
String updateString = "UPDATE COFFEES SET SALES = 75 " + "WHERE COF_NAME LIKE 'Colombian'";
stmt.executeUpdate(updateString);
Code Fragment 2:
PreparedStatement updateSales = con.prepareStatement("UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ? ");
updateSales.setInt(1, 75);
updateSales.setString(2, "Colombian");
updateSales.executeUpdate();
片斷2和片斷1的區(qū)別在于,后者使用了PreparedStatement對(duì)象,而前者是普通的Statement對(duì)象。PreparedStatement對(duì)象不僅包含了SQL語(yǔ)句,而且大多數(shù)情況下這個(gè)語(yǔ)句已經(jīng)被預(yù)編譯過(guò),因而當(dāng)其執(zhí)行時(shí),只需DBMS運(yùn)行SQL語(yǔ)句,而不必先編譯。當(dāng)你需要執(zhí)行Statement對(duì)象多次的時(shí)候,用PreparedStatement對(duì)象將會(huì)大大降低運(yùn)行時(shí)間,當(dāng)然也加快了訪問(wèn)數(shù)據(jù)庫(kù)的速度。
這種轉(zhuǎn)換也給你帶來(lái)很大的便利,不必重復(fù)SQL語(yǔ)句的句法,而只需更改其中變量的值,便可重新執(zhí)行SQL語(yǔ)句。選擇PreparedStatement對(duì)象與否,在于相同句法的SQL語(yǔ)句是否執(zhí)行了多次,而且兩次之間的差別僅僅是變量的不同。如果僅僅執(zhí)行了一次的話,它應(yīng)該和普通的Statement對(duì)象毫無(wú)差異,體現(xiàn)不出它預(yù)編譯的優(yōu)越性。
軟件模型中對(duì)數(shù)據(jù)庫(kù)訪問(wèn)的設(shè)計(jì)模式的優(yōu)化
在我閱讀J2EE藍(lán)圖和JDO草案的過(guò)程中,我發(fā)現(xiàn)了訪問(wèn)模式對(duì)數(shù)據(jù)庫(kù)訪問(wèn)的影響,因而想在本文中闡述如何針對(duì)自己的軟件需求選擇合適的軟件模式。
J2EE藍(lán)圖的設(shè)計(jì)者在Java Pet Store示例應(yīng)用中使用了MVC(Model-View-Controller)體系,給許多J2EE設(shè)計(jì)模式提供了背景。我要談及的三種設(shè)計(jì)模式是:Data Access Object、Fast Lane Reader、Page-by-Page Iterator,它們?yōu)榧涌鞌?shù)據(jù)存取速度提供了一些可以在系統(tǒng)設(shè)計(jì)階段值得我們借鑒的想法。
Data Access Object
將商業(yè)邏輯從數(shù)據(jù)存取邏輯中分離出來(lái),把存取的資源改編,從而使資源可以容易和獨(dú)立地轉(zhuǎn)變。
依賴于底層數(shù)據(jù)資源的特殊要素(例如數(shù)據(jù)庫(kù)的供應(yīng)商)的商業(yè)組件,常將商業(yè)邏輯和數(shù)據(jù)存取邏輯配合起來(lái),只能使用特殊類型的資源,而使用不同類型的資源時(shí),復(fù)用將會(huì)非常困難,因此,只能服務(wù)于有限的市場(chǎng)領(lǐng)域。DAO(Data Access Object)即是將數(shù)據(jù)存取邏輯從EJB中抽去出來(lái)抽象為一個(gè)獨(dú)立的接口,EJB根據(jù)接口的操作執(zhí)行商業(yè)邏輯,而接口針對(duì)使用的數(shù)據(jù)資源實(shí)現(xiàn)為DAO對(duì)象。
在Java Pet Shop這個(gè)例子中,OrderEJB組件通過(guò)關(guān)聯(lián)的OrderDAO類訪問(wèn)數(shù)據(jù)庫(kù),自身則關(guān)注于商業(yè)邏輯的實(shí)現(xiàn)。在調(diào)度階段,將配置某一類(OrderDAOCS、OrderDAOOracle或OrderDAOSybase)為OrderDAO的實(shí)現(xiàn),而OrderEJB無(wú)須任何更改。圖3更能幫助你明白其中的道理:
圖3 Data Access Object的設(shè)計(jì)模式
此舉增加了數(shù)據(jù)存取的彈性、資源的獨(dú)立性和擴(kuò)展性,但復(fù)雜度有相應(yīng)的提高,其它附帶的問(wèn)題我們不在這兒討論。
Fast Lane Reader
拋棄EJB,加速只讀數(shù)據(jù)的存取。
有些時(shí)候,高效地存取數(shù)據(jù)比獲得最新的數(shù)據(jù)更重要。在Java Pet Store中,當(dāng)一個(gè)用戶瀏覽商店的目錄時(shí),屏幕與數(shù)據(jù)庫(kù)內(nèi)容吻合不是至關(guān)緊要的,相反,迅速顯示和重新獲得非常重要。FLR模式可以加速?gòu)馁Y源中重新獲得大型的列數(shù)據(jù)項(xiàng)的速度,它不用EJB,而是更直接地通過(guò)DAO來(lái)存取數(shù)據(jù),從而消除EJB的經(jīng)常開(kāi)支(例如遠(yuǎn)程方法調(diào)用、事務(wù)管理和數(shù)據(jù)序列化等)。
在Java Pet Store這個(gè)例子中,當(dāng)一個(gè)用戶瀏覽目錄時(shí),通過(guò)CatalogDAO(而不是CatalogEJB)從數(shù)據(jù)庫(kù)加載數(shù)據(jù)項(xiàng),而CatalogDAO是一個(gè)Fast Lane Reader的實(shí)例,使得讀訪問(wèn)變得迅速,如圖4:
圖4 Fast Lane Reader設(shè)計(jì)模式
與DAO模式不同的是,F(xiàn)LR是一個(gè)優(yōu)化的模式,但不是要替代原有的訪問(wèn)機(jī)制,而是作為補(bǔ)充使其完備。當(dāng)你頻繁地只讀大型的列數(shù)據(jù)和不必存取最新的數(shù)據(jù)時(shí),使用FLR將是非常合適的。
Page-by-Page Iterator
為了高效地存取大型的遠(yuǎn)程數(shù)據(jù)列,一下子通過(guò)重新獲得其元素為一個(gè)子列的Value Object(提高遠(yuǎn)程傳輸效率的設(shè)計(jì)模式,這兒不詳盡描述)。
分布式數(shù)據(jù)庫(kù)的應(yīng)用經(jīng)常需要用戶考慮一長(zhǎng)列數(shù)據(jù)項(xiàng),例如一個(gè)目錄或一個(gè)搜索結(jié)果的集合。在這些情況下,立刻提供全列的數(shù)據(jù)經(jīng)常不必要(用戶并不是對(duì)所有的數(shù)據(jù)項(xiàng)感興趣)或不可能(沒(méi)有足夠的空間)。此外,當(dāng)重新獲得一列數(shù)據(jù)項(xiàng)時(shí),使用Entity Bean的代價(jià)將非常高昂,一個(gè)開(kāi)銷來(lái)自于使用遠(yuǎn)程探測(cè)器來(lái)收集Requested Bean,另外,更大的開(kāi)銷來(lái)自對(duì)每個(gè)Bean產(chǎn)生遠(yuǎn)程調(diào)用以從用戶獲得數(shù)據(jù)。
通過(guò)Iterator,客戶機(jī)對(duì)象能一下子重新獲得一個(gè)子列或者頁(yè)的Value Object,每一頁(yè)都剛好滿足客戶機(jī)的需求,因此,程序使用較少的資源滿足了客戶機(jī)的立刻需求。
在Java Pet Store這個(gè)例子中,JSP頁(yè)面product.jsp任何時(shí)候只顯示一個(gè)數(shù)據(jù)列的一部分,從ProductItemListTag(Page-by-Page Iterator)重新獲得數(shù)據(jù)項(xiàng),當(dāng)客戶機(jī)希望看到列中的別的數(shù)據(jù)項(xiàng),product.jsp再次調(diào)用Iterator重新獲得這些數(shù)據(jù)項(xiàng),流程見(jiàn)圖5:
圖5 Page-by-Page Iterator設(shè)計(jì)模式
以上設(shè)計(jì)模式的應(yīng)用向我們表明,在某些特殊情況下,優(yōu)化對(duì)數(shù)據(jù)庫(kù)的訪問(wèn)模型,既可滿足用戶的需求又可提高訪問(wèn)數(shù)據(jù)庫(kù)的效率。這給我們一個(gè)思路,就是:在你的硬件環(huán)境可能會(huì)產(chǎn)生瓶頸的情況下,可以通過(guò)對(duì)軟件模型的優(yōu)化來(lái)達(dá)到滿足需求的目的。上述三種設(shè)計(jì)模式的應(yīng)用情形為:
Data Access Object | 需要將商業(yè)邏輯和數(shù)據(jù)存取邏輯分離; 在調(diào)度的時(shí)刻,需要支持選擇數(shù)據(jù)源的類型; 使用的數(shù)據(jù)源的類型的變化,對(duì)商業(yè)對(duì)象或其它客戶端完成數(shù)據(jù)存取沒(méi)有影響。 |
Fast Lane Reader | 面對(duì)大型的列數(shù)據(jù),需要經(jīng)常的只讀訪問(wèn); 訪問(wèn)最新的數(shù)據(jù)并不是至關(guān)緊要的事情。 |
Page-by-Page Iterator | 存取大型的服務(wù)器端數(shù)據(jù)列; 任何時(shí)刻,用戶只對(duì)列的一部分內(nèi)容感興趣; 整個(gè)列的數(shù)據(jù)不適合在客戶端顯示; 整個(gè)列的數(shù)據(jù)不適合在存儲(chǔ)器中保存; 傳輸整個(gè)列的數(shù)據(jù)將耗費(fèi)太多的時(shí)間。 |
在顯示商品目錄的時(shí)候,我們選擇了DAO和FLR的結(jié)合,因?yàn)樗鼈儍烧叩臈l件都得到了滿足(需要分離商業(yè)邏輯和數(shù)據(jù)存取邏輯,經(jīng)常的只讀訪問(wèn)和對(duì)即時(shí)性不敏感),此時(shí)應(yīng)用將會(huì)大大發(fā)揮它們的優(yōu)點(diǎn)。而在進(jìn)行內(nèi)容檢索的時(shí)候,我們會(huì)選擇PPI,因?yàn)橐苍S檢索出了上千條的記錄,但是用戶沒(méi)有興趣立即閱讀全部?jī)?nèi)容,而是一次十條地閱讀,或者他在閱讀完前十條記錄后發(fā)覺(jué)自己的目的已經(jīng)達(dá)到,接下來(lái)瀏覽別的網(wǎng)頁(yè)了,都不必我們一次性地傳輸上千條記錄給他,所以也是PPI的應(yīng)用條件得到了滿足,結(jié)果則是此模式的優(yōu)點(diǎn)得到了發(fā)揮,又不影響全局的數(shù)據(jù)訪問(wèn)。
在進(jìn)行軟件模型的設(shè)計(jì)時(shí),整體的框架可以應(yīng)用某些優(yōu)秀的、通用的設(shè)計(jì)模式,這樣既加快模型的建立速度,又能和其它系統(tǒng)集成。但是,碰到一些瓶頸問(wèn)題的情況下,我們就需要對(duì)局部的設(shè)計(jì)模式做一些調(diào)整,以優(yōu)化整個(gè)系統(tǒng),上述三個(gè)模式就是對(duì)原有體系的補(bǔ)充,它們并沒(méi)有對(duì)整體的框架做出巨大的改變,卻突破了某些瓶頸(瓶頸往往是局部的)障礙,讓我們的產(chǎn)品更好地服務(wù)于用戶。
將深入研究的問(wèn)題
開(kāi)篇至今,我們主要探討了軟件層次上的解決問(wèn)題,但是,必須肯定一點(diǎn),如果你的硬件環(huán)境非常差(運(yùn)行Java都有困難)或非常好(額外的存儲(chǔ)空間、超快的運(yùn)算速度和富裕的網(wǎng)絡(luò)帶寬),上述途徑對(duì)你來(lái)說(shuō)很難有大的幫助。前一種情況,我建議你升級(jí)硬件設(shè)備到軟件廠商推薦的配置(強(qiáng)烈反對(duì)最小配置),以使應(yīng)用服務(wù)器、數(shù)據(jù)庫(kù)、Java等軟件能夠運(yùn)行自如;后一種情況,我沒(méi)什么話可說(shuō),花錢是解決這個(gè)問(wèn)題最好的辦法。
本文并未談及線程池和告訴緩沖這兩個(gè)非常重要的概念,因?yàn)楣P者認(rèn)為,它們是針對(duì)局部時(shí)間高訪問(wèn)量的瓶頸問(wèn)題的解決,不能理解為簡(jiǎn)單的速度瓶頸問(wèn)題,所以我會(huì)在下一篇文章中分析這種特殊的情況和提出解決問(wèn)題的辦法。也許你對(duì)這一點(diǎn)更關(guān)心一些,認(rèn)為自己的問(wèn)題就出在這個(gè)地方,這是非常好的思考問(wèn)題的方式,你已經(jīng)抓住了問(wèn)題的關(guān)鍵。但是,我還是建議你通讀一下本文,讓自己對(duì)速度瓶頸問(wèn)題有更好的理解,并掌握在解決問(wèn)題的過(guò)程中,分辨常態(tài)和暫態(tài),從而選擇不同的思路入手。其實(shí),本文談及的就是速度瓶頸問(wèn)題的常態(tài),而下一篇文章討論的將會(huì)是暫態(tài),希望你能夠漸入佳境。
JDO(Java Data Object)是需要我們關(guān)注的一個(gè)API,它定義了新的數(shù)據(jù)存取模型,直接借鑒了DAO設(shè)計(jì)模式。不同的數(shù)據(jù)源,有不同的數(shù)據(jù)存取技術(shù),就有不同的API供開(kāi)發(fā)人員使用。JDO正是為了解決這個(gè)問(wèn)題而產(chǎn)生的,它實(shí)現(xiàn)了即插即用的數(shù)據(jù)存取的實(shí)現(xiàn)和持久信息(包括企業(yè)數(shù)據(jù)和本地存儲(chǔ)的數(shù)據(jù))以Java為中心的視圖。因此,開(kāi)發(fā)人員只關(guān)注創(chuàng)建那些實(shí)現(xiàn)商業(yè)邏輯的類和用它們來(lái)表現(xiàn)數(shù)據(jù)源的數(shù)據(jù),而這些類和數(shù)據(jù)源之間的映射則由那些EIS領(lǐng)域的專家來(lái)完成。如果大家對(duì)JDO感興趣的話,那么我會(huì)寫(xiě)第三篇文章把其詳細(xì)介紹給大家,并給出示例應(yīng)用。