- 相關(guān)推薦
分布式多層數(shù)據(jù)庫系統(tǒng)的應(yīng)用(一)
摘要
本次畢業(yè)設(shè)計任務(wù)是通過開發(fā)一個分布式多層數(shù)據(jù)庫圖書管理系統(tǒng),學(xué)習(xí)用delphi開發(fā)分布式多層數(shù)據(jù)庫系統(tǒng)。采用Delphi6.0和MS Server2000等軟件為開發(fā)工具;通過對計算機硬件和軟件解決方案的論證;對應(yīng)用領(lǐng)域進行調(diào)查分析;參考各種資料和進行數(shù)據(jù)庫編程實踐。在指導(dǎo)老師的幫助下,已經(jīng)基本上成功地實現(xiàn)了設(shè)計任務(wù)書的要求。使得設(shè)計的數(shù)據(jù)庫系統(tǒng)能夠?qū)崿F(xiàn)一般數(shù)據(jù)庫的管理。我們研究了數(shù)據(jù)庫的查詢優(yōu)化問題。
第一部分 引 言
1.1任務(wù)或問題:
開發(fā)一個分布式多層圖書管理系統(tǒng),可以實現(xiàn)動態(tài)的連接應(yīng)用程序服務(wù)器,只要對配置文件進行配置,就可以像網(wǎng)上鄰居一樣選擇所要連接的應(yīng)用程序服務(wù)器。并提供借書還書,圖書和期刊檢索等查詢功能。
1.2實際背景:
隨著社會發(fā)展,人類的生產(chǎn)、生活越來越離不開信息。誰擁有了更多更有效的信息,誰就將在競爭中處于有利地位。信息產(chǎn)業(yè)正在成為一個國家的支柱。數(shù)據(jù)作為信息的載體,其管理工具數(shù)據(jù)庫對于信息技術(shù)的重要性,正日益得到人們的重視。只有擁有了先進的數(shù)據(jù)庫技術(shù),才能有效地管理好浩如煙海的數(shù)據(jù),并從中提取出對自己有用的信息來加以利用。
90年代,人們開發(fā)MIS系統(tǒng)大都采用客戶機/服務(wù)器結(jié)構(gòu),客戶機/服務(wù)器結(jié)構(gòu)既是硬件結(jié)構(gòu)又是軟件結(jié)構(gòu)。即數(shù)據(jù)放在服務(wù)器上,程序在客戶機上。進行數(shù)據(jù)訪問時,由客戶機提出請求(一般是SQL語句),服務(wù)器執(zhí)行并給出結(jié)果?蛻魴C/服務(wù)器對于優(yōu)化了網(wǎng)絡(luò),提高了系統(tǒng)的利用率?蛻魴C/服務(wù)器體系結(jié)構(gòu)的發(fā)展經(jīng)歷了從二級體系結(jié)構(gòu)模式到三級體系結(jié)構(gòu)模式。
1.3我的工作
設(shè)計系統(tǒng)框架,設(shè)計數(shù)據(jù)庫,編寫代碼,測試數(shù)據(jù)等。
1.4特色(創(chuàng)新)
可以像網(wǎng)上鄰居一樣選擇所要連接的應(yīng)用程序服務(wù)器。
第二部分 畢業(yè)設(shè)計課題
設(shè)計課題
漳大圖書館管理系統(tǒng)
設(shè)計時間
二○○四年10月至二○○四年12月
設(shè)計人員及任務(wù)
王東凱 動態(tài)連接服務(wù)器模塊的實現(xiàn)及幫助件功能模塊的實現(xiàn)
王開斌 分布式多層數(shù)據(jù)模塊的實現(xiàn)
王杰林 圖書管理功能模塊的實現(xiàn)
陳慶輝 sqlserver 2000數(shù)據(jù)庫的分析及表的設(shè)計
指導(dǎo)老師
蘇綠園
設(shè)計內(nèi)容
利用Delphi6.0和MS Server2000為主要開發(fā)工具,以WindowsXP為開發(fā)平臺。設(shè)計出分布式多層應(yīng)用的圖書館管理系統(tǒng)?梢詫崿F(xiàn)動態(tài)的連接應(yīng)用程序服務(wù)器,只要對配置文件進行配置,就可以像網(wǎng)上鄰居一樣選擇所要連接的應(yīng)用程序服務(wù)器。實現(xiàn)與應(yīng)用程序服務(wù)器快速而準(zhǔn)確的連接。
第三部分 系統(tǒng)方案論證
3.1軟件定義
數(shù)據(jù)庫設(shè)計所要的解決的問題是:對于一個給定的應(yīng)用領(lǐng)域,設(shè)計優(yōu)化的數(shù)據(jù)庫邏輯和物理結(jié)構(gòu),使之滿足用戶的信息管理要求和數(shù)據(jù)操作要求,有效地支持各種應(yīng)用系統(tǒng)的開發(fā)和運行。數(shù)據(jù)庫設(shè)計的目標(biāo)是為用戶和各種應(yīng)用系統(tǒng)提供一個高效的運行環(huán)境。而數(shù)據(jù)庫的設(shè)計可以視為如下的優(yōu)化問題。
計算機的軟硬件環(huán)境;
數(shù)據(jù)庫管理系統(tǒng)的能力;
用戶的操作要求與信息要求;
完整性和安全性約束。
3.2 體系結(jié)構(gòu)規(guī)劃
本次設(shè)計的系統(tǒng)采用 三層″客戶/服務(wù)器″體系,為了便于理解,我們先從二層″客戶/服務(wù)器″體系結(jié)構(gòu)來闡述:
客戶/服務(wù)器是在網(wǎng)絡(luò)基礎(chǔ)上,以數(shù)據(jù)庫管理為后援,以計算機為網(wǎng)上工作站的一種系統(tǒng)結(jié)構(gòu)。該結(jié)構(gòu)的關(guān)鍵在把網(wǎng)絡(luò)環(huán)境上的數(shù)據(jù)庫存取和應(yīng)用程序一分為二,分別由網(wǎng)上的數(shù)據(jù)庫服務(wù)器和網(wǎng)上客戶來執(zhí)行。雖然本系統(tǒng)客戶/服務(wù)器是建立在LAN的基礎(chǔ)上,但它比以往的文件服務(wù)系統(tǒng)有了很大的改進。首先,它消除了不必要的網(wǎng)絡(luò)傳輸負(fù)擔(dān);其次,它可以使作為數(shù)據(jù)庫服務(wù)器的計算機被高度優(yōu)化,以適應(yīng)數(shù)據(jù)處理的需要?蛻/服務(wù)器已經(jīng)能夠應(yīng)用于復(fù)雜的網(wǎng)絡(luò)上,并使之能夠更有效地進行選擇、檢索、索引排序等數(shù)據(jù)處理。作為一種高級的分布式計算機環(huán)境、客戶/服務(wù)器有足夠的能力把處理后的結(jié)果(不是整個文件)通過網(wǎng)絡(luò)傳輸出去,并根據(jù)用戶需求靈活地配置各種大、中、小型計算機系統(tǒng)。
3.3 系統(tǒng)設(shè)計
數(shù)據(jù)流圖
管理要求 查詢要求
管理結(jié)果 查詢結(jié)果
(頂層數(shù)據(jù)流圖)
數(shù)據(jù)庫設(shè)計過程
數(shù)據(jù)庫的設(shè)計過程如下圖所示。在數(shù)據(jù)庫設(shè)計過程中,需求分析和概念設(shè)計可以獨立于任何數(shù)據(jù)庫管理系統(tǒng)進行。邏輯設(shè)計和物理設(shè)計與具體的數(shù)據(jù)庫管理系統(tǒng)密切相關(guān)。由于需求分析比較重要。我們在設(shè)計的時候,花了比較多的時間。在獲得這些資料之后,進行分析。從中提取有用的部分。分析各種用戶的權(quán)限。
需求分析說明書
圖:數(shù)據(jù)庫設(shè)計過程
第四部分 畢業(yè)設(shè)計內(nèi)容
4.1分布式多層數(shù)據(jù)庫開發(fā)簡介
Delphi提出的MIDAS(Multi-Tier distributed Application Services Suite多層分布式應(yīng)用服務(wù)器組),是把原來Two- Tier數(shù)據(jù)連接放到了服務(wù)器端的COM組件上,客戶端只剩下了執(zhí)行文件和MIDAS.DLL,前臺和服務(wù)器上的COM組件,通過DCOM機制互相溝通。
這個多的一層,稱為應(yīng)用程序服務(wù)器(Application Server),或者稱為中間件。整個工作機制見下圖:
這種多層分布式工作機制,主要基于這樣幾點考慮:
減少客戶機的維護量,因為前臺程序比較簡單;
把企業(yè)邏輯封裝在通用的中間件應(yīng)用服務(wù)器中,不同的客戶都可以共享同一個中間層(包括Web),而不必每個客戶都單獨實現(xiàn)企業(yè)規(guī)則,避免了重復(fù)開發(fā)和維護的麻煩。由于客戶程序相當(dāng)瘦(這就是現(xiàn)在流行的瘦客戶機概念),無論是開發(fā)還是發(fā)布,都變得簡單了。
便于升級,當(dāng)中間件升級的時候,客戶程序可能不需要變化;
實現(xiàn)了分布式數(shù)據(jù)處理,把一個應(yīng)用程序分布在幾臺機器上運行,可以提高應(yīng)用程序的性能,也可以把敏感部分封裝在中間件,為不同的用戶設(shè)置不同的訪問權(quán)限,增強了安全性。
減少直接連接數(shù)據(jù)庫的用戶數(shù)目,減少費用。
在Delphi 6.0上,在原來的MIDAS基礎(chǔ)上,發(fā)展了DataSnap技術(shù),在很多細(xì)節(jié)方面,它提供了原來MIDAS所沒有的許多功能,使用上更加方便了。
DataSnap主要提供客戶端和中間件之間的通信,不但支持COM+技術(shù)也支持TCP/IP或者CORBA,它們使用類似的界面和方法,其結(jié)果由程序自動完成,這就大大擴充了它的應(yīng)用范圍。
必須要提醒的是,前臺機器上除了應(yīng)用程序以外,還必須把一個MIDAS.DLL文件復(fù)值到前臺機器上,這個文件在服務(wù)器的WINNT\System32目錄下。
4.2 服務(wù)器端程序的建立
服務(wù)器端程序?qū)嶋H上是個COM 工程,它本身連接數(shù)據(jù)源,再通過接口與客戶端聯(lián)系,這個COM 工程必須注冊在服務(wù)器上。
首先建立一個空白的工程,在工程里放置一個Adoconnection組件。然后再建一個遠(yuǎn)程數(shù)據(jù)模塊file -> New -> Other -> Multitier -> Remote Data Module(遠(yuǎn)程數(shù)據(jù)模塊)。 Coclass Name : libserver ,Instancing :執(zhí)行模式,大部分用Multiple Instance(多重實例),Threading Model:線程模式,建議用Apartment(單元),產(chǎn)生一個窗口,在這個窗口里,可以放入數(shù)據(jù)控件。
在Viwe -> Type Libray 中,我們可以看到這個COM 的一些特性。我們也可以記下系統(tǒng)提供的GUID,以備后來使用。加入一個ADOTable,并設(shè)置其指向一個數(shù)據(jù)庫。再設(shè)置一個DataSetProvider(在DataAccess頁)指向ADOTable,這就完成了服務(wù)器端的程序設(shè)計。
保存,編譯,注冊(注意,只要運行就自動在本機注冊了)。
4.3 客戶端程序的建立
在Two-Tier模式中,客戶端(Client)程序是直接和服務(wù)器的數(shù)據(jù)源相連的,而Multi-Tier模式,多個客戶端連接的是一個應(yīng)用程序服務(wù)器,因為收費是按客戶端數(shù)計算的,所以,數(shù)據(jù)庫的使用費用比較低。
1)建立一個普通的工程。
2)放置一個TDCOMConnrction控件(在Datasnap頁),屬性:在本機注冊時,可直接設(shè)置以下屬性:ServerName:應(yīng)用程序服務(wù)器注冊名(server.libserver) ,Connected=true。這時你可以看到服務(wù)器端的COM 程序被激活了。如果在網(wǎng)絡(luò)上調(diào)試,需要給出服務(wù)器名:ComputerName:服務(wù)器名(自動給出網(wǎng)上鄰居)注意: ServerGUID的GUID值是自動給出的。
3)放置一個TClientDataSet控件(在Data Access頁),屬性RemoteServer= DCOMConnrction1,ProviderName:=DataSetProvider1(服務(wù)器端將被激活),Active=true (激活后將能正常連接)
4)放置TDataSource,屬性:Dataset:指向cdsCustomer。
這樣一個客戶端程序就建立好了,其余猶如普通的數(shù)據(jù)庫設(shè)計。
4.4 客戶端實現(xiàn)SQL 查詢
由于在客戶端不存在TQuery控件,似乎客戶服務(wù)器模式是無法做SQL查詢的。但是,Delphi很好的解決了這個問題。事實上,只要客戶端連接上服務(wù)端應(yīng)用程序,客戶端的TClientDataSet就包含了一個名字為Provider的屬性,對應(yīng)到服務(wù)器端DataSetProvider的所有默認(rèn)屬性和方法,其中DataSetProvider有一個Options屬性,只要讓其中的poAllowCommandText=true, 那么,DataSetProvider的poAllowCommandText就可以接受前臺來的SQL 命令,并傳送給TQuery。
可以看出,真正傳遞數(shù)據(jù)的是DataSetProvider的接口,所以,用這個接口搭建傳遞SQL 的橋梁是必需的?蛻舳诉M行SQL 查詢的方法是:
ClientDataSet.Close;
ClientDataSet.CommandText := 'SQL語句';
ClientDataSet.Open;
4.5 動態(tài)連接應(yīng)用程序服務(wù)器的實現(xiàn)
客戶端程序在運行時,需要連接應(yīng)用服務(wù)器程序以取得服務(wù)。但是,在系統(tǒng)實際應(yīng)用的時候,運行應(yīng)用服務(wù)器程序的計算機是經(jīng)常改變的,因此在客戶端程序啟動時,應(yīng)該先找到運行應(yīng)用服務(wù)器程序的計算機的設(shè)置。動態(tài)連接應(yīng)用服務(wù)器的流程類似于12.3節(jié)的動態(tài)數(shù)據(jù)庫連接,動態(tài)連接應(yīng)用服務(wù)器程序的流程圖14-1所示。
掌握了動態(tài)連接應(yīng)用服務(wù)器的流程,就可以具體實現(xiàn)它。下面就將分步驟介紹動態(tài)連接應(yīng)用服務(wù)器的實現(xiàn)過程。
在Delphi中新建一個窗體,將單元文件保存為connect.pas窗體的Name屬性設(shè)為fm_serconfig,Caption屬性設(shè)為”服務(wù)器配置”,運行后窗體如下圖所示。
(2) 在“連接設(shè)置”窗體中,需要輸入應(yīng)用服務(wù)器主機名(或者應(yīng)用服務(wù)器IP地址)和應(yīng)用服務(wù)器的端口號,這些配置信息將用來連接應(yīng)用服務(wù)器。如果連接成功,輸入的配置信息將被寫入到注冊表中,以后程序啟動時,讀取注冊表配置信息,就可而已連接應(yīng)用服務(wù)器程序了。程序的具體實現(xiàn)部分如程序清單如下所示。
procedure BitBtn1Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
procedure WriteToReg(const bappHost,bappIp,aPort:string);
{ Private declarations }
public
{ Public declarations }
end;
var
fm_SerConfig: Tfm_SerConfig; Connected: boolean= false; //代表是否連接成功
implementation
uses netlist, data;
{$R *.dfm}
procedure Tfm_SerConfig.BitBtn1Click(Sender: TObject);
begin
if ((Edt_host.Text='') or (Edt_host.Text=null))
and((Edt_ip.Text='') or (Edt_host.Text=null)) then
begin
application.MessageBox('請輸入服務(wù)器和IP','輸入錯誤',
mb_iconinformation + mb_defbutton1);
exit;
end;
try
strtoint(edt_Port.text);
except
Application.MessageBox('請輸入正確的端口號', '輸入錯誤..', mb_iconinformation + mb_defbutton1);
exit;
end;
statusbar1.Panels[0].Text:='正在連接服務(wù)器,pleale wait';
statusbar1.Refresh;
screen.Cursor:=crHourGlass;
fm_data.Socket.Connected:=false;
fm_data.Socket.Host:=edt_host.Text;
fm_data.Socket.Address:=edt_ip.Text;
fm_data.Socket.Port:=strtoint(edt_port.Text);
try
screen.Cursor:=crdefault;
fm_data.Socket.Connected:=true;
application.MessageBox('連接成功','圖書管理系統(tǒng)', mb_iconinformation + mb_defbutton1);
connected:=true;
except
screen.Cursor:=crdefault;
application.MessageBox('連接失敗','圖書管理系統(tǒng)',mb_iconinformation+mb_defbutton1);
connected:=false;
end;
//連接成功向注冊表里寫入應(yīng)用服務(wù)器配置信息
WriteToReg(edt_Host.Text, edt_IP.Text, edt_Port.Text);
close;
end;
//利用可視化窗體來選擇計算機
procedure Tfm_SerConfig.Button1Click(Sender: TObject);
begin
edt_ip.Clear;
edt_host.Text:= NetExecute(TFm_NetList);
end;
//把信息寫入注冊表
procedure Tfm_SerConfig.WriteToReg(const bappHost,bappIp,aPort:string);
var
reg:Tregistry;
begin
reg:=Tregistry.Create;
reg.RootKey:=HKEY_LOCAL_MACHINE;
if not reg.OpenKey('\Software\pz',false) then //如果可以創(chuàng)建目錄
begin
reg.CreateKey('\Software\pz');
reg.OpenKey('\Software\pz',false);
end;
reg.WriteString('host',bapphost);
reg.WriteString('ip',bappip);
reg.WriteString('port',aport);
reg.Free;
end;
end.
打開“連接設(shè)置”配置窗口,在打開窗體之前,函數(shù)已經(jīng)將布爾變量Connected設(shè)為False,而在窗體被關(guān)閉之后,將返回Connected變量的值,根據(jù)布爾變量Connected的值可以判斷是否已經(jīng)連接上應(yīng)用服務(wù)器。
(3) 在連接設(shè)置主窗口中,我們?yōu)閼?yīng)用服務(wù)器名提供了輔助錄入的方法,點擊應(yīng)用服務(wù)器名編輯框右邊的省略號按鈕(Button1),將彈出一個瀏覽局域網(wǎng)計算機的對話框,以方便用戶選擇應(yīng)用服務(wù)器所在的計算機。在此我們調(diào)用了一個NetExecute方法,它將返回用戶選中的計算機的主機名。這個方法是如何實現(xiàn)的呢?下面將介紹NetExecute方法的實現(xiàn)過程。
在Delphi中新建一個窗體,將窗體單元文件保存為netlist .pas,窗體的Name屬性設(shè)為Fm_netlist。運行后窗體如下圖所示。
在列舉網(wǎng)絡(luò)資源窗體中,將按照工作組以樹型目錄的形式顯示局域網(wǎng)中的計算機。程序的具體實現(xiàn)部分如下所示。
procedure FormActivate(Sender: TObject);
procedure TreeView1Click(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
private
procedure getcomputername;
procedure getgroupname;
{ Private declarations }
public
{ Public declarations }
end;
function NetExecute(aFormClass: TFormClass): string;
var
fm_NetList: Tfm_NetList;
node: Ttreenode;
aComputerName : string;//全局變量,存儲選中的主機名
implementation
{$R *.dfm}
//打開窗體,并返回選定的計算機
function NetExecute(aFormClass: TFormClass): string;
begin
aComputerName := '';
with aFormClass.Create(Application) do
begin
try
showModal;
finally
free;
end;
result := aComputerName;
end;
end;
procedure TFm_netlist.FormActivate(Sender: TObject);
begin
node:=treeview1.items.add(Treeview1.topitem, '整個網(wǎng)絡(luò)');
node.imageindex:=0;
treeview1.setfocus;
end;
procedure TFm_netlist.TreeView1Click(Sender: TObject);
begin
if treeview1.Selected.Level=0 then
begin
if treeview1.Selected.Count=0 then
//添加工作組名
getgroupname();
end;
if treeview1.Selected.Level=1 then
begin
if treeview1.Selected.Count=0 then
//添加計算機名
getcomputername;
end;
if treeview1.Selected.Level=2 then
bitbtn1.Enabled:=true
else
bitbtn1.Enabled:=false;
end;
//取得計算機名
procedure Tfm_netlist.getcomputername;
var
NetResource: TNetResource;
Buf: Pointer;
Count, BufSize, Res: DWord;
Ind: Integer;
lphEnum: THandle;
Temp: TNetResourceArray;
groupname: string;
my_node: Ttreenode;
my_node_2: Ttreenode;
begin
screen.Cursor := crHourGlass;
statusbar.panels[0].text := '正在列舉組名...,請稍侯';
statusbar.refresh;
my_node := treeview1.Selected;
groupname := treeview1.Selected.Text;
FillChar(NetResource, SizeOf(NetResource), 0); //初始化網(wǎng)絡(luò)層次信息
NetResource.lpRemoteName := @GroupName[1]; //指定工作組名稱
NetResource.dwDisplayType := RESOURCEDISPLAYTYPE_SERVER; //類型為服務(wù)器(工作組)
NetResource.dwUsage := RESOURCEUSAGE_CONTAINER;
NetResource.dwScope := RESOURCETYPE_DISK; //列舉文件資源信息
//獲取指定工作組的網(wǎng)絡(luò)資源句柄
Res := WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK,
RESOURCEUSAGE_CONTAINER, @NetResource, lphEnum);
if Res <> NO_ERROR then Exit; //執(zhí)行失敗
while True do //列舉指定工作組的網(wǎng)絡(luò)資源
begin
Count := $FFFFFFFF; //不限資源數(shù)目
BufSize := 8192; //緩沖區(qū)大小設(shè)置為8K
GetMem(Buf, BufSize); //申請內(nèi)存,用于獲取工作組信息
//獲取計算機名稱
Res := WNetEnumResource(lphEnum, Count, Pointer(Buf), BufSize);
if Res = ERROR_NO_MORE_ITEMS then break; //資源列舉完畢
if (Res <> NO_ERROR) then Exit; //執(zhí)行失敗
Temp := TNetResourceArray(Buf);
for Ind := 0 to Count - 1 do //列舉工作組的計算機名稱
begin
//獲取工作組的計算機名稱,+2表示刪除"\\",如
my_node_2 := treeview1.Items.AddChild(my_node, Temp^.lpRemoteName + 2);
my_node_2.imageindex := 2;
Inc(Temp);
end;
end;
Res := WNetCloseEnum(lphEnum); //關(guān)閉一次列舉
if Res <> NO_ERROR then exit; //執(zhí)行失敗
FreeMem(Buf);
screen.Cursor := crDefault;
statusbar.panels[0].text := '';
statusbar.refresh;
end;
//獲取組名
procedure Tfm_NetList.GetGroupName;
var
NetResource: TNetResource;
Buf: Pointer;
Count, BufSize, Res: DWORD;
lphEnum: THandle;
p: TNetResourceArray;
i, j: SmallInt;
NetworkTypeList: TList;
my_node_1: Ttreenode;
begin
statusbar.panels[0].text := '正在列舉域名...,請稍侯';
statusbar.refresh;
screen.Cursor := crHourGlass;
NetworkTypeList := TList.Create;
//獲取整個網(wǎng)絡(luò)中的文件資源的句柄,lphEnum為返回名柄
Res := WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK,
RESOURCEUSAGE_CONTAINER, nil, lphEnum);
if Res <> NO_ERROR then exit; //執(zhí)行失敗
//獲取整個網(wǎng)絡(luò)中的網(wǎng)絡(luò)類型信息
Count := $FFFFFFFF; //不限資源數(shù)目
BufSize := 8192; //緩沖區(qū)大小設(shè)置為8K
GetMem(Buf, BufSize); //申請內(nèi)存,用于獲取工作組信息
Res := WNetEnumResource(lphEnum, Count, Pointer(Buf), BufSize);
if (Res = ERROR_NO_MORE_ITEMS) //資源列舉完畢
or (Res <> NO_ERROR) //執(zhí)行失敗
then Exit;
P := TNetResourceArray(Buf);
for I := 0 to Count - 1 do //記錄各個網(wǎng)絡(luò)類型的信息
begin
NetworkTypeList.Add(p);
Inc(P);
end;
//WNetCloseEnum關(guān)閉一個列舉句柄
Res := WNetCloseEnum(lphEnum); //關(guān)閉一次列舉
if Res <> NO_ERROR then exit;
for J := 0 to NetworkTypeList.Count - 1 do //列出各個網(wǎng)絡(luò)類型中的所有工作組名稱
begin //列出一個網(wǎng)絡(luò)類型中的所有工作組名稱
NetResource := TNetResource(NetworkTypeList.Items[J]^); //網(wǎng)絡(luò)類型信息
//獲取某個網(wǎng)絡(luò)類型的文件資源的句柄,NetResource為網(wǎng)絡(luò)類型信息,lphEnum為返回名柄
Res := WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK,
RESOURCEUSAGE_CONTAINER, @NetResource, lphEnum);
if Res <> NO_ERROR then break; //執(zhí)行失敗
while true do //列舉一個網(wǎng)絡(luò)類型的所有工作組的信息
begin
Count := $FFFFFFFF; //不限資源數(shù)目
BufSize :=8192; //緩沖區(qū)大小設(shè)置為8K
GetMem(Buf, BufSize); //申請內(nèi)存,用于獲取工作組信息
//獲取一個網(wǎng)絡(luò)類型的文件資源信息,
Res := WNetEnumResource(lphEnum, Count, Pointer(Buf), BufSize);
if (Res = ERROR_NO_MORE_ITEMS) //資源列舉完畢
or (Res <> NO_ERROR) //執(zhí)行失敗
then break;
P := TNetResourceArray(Buf);
for I := 0 to Count - 1 do //列舉各個工作組的信息
begin
my_node_1 := treeview1.Items.addchild(node, StrPAS(P^.lpRemoteName)); //取得一個工作組的名稱
my_node_1.imageindex := 1;
Inc(P);
end;
end;
Res := WNetCloseEnum(lphEnum); //關(guān)閉一次列舉
if Res <> NO_ERROR then break; //執(zhí)行失敗
end;
FreeMem(Buf);
NetworkTypeList.Destroy;
screen.Cursor := crDefault;
statusbar.panels[0].text := '';
statusbar.refresh;
end;
procedure TFm_netlist.BitBtn1Click(Sender: TObject);
begin
aComputerName := treeview1.Selected.Text;
close;
end;
end.
在上面的程序清單中,首先定義了NetExecute方法,它根據(jù)傳遞進來的TFormClass參數(shù)值TformNet,打開“列舉網(wǎng)絡(luò)資源”窗口,用戶可以在此窗口中選擇想要連接的運行應(yīng)用服務(wù)器程序的計算機。NetExecute方法將返回選中的計算機主機名。
在程序清單中,還自定義了GetGroupName和GetComputerName這兩個非常重要的過程,其中GetGroupName方法用于獲取網(wǎng)絡(luò)中所有的工作組名稱,并將工作組名添加到目錄樹的第二級目錄中;GetComputerName方法則根據(jù)工作組的名稱窮舉工作組下的計算機,并將這些計算機添加到目錄樹的第三級目錄中。
選擇好計算機后,單擊“確定”按鈕,系統(tǒng)將把選定的計算機主機名賦給aComputerName全局變量,此時在NetExecute方法中,便返回此值。
(4) 在data單元(data.pas)中定義connect_app方法。connect_app方法用語讀取注冊表中配置應(yīng)用服務(wù)器的信息并測試連接,如果沒有連接上應(yīng)用程序服務(wù)器將從新彈出配置窗口。這個接口方法在程序主窗體創(chuàng)建時被調(diào)用,用以嘗試連接應(yīng)用服務(wù)器。
ConnectAppServ方法在interface中的具體定義為:
function TFm_data.connect_app: boolean; //判斷是否連接上了應(yīng)用服務(wù)器
var
vs_Host, vs_Address, vs_Port: string;
reg: TRegistry;
begin
Result := True;
reg := Tregistry.create;
Reg.RootKey := HKEY_LOCAL_MACHINE;
socket.Connected := false;
//讀取注冊表配置的應(yīng)用服務(wù)器信息
if Reg.OpenKey('\Software\pz', False) then //如果注冊表有信息
begin
vs_Host := reg.ReadString('Host');
vs_Address := reg.ReadString('ip');
vs_Port := reg.readstring('Port');
try
//測試連接
socket.Address := vs_Address;
socket.Host := vs_Host;
socket.Port := strtoint(vs_Port);
socket.Connected := true;
reg.closekey;
except //未連接上,彈出配置窗口
reg.closekey;
try
fm_SerConfig := Tfm_serconfig.create(self);
fm_SerConfig.showmodal;
finally
fm_SerConfig.free;
end;
end;
end
else //如果沒有信息 彈出配置窗口
begin
try
fm_SerConfig := Tfm_SerConfig.create(self);
fm_SerConfig.showmodal;
finally
fm_SerConfig.free;
end;
end;
end;
在此過程里,將主要讀取鍵為“HKEY_LOCAL_MACHINE\SOFTWARE\PZ”目錄下的應(yīng)用服務(wù)器主機名,應(yīng)用服務(wù)器IP地址和端口號的值,然后將這些值賦給主窗體的SocketConnection組件以測試連接。如果連接成功就返回True值,如果連接失敗,將彈出“連接設(shè)置“窗口,用戶需要從新輸入應(yīng)用服務(wù)器主機名,應(yīng)用服務(wù)器IP地址和端口號。如果仍然連接失敗,就返回False值,表示連接失敗。
(5) 動態(tài)連接設(shè)置的最后一個步驟就是在主窗體被創(chuàng)建時,調(diào)用第4步中自定義的Imyserver_autho方法,判斷應(yīng)用程序是否連接上了應(yīng)用服務(wù)器。如果連接成功,將進入應(yīng)用程序;如果連接失敗,將退出應(yīng)用程序。
至此,動態(tài)連接應(yīng)用服務(wù)器就做完了。
4.6 圖書管理功能的實現(xiàn)
圖書管理系統(tǒng)需要滿足來自三方面的需求,這三個方面分別是圖書借閱者、圖書館工作人員和圖書館管理人員。圖書借閱者的需求是查詢圖書館所存的圖書、個人借閱情況及個人信息的修改;圖書館工作人員對圖書借閱者的借閱及還書要求進行操作,同時形成借書或還書報表給借閱者查看確認(rèn);圖書館管理人員的功能最為復(fù)雜,包括對工作人員、圖書借閱者、圖書進行管理和維護,及系統(tǒng)狀態(tài)的查看、維護并生成催還圖書報表。 圖書借閱者可直接查看圖書館圖書情況,如果圖書借閱者根據(jù)本人借書證號和密碼登錄系統(tǒng),還可以進行本人借書情況的查詢和維護部分個人信息。一般情況下,圖書借閱者只應(yīng)該查詢和維護本人的借書情況和個人信息,若查詢和維護其他借閱者的借書情況和個人信息,就要知道其他圖書借閱者的借書證號和密碼。這些是很難得到的,特別是密碼,所以不但滿足了圖書借閱者的要求,還保護了圖書借閱者的個人隱私。 圖書館工作人員有修改圖書借閱者借書和還書記錄的權(quán)限,所以需對工作人員登陸本模塊進行更多的考慮。在此模塊中,圖書館工作人員可以為圖書借閱者加入借書記錄或是還書記錄,并打印生成相應(yīng)的報表給用戶查看和確認(rèn)。 在本系統(tǒng)中由于沒有打印機設(shè)備供試驗,所以沒有制作打印模塊。本系統(tǒng)提供的功能有 1. 設(shè)計不同用戶的操作權(quán)限和登陸方法 2. 對所有用戶開放的圖書查詢 3. 借閱者維護借閱者個人部分信息 4. 借閱者查看個人借閱情況信息 5. 維護借閱者個人密碼 6. 查詢及統(tǒng)計各種信息 7 . 維護圖書信息 8. 維護借閱者信息 9. 對借閱過期的圖書進行通知
第五部分 畢業(yè)設(shè)計心得體會及結(jié)論
在蘇綠園老師的指導(dǎo)下。本次畢業(yè)設(shè)計,就要畫上一個句號了?墒,對我來說,這次設(shè)計的本身所產(chǎn)生的影響,還遠(yuǎn)遠(yuǎn)沒有結(jié)束,我從本次畢業(yè)設(shè)計中學(xué)到了許多課本上沒有的知識。從設(shè)計任務(wù)書的下達(dá)到今天基本實現(xiàn)任務(wù)書中的設(shè)計要求,時間已整整過去了兩個月。在這兩個月中。通過自己的學(xué)習(xí)和努力;通過各位老師的指導(dǎo)和教育,使我不僅僅在知識水平和解決實際問題的能力上有了很大的提高。還從思想的深處體會到,要把自己的所學(xué)變成現(xiàn)實時所將面對的種種難題。
由于我平時的課程理論知識學(xué)的還可以,我總是認(rèn)為自己的知識水平已經(jīng)能處理許多的現(xiàn)實問題了。而當(dāng)自己真正的深入到設(shè)計實踐當(dāng)中,深入到問題當(dāng)中時。我竟然發(fā)現(xiàn)自己無從下手,我開始懷疑我是否真正的學(xué)到了知識。也只有到了那個時候,我才真正體會到學(xué)會運用自己的能力與知識是何等的重要,知識是在課堂上,老師教授的,在書本中學(xué)到的,實踐則是要自己動手,自己去做才能掌握。
在老師們的關(guān)心和幫助下,我漸漸的開始了設(shè)計。根據(jù)老師的建議,我找來了數(shù)據(jù)庫設(shè)計與建設(shè)的相關(guān)書籍和資料,從最基本的問題入手開始一個個的解決我心中的疑惑。 這是一個漫長的學(xué)習(xí)過程。隨著時間的推移,我開始慢慢的掌握了設(shè)計時所需要的知識。我也終于明白了大學(xué)三年學(xué)習(xí)的意義和作用。扎實的基本功和良好的學(xué)習(xí)習(xí)慣,能使自己在學(xué)習(xí)新知識有更深刻的認(rèn)識力和更快的領(lǐng)會力。
同時老師對畢業(yè)設(shè)計的重視也是我能完成設(shè)計的一個重要條件。為了保證我們畢業(yè)設(shè)計的正常進行,學(xué)院抽調(diào)了優(yōu)秀的老師指導(dǎo)我們進行畢業(yè)設(shè)計,提供良好的設(shè)備給我們,在軟硬件上支持我們進行畢業(yè)設(shè)計,并且不時地詢問我們畢業(yè)設(shè)計的進展情況。為我們這次設(shè)計的正常開展提供了必要的物質(zhì)基礎(chǔ)。
關(guān)于本次設(shè)計的命題,我的設(shè)計只能提供其基本的功能。還有許多的設(shè)想由于時間和自身和因素?zé)o法得以實現(xiàn),這不能不說是本次設(shè)計的遺憾之處。不過,至少它已經(jīng)啟發(fā)了自己的思維,提高了我的動手能力,這是我在課本中學(xué)不到的。它為我們在以后的工作崗位上發(fā)揮自己的才能奠定了堅實的基礎(chǔ)。
第六部分 附錄
6.1參考資料
《軟件工程》 陸惠恩 陸培恩 主編 電子工業(yè)出版社 2004年
《delphi高級程序員認(rèn)證教材》 北京科海培訓(xùn)中心 Delphi主講教師:謝新華
《SQL Server2000數(shù)據(jù)庫及應(yīng)用基礎(chǔ)》徐人鳳 曾建華 主編 高等教育現(xiàn)版社 2004年
《Delphi 6深度編程及其應(yīng)用開發(fā)》 李存斌 汪兵 編著 中國水利水電出版社 2002年
【分布式多層數(shù)據(jù)庫系統(tǒng)的應(yīng)用(一)】相關(guān)文章:
分布式發(fā)電系統(tǒng)的應(yīng)用及前景03-18
關(guān)于分布式發(fā)電系統(tǒng)的應(yīng)用及前景11-23
分布式對象技術(shù)及其在Web上的應(yīng)用03-18
PowerBuilder的分布式計算技術(shù)及其應(yīng)用03-18
用RMI開發(fā)基于Java的企業(yè)分布式應(yīng)用03-19
多層螺旋CT不同成像方法在腦血管成像中的應(yīng)用03-16