張志強(qiáng), 鄭 濤, 王偉鈞,楊晉浩
(成都大學(xué) 信息科學(xué)與工程學(xué)院,四川 成都 610106)
目前,在證券公司的數(shù)據(jù)交易系統(tǒng)中,其數(shù)據(jù)查詢是系統(tǒng)非常重要的功能之一.同時(shí),由于證券交易系統(tǒng)的數(shù)據(jù)量往往非常龐大,因此,提高查詢效率是數(shù)據(jù)查詢功能模塊設(shè)計(jì)的關(guān)鍵[1].針對(duì)不同環(huán)境下的數(shù)據(jù)訪問(wèn)接口,科研人員進(jìn)行了相關(guān)的研究與設(shè)計(jì),并取得了一系列成果[2-8],但針對(duì)證券數(shù)據(jù)交易系統(tǒng)的數(shù)據(jù)查詢?cè)L問(wèn)接口的研究和設(shè)計(jì)很少.對(duì)此,本研究采用分層化策略來(lái)設(shè)計(jì)數(shù)據(jù)訪問(wèn)接口,在客戶端層與服務(wù)器端數(shù)據(jù)層之間設(shè)計(jì)數(shù)據(jù)訪問(wèn)接口的中間層實(shí)現(xiàn)數(shù)據(jù)查詢流程,通過(guò)該數(shù)據(jù)訪問(wèn)接口的實(shí)現(xiàn),使得查詢過(guò)程具有分層化查詢、查詢數(shù)據(jù)精簡(jiǎn)化獲取等特點(diǎn),從而提高了數(shù)據(jù)查詢的效率.
本研究數(shù)據(jù)訪問(wèn)接口的體系架構(gòu)如圖1所示.

圖1數(shù)據(jù)訪問(wèn)接口的體系架構(gòu)
如圖1所示,本數(shù)據(jù)訪問(wèn)接口實(shí)現(xiàn)了客戶端層和服務(wù)器端數(shù)據(jù)層之間的中間層設(shè)計(jì).通過(guò)該中間層,當(dāng)客戶端利用瀏覽器請(qǐng)求查詢時(shí),查詢參數(shù)以get請(qǐng)求方式通過(guò)瀏覽器地址進(jìn)行傳遞,數(shù)據(jù)訪問(wèn)接口接收查詢參數(shù).在數(shù)據(jù)訪問(wèn)接口中,通過(guò)存儲(chǔ)過(guò)程調(diào)用接口將查詢參數(shù)傳遞到服務(wù)器端數(shù)據(jù)層的存儲(chǔ)過(guò)程進(jìn)行數(shù)據(jù)查詢,查詢結(jié)果返回到存儲(chǔ)過(guò)程調(diào)用接口.為了向客戶端瀏覽器返回精簡(jiǎn)的查詢數(shù)據(jù)結(jié)果,數(shù)據(jù)訪問(wèn)接口在接收到查詢結(jié)果數(shù)據(jù)后,需要進(jìn)行后期處理,其先將查詢結(jié)果數(shù)據(jù)通過(guò)對(duì)象數(shù)據(jù)封裝模塊封裝到數(shù)據(jù)對(duì)象中,然后再通過(guò)JSON封裝模塊將數(shù)據(jù)對(duì)象以JSON數(shù)據(jù)格式進(jìn)行封裝并產(chǎn)生JSON字符串,最后將JSON字符串返回到客戶端瀏覽器,從而實(shí)現(xiàn)精簡(jiǎn)的查詢數(shù)據(jù)結(jié)果.在后期,客戶端瀏覽器接收了JSON數(shù)據(jù)后,進(jìn)行前端解析,并最終將查詢數(shù)據(jù)在Web端或移動(dòng)端瀏覽器以設(shè)定的樣式進(jìn)行顯示.這種分層化的設(shè)計(jì)可以使數(shù)據(jù)查詢壓力分散在不同的地方.
為了實(shí)現(xiàn)數(shù)據(jù)訪問(wèn)接口的通用性參數(shù)控制,本研究將數(shù)據(jù)庫(kù)服務(wù)器連接和登錄信息參數(shù)存儲(chǔ)在配置參數(shù)文件中.其配置參數(shù)文件的內(nèi)容格式說(shuō)明如表1所示.同時(shí),多個(gè)配置參數(shù)以XML格式存儲(chǔ)在文件中,其存儲(chǔ)結(jié)構(gòu)形式如圖2所示.

表1 配置參數(shù)文件的格式說(shuō)明

圖2參數(shù)配置文件的存儲(chǔ)形式
在數(shù)據(jù)訪問(wèn)接口中,首先利用DOM接口進(jìn)行配置參數(shù)文件的讀取操作,然后根據(jù)讀取的參數(shù)值實(shí)現(xiàn)數(shù)據(jù)庫(kù)服務(wù)器的連接和登錄.由此可見(jiàn),通過(guò)動(dòng)態(tài)修改配置參數(shù)文件內(nèi)容的方式,可以使得數(shù)據(jù)訪問(wèn)接口具有動(dòng)態(tài)設(shè)置權(quán)限賬戶連接和登錄數(shù)據(jù)庫(kù)服務(wù)器的通用能力.此外,對(duì)配置參數(shù)文件的內(nèi)容進(jìn)行修改后,將參數(shù)配置文件的路徑地址作為參數(shù)傳遞到配置參數(shù)讀取程序,從而完成配置參數(shù)的讀取.
通常,在證券數(shù)據(jù)交易系統(tǒng)中,數(shù)據(jù)表的數(shù)據(jù)量非常大,而且查詢數(shù)據(jù)往往來(lái)自多個(gè)表的關(guān)聯(lián),如果在Web服務(wù)器中執(zhí)行查詢操作會(huì)給Web服務(wù)器帶來(lái)較大的壓力.為了降低Web服務(wù)器的壓力,可將數(shù)據(jù)查詢操作放在數(shù)據(jù)層的數(shù)據(jù)庫(kù)服務(wù)器中,通過(guò)由客戶查詢需求設(shè)計(jì)的存儲(chǔ)過(guò)程來(lái)完成數(shù)據(jù)查詢的任務(wù).因此,在數(shù)據(jù)訪問(wèn)接口的設(shè)計(jì)中,需要設(shè)計(jì)存儲(chǔ)過(guò)程調(diào)用接口模塊,通過(guò)該模塊,根據(jù)客戶的不同查詢需求,調(diào)用相應(yīng)存儲(chǔ)過(guò)程完成查詢?nèi)蝿?wù).在存儲(chǔ)過(guò)程調(diào)用接口模塊設(shè)計(jì)中,首先判斷數(shù)據(jù)庫(kù)連接和登錄操作是否完成,如果沒(méi)有完成,則完成相應(yīng)的數(shù)據(jù)庫(kù)連接和登錄操作,然后獲取執(zhí)行參數(shù),這里執(zhí)行參數(shù)由3部分構(gòu)成,分別是存儲(chǔ)過(guò)程名、存儲(chǔ)過(guò)程in參數(shù)列表及存儲(chǔ)過(guò)程out參數(shù)個(gè)數(shù).由in參數(shù)列表動(dòng)態(tài)構(gòu)建和設(shè)置存儲(chǔ)過(guò)程的in參數(shù),由out參數(shù)個(gè)數(shù)動(dòng)態(tài)構(gòu)建和設(shè)置存儲(chǔ)過(guò)程的out參數(shù)類(lèi)型,調(diào)用存儲(chǔ)過(guò)程,獲取并返回查詢結(jié)果集.其算法設(shè)計(jì)如下:
GetInfo(storageprogramname,In-pram,Out-pram-length)
參數(shù)說(shuō)明:
storageprogramname:存儲(chǔ)過(guò)程名
In-pram:存儲(chǔ)過(guò)程in參數(shù)列表
Out-pram-length:存儲(chǔ)過(guò)程out參數(shù)的個(gè)數(shù)值
begin
如果沒(méi)有完成數(shù)據(jù)庫(kù)的連接和登錄操作,則先完成相關(guān)操作;
String str=″{call″ + storageprogramname + ″(″;
repeat
str=str + ″?,″;
untile In-pram參數(shù)列表處理完;
repeat
str=str + ″?,″;
until Out-pram-length - 1處理完;
str = str + ″?)}″;
st =conn.prepareCall(str);
repeat
設(shè)置st的in參數(shù)值;
until In-pram參數(shù)列表處理完;
repeat
設(shè)置st的out參數(shù)值類(lèi)型;
until Out-pram-length參數(shù)處理完;
結(jié)果集rs執(zhí)行存儲(chǔ)過(guò)程storageprogramname;
return結(jié)果集rs;
end
存儲(chǔ)過(guò)程返回查詢結(jié)果集后,需要將查詢結(jié)果集的數(shù)據(jù)封裝到數(shù)據(jù)對(duì)象中,這樣便于為后期JSON數(shù)據(jù)封裝處理提供數(shù)據(jù)源.在數(shù)據(jù)對(duì)象的封裝處理過(guò)程中,首先根據(jù)查詢需求,設(shè)計(jì)出數(shù)據(jù)對(duì)象的實(shí)體類(lèi),然后根據(jù)獲取的查詢結(jié)果集,將其數(shù)據(jù)寫(xiě)入實(shí)體類(lèi)的對(duì)象中.
以客戶信息查詢?yōu)槔诳蛻粜畔⒉樵冃枨笾校蛻粜畔⒂煽蛻艋拘畔⒑涂蛻敉扑]產(chǎn)品信息構(gòu)成,客戶信息查詢數(shù)據(jù)類(lèi)的UML設(shè)計(jì)如圖3所示.
圖3客戶信息查詢數(shù)據(jù)類(lèi)的UML結(jié)構(gòu)
從圖3可知,客戶查詢數(shù)據(jù)類(lèi)ClientInfo的對(duì)象包含了經(jīng)理數(shù)據(jù)類(lèi)ManagerInfo的對(duì)象(manager)和客戶產(chǎn)品推薦類(lèi)Recommends的對(duì)象(recommends),其中,類(lèi)ClientInfo與類(lèi)ManagerInfo之間是1∶1的關(guān)聯(lián)關(guān)系,類(lèi)ClientInfo與類(lèi)Recommends之間是1∶n的關(guān)聯(lián)關(guān)系.這些類(lèi)之間的關(guān)聯(lián)關(guān)系也體現(xiàn)了數(shù)據(jù)庫(kù)的多表關(guān)聯(lián)查詢的形式.客戶信息查詢的數(shù)據(jù)對(duì)象封裝算法設(shè)計(jì)如下:
getClients (rs1,rs2)
參數(shù)說(shuō)明:
rs1:客戶基本信息查詢結(jié)果集;
rs2:客戶推薦產(chǎn)品信息查詢結(jié)果集
begin
構(gòu)建ClientInfo類(lèi)的對(duì)象集合clients和Recommends類(lèi)的對(duì)
象集合res;
i←0;
repeat
c←創(chuàng)建ClientInfo對(duì)象;
將rs1的第i條數(shù)據(jù)記錄的ClientInfo對(duì)象基本分量寫(xiě)
入c;
m←創(chuàng)建ManagerInfo對(duì)象;
將rs1的第i條數(shù)據(jù)記錄的ManagerInfo對(duì)象分量寫(xiě)入m;
c的ManagerInfo對(duì)象分量manager←m;
j←0;
清空res;
repeat
r←創(chuàng)建Recommends對(duì)象;
將rs2的第j條數(shù)據(jù)記錄的Recommends對(duì)象分量
寫(xiě)入r;
res←r;
j←j + 1;
until rs2結(jié)果集中所有數(shù)據(jù)記錄處理結(jié)束;
c的Recommends對(duì)象分量recommends←res;
clients←c;
i←i + 1;
until rs1結(jié)果集中所有數(shù)據(jù)記錄處理結(jié)束;
return clients;
end
在本算法中,rs1和rs2都是通過(guò)GetInfo接口獲取的查詢結(jié)果集,最后根據(jù)rs1和rs2的結(jié)果集,將相應(yīng)數(shù)據(jù)封裝到客戶信息查詢數(shù)據(jù)對(duì)象集合clients中.
一般而言,在證券數(shù)據(jù)交易系統(tǒng)的查詢中,為了提高查詢效率,在客戶端瀏覽器進(jìn)行查詢后,客戶端瀏覽器只需要接收精簡(jiǎn)的查詢結(jié)果數(shù)據(jù),而不需要接收臃腫的html數(shù)據(jù)代碼.為了實(shí)現(xiàn)這種策略,需要將查詢結(jié)果數(shù)據(jù)封裝為JSON數(shù)據(jù),然后返回給客戶端瀏覽器.由于JSON數(shù)據(jù)格式是一種輕量級(jí)的數(shù)據(jù)交換格式,其廣泛應(yīng)用于網(wǎng)頁(yè)數(shù)據(jù)的存儲(chǔ)和交換文本信息,客戶端很容易利用JS解析JSON數(shù)據(jù)并在客戶端瀏覽器按照指定樣式顯示數(shù)據(jù).因此,客戶端瀏覽器接收J(rèn)SON數(shù)據(jù),有利于后期的解析處理.
在數(shù)據(jù)對(duì)象封裝模塊中,客戶查詢數(shù)據(jù)已經(jīng)封裝到數(shù)據(jù)對(duì)象中,在JSON數(shù)據(jù)封裝模塊中,根據(jù)數(shù)據(jù)對(duì)象,將查詢數(shù)據(jù)以JSON格式進(jìn)行封裝.盡管專(zhuān)門(mén)有封裝JSON數(shù)據(jù)的類(lèi)庫(kù),但由于查詢結(jié)果數(shù)據(jù)的結(jié)構(gòu)復(fù)雜多樣,直接使用類(lèi)庫(kù)產(chǎn)生特殊格式的JSON數(shù)據(jù)會(huì)比較困難.因此,本研究設(shè)計(jì)了特定的JSON數(shù)據(jù)封裝模塊,其以數(shù)據(jù)對(duì)象為數(shù)據(jù)源,進(jìn)行JSON數(shù)據(jù)封裝,并最終形成JSON字符串.JSON數(shù)據(jù)封裝模塊算法設(shè)計(jì)如下:
ClentsJsonString(list)
參數(shù)說(shuō)明:
list:客戶信息查詢數(shù)據(jù)對(duì)象集合,其為getClients算法的clients
begin
if list集合中數(shù)據(jù)對(duì)象個(gè)數(shù) = 1 then
將list集合中第1條數(shù)據(jù)記錄的ClientInfo對(duì)象基本分
量按照J(rèn)SON格式構(gòu)建字符串JsonString1;
j←0;
repeat
recommends←獲取list集合中第1個(gè)數(shù)據(jù)記錄的第
j個(gè)Recommends對(duì)象分量;
將recommends按照J(rèn)SON格式構(gòu)建字符串
JsonString2;
JsonStr集合←JsonString2;j←j + 1;
until list集合中第1條數(shù)據(jù)記錄的Recommends對(duì)象分
量處理結(jié)束;
根據(jù)JsonStr集合構(gòu)建嵌套結(jié)構(gòu)的字符串JsonString3;
JsonString←JsonString1 + JsonString3;
else if list集合中數(shù)據(jù)對(duì)象個(gè)數(shù) > 1 then
i←0;
repeat
clientInfo←獲取list集合中第i條數(shù)據(jù)記錄的
ClientInfo對(duì)象基本分量;
將clientInfo按照J(rèn)SON格式構(gòu)建字符串JsonString1;
j←0;清空J(rèn)sonStr集合;
repeat
recommends←獲取list集合中第i條數(shù)據(jù)記錄
的第j個(gè)Recommends對(duì)象分量;
將recommends按照J(rèn)SON格式構(gòu)建字符串JsonString2;
JsonStr集合←JsonString2;j←j + 1;
until list集合中第i條數(shù)據(jù)記錄的Recommends對(duì)
象分量處理結(jié)束;
根據(jù)JsonStr集合構(gòu)建嵌套結(jié)構(gòu)的字符串JsonString3;
JsonString4←JsonString1 + JsonString3;
JsonStr2集合←JsonString4;
i←i + 1;
until list集合的數(shù)據(jù)對(duì)象處理結(jié)束;
根據(jù)JsonStr2集合構(gòu)建嵌套結(jié)構(gòu)的字符串JsonString5;
JsonString←JsonString5;
end if
return JsonString;
end
在ClentsJsonString算法中,list為getClients算法處理的數(shù)據(jù)對(duì)象集合clients,其由1個(gè)或多個(gè)數(shù)據(jù)對(duì)象構(gòu)成.ClentsJsonString算法根據(jù)數(shù)據(jù)對(duì)象集合list利用JSON數(shù)據(jù)格式進(jìn)行JSON數(shù)據(jù)封裝,在封裝過(guò)程中,會(huì)根據(jù)數(shù)據(jù)對(duì)象之間的關(guān)聯(lián),構(gòu)建具有嵌套結(jié)構(gòu)的JSON字符串JsonString.
在證券數(shù)據(jù)交易系統(tǒng)中,客戶通過(guò)客戶端瀏覽器以get請(qǐng)求方式調(diào)用數(shù)據(jù)訪問(wèn)接口進(jìn)行查詢,數(shù)據(jù)訪問(wèn)接口首先在瀏覽器的地址信息中獲取查詢的參數(shù),然后將查詢參數(shù)傳遞給存儲(chǔ)過(guò)程調(diào)用接口模塊執(zhí)行查詢,接著將查詢結(jié)果集傳遞到數(shù)據(jù)對(duì)象封裝模塊進(jìn)行數(shù)據(jù)對(duì)象的封裝處理,接著將封裝后的數(shù)據(jù)對(duì)象傳遞到JSON數(shù)據(jù)封裝模塊進(jìn)行JSON數(shù)據(jù)封裝處理,最后將封裝后的JSON字符串返回到客戶端瀏覽器.在后期,可以由客戶端的JS進(jìn)行解析操作.由于數(shù)據(jù)訪問(wèn)接口是通過(guò)網(wǎng)絡(luò)請(qǐng)求方式調(diào)用,因此采用Servlet方式設(shè)計(jì),其部署在Tomcat的Web服務(wù)器端.數(shù)據(jù)處理流程如圖4所示.
圖4數(shù)據(jù)訪問(wèn)接口的數(shù)據(jù)處理流程
在測(cè)試中,數(shù)據(jù)訪問(wèn)接口采用Java編程實(shí)現(xiàn),Web服務(wù)器采用Tomcat 7.0進(jìn)行部署,數(shù)據(jù)庫(kù)服務(wù)器系統(tǒng)采用SQL Server 2008 R2,數(shù)據(jù)庫(kù)連接與登錄的參數(shù)配置文件內(nèi)容如圖2所示,其部署在Tomcat服務(wù)器中.
接口設(shè)計(jì)中,首先需要根據(jù)客戶的查詢需求設(shè)計(jì)不同的多個(gè)數(shù)據(jù)訪問(wèn)接口,本研究以客戶信息查詢需求為例,設(shè)計(jì)并測(cè)試了客戶信息查詢數(shù)據(jù)訪問(wèn)接口的運(yùn)行結(jié)果.在數(shù)據(jù)庫(kù)服務(wù)器系統(tǒng)中部署了相應(yīng)的數(shù)據(jù)表和存儲(chǔ)過(guò)程,其中,ClientInfo表(用戶信息表)如表2所示,ManagerInfo表(客戶經(jīng)理信息表)如表3所示,ClientRecommendation表(客戶推薦產(chǎn)品表)如表4所示,客戶基本信息查詢存儲(chǔ)過(guò)程如圖5所示,客戶推薦產(chǎn)品信息查詢存儲(chǔ)過(guò)程如圖6所示.

表2 ClientInfo表

表3 ManagerInfo表

表4 ClientRecommendation表

圖5客戶基本信息查詢存儲(chǔ)過(guò)程

圖6客戶推薦產(chǎn)品信息查詢存儲(chǔ)過(guò)程
客戶端瀏覽器查詢界面如圖7所示,在客戶端瀏覽器的http請(qǐng)求地址中,testServlet為數(shù)據(jù)訪問(wèn)接口名、Id為查詢參數(shù),其為客戶身份編號(hào)(以get請(qǐng)求方式傳遞查詢參數(shù)到testServlet接口),查詢結(jié)果以JSON數(shù)據(jù)格式進(jìn)行嵌套封裝后返回到客戶端瀏覽器,從圖7可以看出,返回到客戶端瀏覽器的數(shù)據(jù)不再是冗余的html代碼,而是精簡(jiǎn)的可解析查詢數(shù)據(jù).

圖7數(shù)據(jù)訪問(wèn)接口查詢的返回結(jié)果
針對(duì)證券數(shù)據(jù)交易系統(tǒng)查詢的特殊性,本研究采用了分層的數(shù)據(jù)訪問(wèn)接口,通過(guò)該接口的實(shí)現(xiàn)可以看出,一方面分散了各部分的查詢壓力,另一方面也精簡(jiǎn)了查詢結(jié)果的返回值,進(jìn)而從整體上提高了查詢效率.本研究為證券數(shù)據(jù)交易系統(tǒng)的查詢功能提供了一種可實(shí)例化的設(shè)計(jì)模式.