董 琴
(鹽城工學院 實驗教學部, 鹽城 224051)
PowerBuilder提供了對目前流行的大多數關系數據庫管理系統的支持,由于在PowerBuilder的應用程序中對數據庫訪問的部分一般采用國際化標準數據庫查詢語言SQL,使得用PowerBuilder開發的應用程序可以不做修改或者只做少量的修改就可以在不同的后臺數據庫管理系統上使用。也就是說用PowerBuilder開發的應用程序是獨立于服務器上的數據庫管理系統的。PowerBuilder是一種面向對象的開發工具,各種WINDOWS應用程序中常見的窗口、菜單、控件等在PowerBuilder中都是一個個的對象。在PowerBuilder中我們還可以創建自己的用戶對象。特別要指出的是PowerBuilder提供了對面向對象方法中的各種技術的全面支持,我們可以利用面向對象方法中的對象的封裝性、繼承性、多態性等特點使得我們開發的應用程序具有極大的可重用性和可擴展性,而這一點正是軟件工程中對應用程序所提出的重要目標。
對客戶端軟件開發我們用PowerBuilder編程語言實現。PowerBuilder是一種目前流行的數據庫前端開發工具,相對于其他的客戶機/服務器開發工具而言,PowerBuilder提供的開發環境更加方便快捷,而且功能也更為強大,特別適合做信息系統的開發,它為開發人員提供豐富的對象、控件、函數以及良好的用戶界面,支持目前流行的數據庫,支持Web應用的開發,支持應用的跨平臺開發和分布,極大地減輕了程序員在不同平臺上移植程序的工作量。PowerBuilder提出了數據窗口(DataWindow)對象的概念。數據窗口對象是PowerBuilder中的一種對象類型,是專門為訪問后臺的數據庫服務的,在數據窗口對象中我們定義了數據的來源和數據的顯示風格。PowerBuilder在數據窗口對象中提供了豐富的數據顯示方式,可以滿足各種不同的需要。我們應用中的很多報表就是通過數據窗口對象來實現的,如果要更改報表的數據內容和顯示格式,也只要對相應的數據窗口對象進行修改就可以了。
PowerBuilder開發的應用服務器上的組件其實就是一個自定義的類。它基于面向對象的思想,將復雜的業務邏輯處理和數據訪問代碼封裝在其中,以實現邏輯獨立性和組件級的代碼共享,
便于維護。我們將組件方法調用中引用到的數據窗口對象(也就是報表對象)跟該組件對象的自定義對象存儲在同一個庫文件中,可以利用PowerBuilder開發工具中的很多向導一起發行并部署到EAServer上。EAServer作為Sybase公司提供的企業級應用服務器,支持用PB、Java、C等多種語言編寫的組件。EAServer為服務器端的組件提供了緩沖機制、安全性和事務處理等多方面的支持,可以使用EAServer提供的事務管理機制來取代傳統的使用Commit和Rollback的事務管理方法。
服務組件對后臺數據庫的訪問是通過通用數據庫接口(如ODBC)或者DBMS生產商提供的專用數據庫接口進行的。為了提高資源利用率,減少服務器的開銷,EAServer提供了數據庫連接緩沖機制。由于分布式應用中客戶端不直接訪問數據庫,而通過組件來訪問數據庫,PB開發的組件是通過使用PB傳統的非可視化數據訪問對象Datastore來訪問后臺數據庫,訪問方法與兩層C/S應用中的數據訪問方法相同。當數據存儲對象通過Retrieve函數把報表數據提取到數據存儲對象后,通過數據存儲對象的GetFullState函數再把它提取到一個Blob型的變量里。客戶端軟件通過遠程對象的方法調用再把Blob型的數據提取到客戶端,用SetFullState函數把Blob變量里的內容重新填入目標數據窗口中,以便再現從數據庫提取的報表內容和格式。
如圖1所示,系統采用基于EAServer應用服務器的多層分布式結構。EAServer提供了對各類組件的管理和通信環境,報表引擎是封裝數據存儲和數據連接的一組組件,由客戶端的報表系統接口調用。其中數據連接對象用于與各種數據庫建立連接,支持PowerBuilder的內部接口和ODBC兩種接口,組件對象向客戶端提供了獲取報表數據的各種方法。

圖1 系統的總體結構
在客戶端應用中,連接對象負責與EAServer的通信聯系;代理對象封裝了EAServer組件的客戶端接口,使客戶端應用象訪問本地對象實例一樣訪問EAServer組件。報表接口就是封裝了連接對象和代理對象的客戶端應用接口,可以訪問報表引擎的所有功能。
報表引擎運行在應用服務器EAServer上,為客戶端提供所有報表系統的功能服務。EAServer支持多種組件類型,如COM、CORBA、JavaBean/EJB和PowerBuilder NVO。PowerBuilder NVO組件具有跨平臺特性,可以高效穩定地運行,因此報表引擎采用PowerBuilderNVO組件來實現。PowerBuilder是面向對象的可視化編程語言,支持類的繼承、封裝、重載和多態性。在報表引擎的實現中首先把數據庫連接、數據存儲和數據訪問做成基本類庫,供其他功能類繼承。組件類圖如圖2所示。

圖2 組件基本類庫
n_easdb為其他類的父類,主要方法有對事務服務對象、數據庫事務對象、錯誤日志對象的建立和對日志信息的記錄等,其中s_userinfo是一個包含客戶端用戶信息的參數類型,便于對客戶端的操作進行記錄,n_easdb類是跟數據操作相關類的基礎類。類n_rep用于從數據庫提取報表結構數據,其中of_getdw_withparm函數一般被子類調用,用于根據用戶參數生成對應報表的blob數據(帶有數據內容和格式);of_get_ddlb_reps函數用于提取客戶端框架窗口可以操作的報表對象名,以便客戶端用戶選擇對應報表;of_get_parm_window函數用于提取客戶端框架窗口對應的報表參數選擇窗口。類n_rep_sale用于根據客戶端框架窗口的選定參數提取對應報表的數據(通過調用of_getdw_withparm函數),生成組件后可以被客戶端通過代理對象進行遠程調用。根據不同的業務報表需要可以從n_rep繼承建立如發貨、庫存等相應類后生成組件對象。
客戶端程序的編寫可分為三個步驟:建立連接對象、建立組件代理對象和編寫客戶端應用。連接對象(Connection Object)負責客戶端應用與組件服務器之間的通信,代理對象(Proxy Object)是應用服務器中處理業務邏輯的組件在客戶端的代理,客戶端應用正是通過代理對象來使用遠程應用服務器的組件所提供的服務。可以利用PowerBuilder所提供的連接對象向導和組件代理向導就可以很容易地建立連接對象和代理對象。
筆者以實現銷售查詢和統計報表框架的實現為例說明客戶端報表框架的設計與實現,其窗口對象的基本類圖如圖3所示。

圖3 窗口對象的基本類圖
w_rep為父類,具有一般報表窗口的基本功能,is_parmwindow屬性存儲框架窗口對應的參數選擇窗口對象,istru_parm,istru_pram_old屬性是一個結構對象,存儲報表對象名以及若干個選擇參數的值,每次打開報表參數選擇窗口后,只要比較該二個屬性的值就可以判斷用戶是否改變了報表參數,從而決定是否要重新從數據庫檢索數據。
類w_rep_sale中的屬性io_rep_sale是服務于該框架窗口的組件代理對象,通過代理對象,客戶端程序可以方便地調用組件的方法,根據報表參數檢索報表數據。根據不同的業務報表需要可以從w_rep繼承建立如發貨、庫存等相應類的報表框架窗口類,在實例對象時只要重載wf_retrieve函數和ue_open事件就可以了,例如w_rep_sale類實例對象的ue_open事件的主要代碼如下:
io_rep = CREATE no_rep_sale
io_rep.of_get_parm_window(gstru_user,this.classname(),is_parmwindow)//取對應參數選擇窗口名,gstru_user為一全局變量。
io_rep.of_get_ddlb_reps(istru_parm.parm4,istru_parm.parm5,this.classname()) //取對應框架窗口可以受理的報表對象名及報表標題,結果保存在參數中,以便在參數選擇窗口中顯示供選報表。
PostEvent("ue_select") //根據istru_parm值打開參數選擇窗口,以便用戶選擇報表參數,確認后調用wf_retrieve()函數。
wf_retrieve()函數的主要代碼如下:
long ll_ret
blob lbl_data
ll_ret= io_rep.of_rep_sale(gstru_user,istru_parm,lbl_data)//通過代理對象調用組件方法
ll_ret = dw_1.SetFullState(lbl_data)//把Blob變量里的內容重新填入報表框架的窗口數據
//窗口中,顯示報表內容和樣式。
用戶查詢和統計銷售數據時對應報表框架窗口及參數選擇窗口界面如圖4所示。客戶銷售統計表框架窗口具有報表的打印、另存、放大、縮小、標尺預覽等常規操作功能,檢索功能可以打開框架窗口對應的報表參數選擇窗口,以便用戶可以方便地選擇要檢索數據的相應條件,也可以選擇報表框架窗口可以處理的其他報表對象。用戶對報表的內容和格式要求有變化的時候,只要修改對應的組件庫中的Datawindow對象就可以,如果用戶要增加一個關于客戶銷售類的報表,也只要在對應的組件庫文件中增加新的DataWindow對象,并在數據庫的表sys_ddlb_rep中增加一條跟該報表框架窗口關聯的記錄,INSERT語句如下:
INSERT INTO sys_ddlb_rep VALUES (
'd_rep_custdaysale',
//新的datawindow對象名
'客戶日銷售統計表',
//報表的標題名稱
'w_rep_sale',
//報表框架窗口對象名
'w_rep_sale_parm_select');
//報表框架窗口對應參數選擇窗口對象名

圖4 運行時銷售報表框架窗口界面
開發基于網絡的、具有較高的邏輯獨立性、可擴展性和可復用性的分布式報表應用是企業信息系統的發展趨勢。本文介紹了一種基于EAServer應用框架的分布式報表系統的開發技術,相信會給廣大軟件開發人員提供一個新的報表應用的開發思路。筆者運用該技術為家紡企業的銷售與分銷管理開發了一個報表應用軟件,投入使用一年多來,性能穩定、運行良好,且易維護,充分體現了分布式應用的各種優勢。
[1] William Green John D.Olson,李洪發,王海峰,等譯.Power-Builder Internet及分布式應用開發[M].北京:機械工業出版社,2004.
[2] 華銓平.PowerBuilder程序設計[M].北京:清華大學出版社、北方交通大學出版社,2004.
[3] 白尚旺.PowerDesigner軟件工程技術[M].北京:電子工業出版社,2004.
[4] 楊曦.基于組件技術的信息系統設計與實現[J].福州大學學報(自然科學版),2006(11).
[5] 劉華成.基于PowerBuilder 10.5數據報表系統的設計與實現[J].電腦知識與技術 2009.(21).
[6] 海濤.課程管理系統PowerBuilder實現[J].計算機技術與發展,2009,(02).