三層體系結(jié)構(gòu)_第1頁
三層體系結(jié)構(gòu)_第2頁
三層體系結(jié)構(gòu)_第3頁
三層體系結(jié)構(gòu)_第4頁
三層體系結(jié)構(gòu)_第5頁
已閱讀5頁,還剩29頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、三層體系結(jié)構(gòu)與數(shù)據(jù)庫編程接要 本文主要介紹了基于三層體系結(jié)構(gòu)的網(wǎng)絡(luò)數(shù)據(jù)庫設(shè)計(jì),并結(jié)合面向?qū)ο螅植际綌?shù)據(jù)庫開發(fā)等理論。全文圍繞一個(gè)典型而簡單的例子,通過VB編程語言,從分析、建模、設(shè)計(jì)、編碼等各個(gè)角度對三層體系與數(shù)據(jù)庫進(jìn)行了全面而詳細(xì)的闡述,文中提供了全部源代碼。關(guān)鍵詞 三層體系 數(shù)據(jù)庫 面向?qū)ο?分布式開發(fā)1. 三層體系結(jié)構(gòu)我們經(jīng)常會(huì)看到許多應(yīng)聘者在簡歷上寫著“精通數(shù)據(jù)庫編程”的字樣,也經(jīng)常會(huì)在招聘網(wǎng)站上看到軟件公司的招聘要求中某一項(xiàng)為“精通數(shù)據(jù)庫編程”。于是這些應(yīng)聘者去這些軟件公司面試,于是我們看到了許多“精通”者落選的現(xiàn)象。一些程序員在設(shè)計(jì)數(shù)據(jù)庫應(yīng)用時(shí),通常會(huì)采用數(shù)據(jù)控件綁定的方法實(shí)現(xiàn)。

2、用鼠標(biāo)拉幾個(gè)控件,再用鼠標(biāo)設(shè)置幾個(gè)屬性,連鍵盤都不用動(dòng),就完成了一個(gè)數(shù)據(jù)庫應(yīng)用的開發(fā)!當(dāng)然,這的確是一種快速的數(shù)據(jù)庫應(yīng)用開發(fā)方式,但快速并不意味著精通。對于大型的數(shù)據(jù)庫應(yīng)用系統(tǒng),或是擁有眾多客戶端的應(yīng)用系統(tǒng),我們需要另外一種“精通”,這就是幾乎每個(gè)程序員都聽說過的“三層體系結(jié)構(gòu)”。1.1. 傳統(tǒng)的C/S模式在傳統(tǒng)的數(shù)據(jù)庫應(yīng)用體系中,客戶端與數(shù)據(jù)庫完全分開,在客戶端上運(yùn)行了大部分服務(wù),如數(shù)據(jù)訪問規(guī)則、業(yè)務(wù)規(guī)則、合法性校驗(yàn)等等。每一個(gè)客戶端都存在數(shù)據(jù)引擎,并且每個(gè)客戶端與數(shù)據(jù)庫服務(wù)器建立獨(dú)立的數(shù)據(jù)庫連接(DB Connection)?;谠摲N體系的數(shù)據(jù)庫應(yīng)用系統(tǒng)的優(yōu)勢:開發(fā)周期較短,能夠適應(yīng)大部分

3、中小型數(shù)據(jù)庫應(yīng)用系統(tǒng)的要求(當(dāng)客戶端數(shù)量少于50時(shí))。但是,隨著數(shù)據(jù)庫應(yīng)用的日漸發(fā)展、數(shù)據(jù)容量的不斷增加、客戶端數(shù)量的不斷增加,該種體系結(jié)構(gòu)顯示出了諸多缺陷,主要體現(xiàn)在以下幾個(gè)方面:1、 可擴(kuò)充性:對于數(shù)據(jù)庫服務(wù)器端,每當(dāng)建立一個(gè)數(shù)據(jù)連接,就會(huì)占用大量的系統(tǒng)資源,當(dāng)數(shù)據(jù)連接達(dá)到一定數(shù)量(如20個(gè))時(shí),數(shù)據(jù)庫服務(wù)器的響應(yīng)速度與處理速度將大打折扣。2、 可維護(hù)性:基于傳統(tǒng)C/S的數(shù)據(jù)庫應(yīng)用系統(tǒng),業(yè)務(wù)規(guī)則通常置于客戶端應(yīng)用程序中。如果業(yè)務(wù)規(guī)則一旦發(fā)生變化(隨便舉個(gè)例子,如身份證號碼有可能升為19位)時(shí),我們就必須修改客戶端應(yīng)用程序,并且將每個(gè)客戶端進(jìn)行相應(yīng)的升級工作。3、 可重用性:采用傳統(tǒng)C/S的

4、設(shè)計(jì)模式時(shí),數(shù)據(jù)庫訪問、業(yè)務(wù)規(guī)則等都固化在客戶端應(yīng)用程序中。如果客戶另外提出了B/S的應(yīng)用需求,則需要在WEB服務(wù)器中重新進(jìn)行數(shù)據(jù)庫訪問、業(yè)務(wù)規(guī)則、合法性校驗(yàn)等編碼(例如將數(shù)據(jù)庫訪問寫入ASP代碼),而所做的工作與客戶端應(yīng)用程序中的功能完全重復(fù),從而加大了工作量,又使得程序開發(fā)者心里感到極不舒服。正因?yàn)橐陨系闹T多缺陷,使得三層(多層)體系結(jié)構(gòu)成為目前數(shù)據(jù)庫應(yīng)用開發(fā)的首選,甚至客戶有時(shí)也會(huì)提出該種技術(shù)需求。1.2. 三層體系結(jié)構(gòu)所謂三層體系結(jié)構(gòu),是在客戶端與數(shù)據(jù)庫之間加入了一個(gè)“中間層”,也叫組件層。這里所說的三層體系,不是指物理上的三層,不是簡單地放置三臺機(jī)器就是三層體系結(jié)構(gòu),也不僅僅有B/S

5、應(yīng)用才是三層體系結(jié)構(gòu),三層是指邏輯上的三層,即使這三個(gè)層放置到一臺機(jī)器上。三層體系的應(yīng)用程序?qū)I(yè)務(wù)規(guī)則、數(shù)據(jù)訪問、合法性校驗(yàn)等工作放到了中間層進(jìn)行處理。通常情況下,客戶端不直接與數(shù)據(jù)庫進(jìn)行交互,而是通過COM/DCOM通訊與中間層建立連接,再經(jīng)由中間層與數(shù)據(jù)庫進(jìn)行交互。這樣的好處顯而易見:1、 由于數(shù)據(jù)訪問是通過中間層進(jìn)行的,因此客戶端不再與數(shù)據(jù)庫直接建立數(shù)據(jù)連接。也就是說,建立在數(shù)據(jù)庫服務(wù)器上的連接數(shù)量將大大減少。例如一個(gè)500個(gè)客戶端的應(yīng)用系統(tǒng),500個(gè)客戶端分別與中間層服務(wù)器建立DCOM連接,而DCOM通訊所占用的系統(tǒng)資源極為有限,并且是動(dòng)態(tài)建立與釋放連接,因此客戶端數(shù)量將不再受到限制。

6、同時(shí),中間層與數(shù)據(jù)庫服務(wù)器之間的數(shù)據(jù)連接通過“連接池”進(jìn)行連接數(shù)量的控制,動(dòng)態(tài)分配與釋放數(shù)據(jù)連接,因此數(shù)據(jù)連接的數(shù)量將遠(yuǎn)遠(yuǎn)小于客戶端數(shù)量。2、 可維護(hù)性得以提高。因?yàn)闃I(yè)務(wù)規(guī)則、合法性校驗(yàn)存在于中間層,因此當(dāng)業(yè)務(wù)規(guī)則發(fā)生改變時(shí),只需更改中間層服務(wù)器上的某個(gè)組件(如某個(gè)DLL文件),而客戶端應(yīng)用程序不需做任何處理,有些時(shí)候,甚至不必修改中間層組件,只需要修改數(shù)據(jù)庫中的某個(gè)存儲(chǔ)過程就可以了。3、 良好的可重用性。同樣,如果需要開發(fā)B/S應(yīng)用,則不必要重新進(jìn)行數(shù)據(jù)訪問、業(yè)務(wù)規(guī)則等的開發(fā),可以直接在WEB服務(wù)器端調(diào)用現(xiàn)有的中間層(如可以采用基于IIS的WebClass開發(fā),或直接編寫ASP代碼)。4、

7、事務(wù)處理更加靈活,可以在數(shù)據(jù)庫端、組件層、MTS(或COM+)管理器中進(jìn)行事務(wù)處理。如果現(xiàn)在你仍然感到不理解,沒關(guān)系,請看下面的例子。2. 簡單的人事管理系統(tǒng)下面以一個(gè)極為簡單的人事管理系統(tǒng)為例詳細(xì)講述如何實(shí)現(xiàn)三層體系結(jié)構(gòu)。編程語言為Visual Basic 6.0。為了全面介紹程序設(shè)計(jì)方法,VB代碼中采用了不同的方法實(shí)現(xiàn)相同的功能,如數(shù)據(jù)庫訪問中,同時(shí)采用了存儲(chǔ)過程與ADO連接。讀者可自行選擇最適合的方法。由于在代碼中加入了大量注釋,因此不再過多地說明函數(shù)功能與原理。在團(tuán)隊(duì)開發(fā)中,代碼中注釋部分應(yīng)占整個(gè)代碼的1/3左右,而且應(yīng)在代碼編寫前就寫好注釋。如果另一個(gè)程序員認(rèn)為你的代碼中注釋全部是廢

8、話,那么這些注釋肯定是在寫完代碼之后才加上去的!2.1. 需求簡單的部門/人員管理系統(tǒng),要求:1、 部門的屬性有部門名稱,人員的屬性有姓名、年齡、性別;2、 部門存在上下級關(guān)系;3、 人員必須屬于一個(gè)部門;4、 人員、部門需要實(shí)現(xiàn)增加、刪除、修改功能5、 可以按人員的名稱、年齡查詢?nèi)藛T6、 如果一個(gè)部門存在人員,或存在下級部門,則該部門不可刪除以上即為系統(tǒng)的簡單需求。2.2. 數(shù)據(jù)庫數(shù)據(jù)庫采用SQL Server 7設(shè)計(jì),數(shù)據(jù)庫名稱為“TEST”,存在兩個(gè)數(shù)據(jù)表(此處假設(shè)讀者已掌握數(shù)據(jù)庫設(shè)計(jì),因?yàn)檫@個(gè)數(shù)據(jù)庫實(shí)在太簡單了)。表tDept字段名稱類型nIDIntDeptNameChar(50)Su

9、perID InttEmployee字段名稱類型nIDIntDeptIDIntEmpNameChar(10)EmpAgeSmallintEmpGenderBit其中,tDept中nID與SuperID為表內(nèi)關(guān)聯(lián)。2.3. 中間層打開VB6,選擇“新建ActiveX DLL”,并引用ADO 2.5。新添加一個(gè)模塊,命名為mdlPublic,新填加5個(gè)類,分別命名為cDept、cEmp、cDepts、cEmps、cPublic。其中,cEmps與cDepts分別為cEmp與cDept的集合類,cPublic為定義枚舉的類,無實(shí)際意義。將工程的啟動(dòng)模塊設(shè)為“Sub Main”(重要!)。在SQL S

10、erver的TEST庫中,添加一個(gè)存儲(chǔ)過程AddDept。全部代碼如下:2.3.1. mdlPublic.basOption ExplicitPublic g_Cn As Connection 用于全局的數(shù)據(jù)連接ActiveX DLL的啟動(dòng)程序,為DLL初始化時(shí)執(zhí)行Public Sub Main() If ConnectToDatabase = False Then Err.Raise vbObjectError + 1, , 連接數(shù)據(jù)庫出錯(cuò)! End IfEnd Sub連接到數(shù)據(jù)庫Public Function ConnectToDatabase() As Boolean On Error

11、GoTo ERR_CONN Set g_Cn = New Connection 設(shè)置服務(wù)器名稱,數(shù)據(jù)庫名稱,登錄名(此時(shí)假設(shè)密碼為空) Dim ServerName As String, DBName As String, UserName As String ServerName = gxc-notepad DBName = TEST UserName = sa 連接到數(shù)據(jù)庫 With g_Cn .CursorLocation = adUseClient .CommandTimeout = 10 .ConnectionString = Provider=SQLOLEDB.1;Persist

12、Security Info=True;User ID= & UserName & ;Initial Catalog= & DBName & ;Data Source= & ServerName .Open End With ConnectToDatabase = True Exit FunctionERR_CONN: ConnectToDatabase = FalseEnd Function去掉字符串中的單引號Public Function RealString(strOrigional) As String RealString = Replace(strOrigional, , )End

13、Function得到某個(gè)數(shù)據(jù)表中主鍵的下一個(gè)值,即當(dāng)前主鍵值加1Public Function NextID(ByVal strTable As String, ByVal strID As String) As Long 兩個(gè)參數(shù)分別是表的名稱與主鍵的名稱 Dim rs As Recordset Set rs = g_Cn.Execute(SELECT MAX( & strID & ) FROM & strTable) If IsNull(rs(0) Then 如果值為NULL,則說明無任何數(shù)據(jù)記錄,此時(shí)ID應(yīng)為1 NextID = 1 Else 使新ID為最大ID值+1 NextID =

14、rs(0).Value + 1 End IfEnd Function查看某個(gè)數(shù)據(jù)表中,是否存在某個(gè)字段等于某個(gè)值的記錄(整型)Public Function ExistByID(ByVal strTable As String, ByVal strID As String, ByVal lngID As Long) As Boolean 第一個(gè)參數(shù)為表名,第二個(gè)為字段名,第三個(gè)為具體的字段值 Dim rs As Recordset Set rs = g_Cn.Execute(Select Count(*) from & strTable & where & strID & = & lngID)

15、 ExistByID = (rs(0).Value = 1)End Function查看某個(gè)數(shù)據(jù)表中,是否存在某個(gè)字段等于某個(gè)值的記錄(字符型)Public Function ExistByName(ByVal strTable As String, ByVal strFieldName As String, ByVal strName As String, ByVal ThisID As Long) As Boolean 第一個(gè)參數(shù)為表名,第二個(gè)為字段名,第三個(gè)為具體的字段值 Dim rs As Recordset Set rs = g_Cn.Execute(Select Count(*)

16、from & strTable & where & strFieldName & = & strName & and nID & ThisID) ExistByName = (rs(0).Value = 1)End Function以上兩個(gè)函數(shù)實(shí)際上可以合并,本程序中為了說明問題,故而分開2.3.2. cPublic.clsOption Explicit該類無實(shí)際意義,只為保存一些自定義枚舉自定義枚舉,用于表示性別Public Enum gxcGender Male = 1 Female = 0End Enum以下枚舉用于“部門”對象的操作用于表示部門刪除結(jié)果的枚舉Public Enum gx

17、cDelete DeleteOK = 0 DeleteFail = 1 未知原因?qū)е虏荒軇h除 DeleteSubExists = 2 由于存在子部,因此不能刪除 DeleteEmpExists = 3 該部門存在人員,不能刪除End Enum用于表示部門更新結(jié)果的枚舉Public Enum gxcUpdate UpdateOK = 0 UpdateFail = 1 DuplicateName_Update = 2 名字不可重復(fù) RecordNotExist = 3 當(dāng)前更新的記錄已被其它客戶端刪除End Enum用于表示部門新增結(jié)果的枚舉Public Enum gxcAddNew AddNew

18、OK = 0 AddNewFail = 1 DuplicateName_AddNew = 2 名字不可重復(fù) SuperNotExist = 3 指定的上級部門的ID不存在End Enum2.3.3. cDept.clsOption ExplicitPrivate mvarDeptName As StringPrivate mvarID As LongPrivate mvarSuperID As Long以下為部門的屬性上級部門IDPublic Property Let SuperID(ByVal vData As Long) mvarSuperID = vDataEnd PropertyPub

19、lic Property Get SuperID() As Long SuperID = mvarSuperIDEnd Property本部門的IDPublic Property Let ID(ByVal vData As Long) mvarID = vDataEnd PropertyPublic Property Get ID() As Long ID = mvarIDEnd Property本部門的名稱Public Property Let DeptName(ByVal vData As String) vData = Trim(vData) 去除兩邊的空格 控制名稱的長度不可大于50

20、If Len(vData) 50 Then vData = Left(vData, 50) mvarDeptName = vDataEnd PropertyPublic Property Get DeptName() As String DeptName = mvarDeptNameEnd Property屬性結(jié)束以下為方法新增一個(gè)部門,并返回操作的結(jié)果Public Function AddNew(Optional strName As String = , _ Optional lngSuperID As Long = -1) As gxcAddNew 根據(jù)傳入的參數(shù)更新屬性值 On Err

21、or GoTo ERR_ADDNEW 如果參數(shù)被傳入,則以傳入的參數(shù)更新屬性 If strName Then Me.DeptName = strName If lngSuperID -1 Then Me.SuperID = lngSuperID 上級部門的ID 通過Command對象調(diào)用存儲(chǔ)過程,由存儲(chǔ)過程 進(jìn)行添加部門的操作,并由存儲(chǔ)過程返回操作結(jié)果 Dim cmd As ADODB.Command Set cmd = New ADODB.Command With cmd Set .ActiveConnection = g_Cn .CommandType = adCmdStoredProc

22、設(shè)置Command類型為“存儲(chǔ)過程” .CommandText = AddDept 存儲(chǔ)過程的名稱 傳入兩個(gè)參數(shù),分別為部門的名稱與上級部門的ID .Parameters.Append .CreateParameter(Name, adChar, adParamInput, 50, Me.DeptName) .Parameters.Append .CreateParameter(SuperID, adInteger, adParamInput, , Me.SuperID) 傳入兩個(gè)返回型的參數(shù),分別返回新記錄的ID與操作結(jié)果 .Parameters.Append .CreateParamete

23、r(ID, adInteger, adParamOutput) .Parameters.Append .CreateParameter(Return, adInteger, adParamOutput) .Execute End With Dim RTN As gxcAddNew RTN = cmd.Parameters(Return).Value 得到操作結(jié)果 如果操作成功,則給對象賦以ID值 If RTN = AddNewOK Then Me.ID = cmd.Parameters(ID).Value AddNew = RTN 返回操作結(jié)果 Set cmd = Nothing Exit F

24、unctionERR_ADDNEW: 來到這里,則說明出錯(cuò)了 If Not cmd Is Nothing Then Set cmd = Nothing AddNew = AddNewFailEnd Function修改部門信息,返回操作結(jié)果Public Function Update() As gxcUpdate 通過ID判斷是否存在該記錄,即該記錄是否被其它客戶端刪除 如果不存在該記錄,則返回相應(yīng)的操作結(jié)果給調(diào)用者 If Not ExistByID(tDept, nID, Me.ID) Then Update = RecordNotExist Exit Function End If 通過名

25、稱判斷是否存在相同名稱的記錄,如果存在相同的名稱, 則返回調(diào)用者“存在相同名稱”的信息 If ExistByName(tDept, DeptName, Me.DeptName, Me.ID) Then Update = DuplicateName_Update Exit Function End If On Error Resume Next Dim strSQL As String 構(gòu)造SQL語句,注意需調(diào)用RealString函數(shù)去除字符串中的單引號 strSQL = Update tDept Set DeptName= & RealString(Me.DeptName) & , strS

26、QL = strSQL & SuperID= & IIf(Me.SuperID = 0, null, Me.SuperID) strSQL = strSQL & where nID= & Me.ID g_Cn.Execute strSQL 執(zhí)行SQL語句 根據(jù)是否出錯(cuò),返回給調(diào)用者相應(yīng)的信息 If Err.Number = 0 Then Update = UpdateOK Else Update = UpdateFail End IfEnd Function刪除一個(gè)部門Public Function Delete(Optional ByVal lngID As Long = 0) As gxc

27、Delete 如果調(diào)用該函數(shù)時(shí)傳入了ID,則更新該對象的ID If lngID 0 Then Me.ID = lngID 如果該部門下面有人員,則也不能刪除 If ExistByID(tEmployee, DeptID, Me.ID) Then Delete = DeleteEmpExists Exit Function End If 如果該部門下有子部門,則不能刪除 If ExistByID(tDept, SuperID, Me.ID) Then Delete = DeleteSubExists Exit Function End If On Error Resume Next 執(zhí)行刪除操作

28、并返回操作結(jié)果 g_Cn.Execute Delete from tDept where nID= & Me.ID Delete = IIf(Err.Number = 0, DeleteOK, DeleteFail)End Function得到本部門的所有員工Public Function Employees() As cEmps Dim objEmps As New cEmps 調(diào)用cEmps類的Find方法,只傳第三個(gè)參數(shù),即“部門ID” Set Employees = objEmps.Find(, , Me.ID)End Function得到本部門的所有子部門Public Functio

29、n SubDepartments() As cDepts Dim objDepts As New cDepts 調(diào)用cDepts的Find方法,通過上級部門的ID查找 Set SubDepartments = objDepts.Find(, Me.ID)End Function得到本部門的上級部門,以對象返回Public Function SuperDepartment() As cDept Dim objDepts As New cDepts 調(diào)用cDepts的Find方法,將該類的“SuperID”作為查找條件 從而查找出其上級部門 objDepts.Find Me.SuperID If

30、objDepts.Count 0 Then Set SuperDepartment = objDepts.Item(1)End Function方法結(jié)束2.3.4. cDepts.clsOption ExplicitPrivate mCol As Collection往集合中加入一個(gè)“部門”對象Public Sub Add(objDept As cDept) mCol.Add objDept, A & objDept.ID 在加入對象是,最好同時(shí)加入其“KEY”屬性 “KEY”屬性不可以是數(shù)字型,因此在前面隨便加 一個(gè)字母,此處加了一個(gè)“A”End SubPublic Property Get

31、 Item(vntIndexKey As Variant) As cDept Set Item = mCol(vntIndexKey)End PropertyPublic Property Get Count() As Long Count = mCol.CountEnd PropertyPublic Sub Remove(vntIndexKey As Variant) mCol.Remove vntIndexKeyEnd SubPublic Property Get NewEnum() As IUnknown 本屬性允許用 For.Each 語法枚舉該集合。 Set NewEnum = mC

32、ol._NewEnumEnd Property清除集合中的全部元素Public Sub Clear() 注意!在清除時(shí)必須倒序清除,否則要出錯(cuò)! Dim i As Long For i = mCol.Count To 1 Step -1 mCol.Remove i Next iEnd SubPrivate Sub Class_Initialize() Set mCol = New CollectionEnd SubPrivate Sub Class_Terminate() Set mCol = NothingEnd Sub按條件查找部門,以集合類的方式返回Public Function Fin

33、d(Optional lngID As Long = 0, Optional lngSuperID As Long = -1) As cDepts 按輸入的參數(shù)查詢,并返回一個(gè)集合類 Dim strSQL As String 構(gòu)造SQL語句 strSQL = Select * from tDept where If lngID 0 Then strSQL = strSQL & nID= & lngID & and If lngSuperID -1 Then If lngSuperID = 0 Then 如果傳入0,則表示沒有上級部門 strSQL = strSQL & SuperID is n

34、ull and Else strSQL = strSQL & SuperID= & lngSuperID & and End If End If strSQL = strSQL & nID0 清空當(dāng)前集合 Me.Clear Dim rs As Recordset Set rs = g_Cn.Execute(strSQL) 往集合中添加查詢結(jié)果 Dim i As Long Dim objDept As cDept For i = 1 To rs.RecordCount Set objDept = New cDept With objDept .ID = rs(nID).Value .DeptNa

35、me = Trim(rs(DeptName).Value) .SuperID = IIf(IsNull(rs(SuperID).Value), 0, rs(SuperID).Value) End With Me.Add objDept Set objDept = Nothing rs.MoveNext Next i Set rs = Nothing Set Find = MeEnd Function2.3.5. cEmp.clsOption ExplicitPrivate mvarID As LongPrivate mvarEmpName As StringPrivate mvarEmpAge

36、 As IntegerPrivate mvarEmpGender As gxcGenderPrivate mvarDeptID As LongPrivate mvarDeptName As String以下為類的屬性部門名稱Public Property Let DeptName(ByVal vData As String) mvarDeptName = vDataEnd PropertyPublic Property Get DeptName() As String DeptName = mvarDeptNameEnd Property部門IDPublic Property Let Dept

37、ID(ByVal vData As Long) mvarDeptID = vDataEnd PropertyPublic Property Get DeptID() As Long DeptID = mvarDeptIDEnd Property性別Public Property Let EmpGender(ByVal vData As gxcGender) mvarEmpGender = vDataEnd PropertyPublic Property Get EmpGender() As gxcGender EmpGender = mvarEmpGenderEnd Property年齡Pub

38、lic Property Let EmpAge(ByVal vData As Integer) If vData 10 Then vData = Left(vData, 10) mvarEmpName = vDataEnd PropertyPublic Property Get EmpName() As String EmpName = mvarEmpNameEnd PropertyIDPublic Property Let ID(ByVal vData As Long) mvarID = vDataEnd PropertyPublic Property Get ID() As Long ID

39、 = mvarIDEnd Property屬性結(jié)束以下為方法添加一個(gè)人員Public Function AddNew(Optional ByVal strName As String = , _ Optional ByVal intAge As Integer = 0, _ Optional varGender As gxcGender = -1, _ Optional lngDeptID As Long = 0) As Boolean On Error Resume Next 如果參數(shù)為缺省值,即未傳入,則直接調(diào)和類中的參數(shù),否則調(diào)用傳入的參數(shù) If strName Then Me.EmpN

40、ame = strName If intAge 0 Then Me.EmpAge = intAge If varGender -1 Then Me.EmpGender = varGender If lngDeptID 0 Then Me.DeptID = lngDeptID Dim strSQL As String g_Cn.BeginTrans 開始一個(gè)事務(wù),以免費(fèi)得到的ID值已被其它客戶端所使用 此處調(diào)用NextID方法,得到該類對應(yīng)的數(shù)據(jù)表的下一個(gè)ID,即最大ID+1 Me.ID = NextID(tEmployee, nID) 構(gòu)造SQL語句,注意需調(diào)用RealString去除字符串中

41、的單引號 strSQL = Insert into tEmployee (nID,DeptID,EmpName,EmpAge,EmpGender) values ( strSQL = strSQL & Me.ID & , & Me.DeptID & , strSQL = strSQL & & RealString(Me.EmpName) & , strSQL = strSQL & Me.EmpAge & , & Me.EmpGender & ) 執(zhí)行SQL語句,并提交事務(wù) g_Cn.Execute strSQL g_Cn.CommitTrans 如果發(fā)生錯(cuò)誤,則返回FALSE,表示未成功添加

42、AddNew = (Err.Number = 0)End Function修改人員信息Public Function Update() As Boolean On Error Resume Next Dim strSQL As String 構(gòu)造SQL語句 strSQL = Update tEmployee set DeptID= & Me.DeptID & , strSQL = strSQL & EmpName= & RealString(Me.EmpName) & , strSQL = strSQL & EmpAge= & Me.EmpAge & , strSQL = strSQL & E

43、mpGender= & Me.EmpGender & strSQL = strSQL & Where nID= & Me.ID g_Cn.Execute strSQL 如果發(fā)生錯(cuò)誤,則返回FALSE,表示未成功更新 Update = (Err.Number = 0)End Function刪除人員資料Public Function Delete(Optional ByVal lngID As Long = 0) As Boolean Dim strSQL As String On Error Resume Next 如果已傳入了要?jiǎng)h除的ID,則按此ID刪除 If lngID 0 Then Me

44、.ID = lngID strSQL = DELETE FROM tEmployee WHERE nID= & Me.ID g_Cn.Execute strSQL 如果發(fā)生錯(cuò)誤,則返回FALSE,表示未刪除成功 Delete = (Err.Number = 0)End Function方法結(jié)束將某個(gè)人員移到指定的部門Public Function AssignToDepartment(ByVal DeptID As Long) As Boolean 實(shí)現(xiàn)很簡單,將部門ID變一下,然后調(diào)用Update方法就行了 Me.DeptID = DeptID AssignToDepartment = Me

45、.UpdateEnd Function得到該人員所在部門,以對象返回Public Function Department() As cDept Dim objDepts As New cDepts 調(diào)用cDepts的Find方法,得到部門 objDepts.Find Me.DeptID If objDepts.Count 0 Then Set Department = objDepts.Item(1)End Function2.3.6. cEmps.clsOption ExplicitPrivate mCol As Collection 局部變量,保存集合將一個(gè)“人員”對象加入集合Public

46、 Sub Add(objEmp As cEmp) mCol.Add objEmp, A & objEmp.ID 在加入對象時(shí),最好同時(shí)加入其“KEY”屬性 “KEY”屬性不可以是數(shù)字型,因此在前面隨便加 一個(gè)字母,此處加了一個(gè)“A”End SubPublic Property Get Item(vntIndexKey As Variant) As cEmp Set Item = mCol(vntIndexKey)End PropertyPublic Property Get Count() As Long Count = mCol.CountEnd PropertyPublic Sub Rem

47、ove(vntIndexKey As Variant) mCol.Remove vntIndexKeyEnd SubPublic Property Get NewEnum() As IUnknown 本屬性允許用 For.Each 語法枚舉該集合。 Set NewEnum = mCol._NewEnumEnd Property清除集合中的全部元素Public Sub Clear() 清除時(shí)應(yīng)倒序清除! Dim i As Long For i = mCol.Count To 1 Step -1 mCol.Remove i Next iEnd SubPrivate Sub Class_Initia

48、lize() Set mCol = New CollectionEnd SubPrivate Sub Class_Terminate() Set mCol = NothingEnd Sub按條件查找人員,以集合類的方式返回Public Function Find(Optional ByVal lngID As Long = 0, _ Optional ByVal strName As String = , _ Optional ByVal lngDeptID As Long = 0) As cEmps 構(gòu)造查詢SQL Dim strSQL As String strSQL = Select t

49、Employee.*,tDept.DeptName from tEmployee left outer join tDept strSQL = strSQL & ON tDept.nID=tEmployee.DeptID Where If lngID 0 Then strSQL = strSQL & tEmployee.nID= & lngID & and 如果是按名稱查詢,則采用“包含”的查詢方法 If strName Then strSQL = strSQL & tEmployee.EmpName like% & RealString(strName) & % and If lngDeptID 0 Then strSQL = strSQL & tEmployee.DeptID= & lngDeptID & and strSQL = strSQL & tEmployee.nID0 將查詢結(jié)果加入集合類 Dim rs As Recordset Set rs = g_Cn.Execute(strSQL) Dim i As Long Dim objEmp As cEmp For

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論