




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、實(shí)戰(zhàn)案例:使用ADO技術(shù)和三層架構(gòu)實(shí)現(xiàn)用戶登錄案例【案例描述】現(xiàn)在我們將會(huì)通過(guò)一個(gè)簡(jiǎn)單的登錄案例體會(huì)三層架構(gòu)的開(kāi)發(fā)。登錄是大部分的軟件都會(huì)擁有的重要功能之一,雖然它不是在軟件設(shè)計(jì)的功能用例之內(nèi),但它卻是軟件不可缺少的一部分,通過(guò)登錄功能我們可以有效的阻止非授權(quán)的用戶訪問(wèn)軟件中保存的信息。首先用戶通過(guò)軟件的提示輸入用戶名和密碼,接下來(lái)軟件將會(huì)通過(guò)ADO在數(shù)據(jù)庫(kù)中使用select語(yǔ)句查詢(xún)對(duì)應(yīng)的信息,檢測(cè)數(shù)據(jù)表中是否有滿足用戶輸入的用戶名和密碼,并將檢測(cè)出來(lái)的結(jié)果返回到記錄集中,軟件通過(guò)讀取記錄集中保存的信息,檢測(cè)用戶是否可以登錄,如果可以登錄則顯示“允許登錄”的提示,否則顯示“不允許登錄”的提示。
2、運(yùn)行效果如下:【三層架構(gòu)的描述】清楚了上面的需求之后我們可以使用三層架構(gòu)來(lái)描述一下這個(gè)簡(jiǎn)單的功能。首先我們從表示層出發(fā)。表示層負(fù)責(zé)提示用戶輸入用戶名和密碼,并且接收用戶輸入的用戶名和密碼。接下來(lái)通過(guò)調(diào)用事務(wù)層的函數(shù)Login,通過(guò)Login的形參將用戶名和密碼傳遞到事務(wù)層進(jìn)行處理。接下來(lái)事務(wù)層將傳遞的用戶名和密碼整理到SQL語(yǔ)句中,并調(diào)用數(shù)據(jù)庫(kù)訪問(wèn)層的函數(shù)ExcuteSelect函數(shù)將這條SQL語(yǔ)句傳遞到數(shù)據(jù)庫(kù)訪問(wèn)層。數(shù)據(jù)庫(kù)訪問(wèn)層通過(guò)ADO技術(shù)和數(shù)據(jù)庫(kù)建立連接并且執(zhí)行該SQL語(yǔ)句,將數(shù)據(jù)庫(kù)執(zhí)行出的結(jié)果通過(guò)RecordSet對(duì)象保存起來(lái)并且返回RecordSet對(duì)象的指針,通過(guò)該指針將Recor
3、dSet對(duì)象傳遞到事務(wù)層。接下來(lái)事務(wù)層通過(guò)對(duì)該RecordSet對(duì)象進(jìn)行“拆包”獲取記錄集中保存的結(jié)果,并判斷該結(jié)果是否可以滿足允許用戶登錄的條件,如果允許則返回true,否則返回false。表示層中通過(guò)事務(wù)層的Login函數(shù)的返回值判斷用戶是否可以登錄,如果可以則提示“允許登錄”,否則提示“不允許登錄”。在Visual Studio中生成的關(guān)系依賴(lài)圖如下:(具體可見(jiàn)工程中的體系結(jié)構(gòu)圖)【數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì)】該案例是一個(gè)非常簡(jiǎn)單的使用用戶名和密碼設(shè)計(jì)的案例,因此我們可以設(shè)計(jì)一個(gè)用于保存某個(gè)用戶的用戶名和密碼的數(shù)據(jù)結(jié)構(gòu),在C+中,用戶自定義的數(shù)據(jù)結(jié)構(gòu)有很多種描述方案,我們此處選擇面向?qū)ο蟮拿枋龇椒ǎ?/p>
4、使用類(lèi)進(jìn)行描述,例如User類(lèi),其類(lèi)圖如下:【數(shù)據(jù)庫(kù)設(shè)計(jì)】接下來(lái)我們可以進(jìn)行該項(xiàng)目的數(shù)據(jù)庫(kù)設(shè)計(jì)了。該數(shù)據(jù)庫(kù)我們可以命名為T(mén)est,而數(shù)據(jù)庫(kù)中只有一張數(shù)據(jù)表Login_Inf。這張數(shù)據(jù)表中僅僅記錄了可以登錄軟件的用戶名和密碼。為了防止用戶名有重復(fù),我們規(guī)定用戶名作為主鍵(作為主鍵的列不能為空,且值要唯一)。同時(shí)為了防止非授權(quán)的用戶登錄軟件(例如盜用密碼或者清除密碼),我們規(guī)定每個(gè)用戶的密碼文件不能夠?yàn)榭铡1砀裥Ч缦聢D:建立數(shù)據(jù)庫(kù)和數(shù)據(jù)表的代碼如下:create database Test -創(chuàng)建名稱(chēng)為T(mén)est的數(shù)據(jù)庫(kù)gouse Test -使用該數(shù)據(jù)庫(kù)gocreate table Login_
5、inf -創(chuàng)建登錄信息表(UserName varchar(20) primary key, -創(chuàng)建用戶名列,為主鍵PasswordKey varchar(20) not null, -創(chuàng)建密碼列,要求該列單元格添加數(shù)據(jù)不能為空值)goinsert into Login_inf values('jianghanxin','jiang_1994221') -添加一個(gè)元組運(yùn)行之后在SQL Server Management Studio的“對(duì)象資源管理器”中可以查看到我們所建立的數(shù)據(jù)庫(kù)Test和數(shù)據(jù)表Login_inf。如下圖:【第一步:從數(shù)據(jù)庫(kù)訪問(wèn)層開(kāi)始】接下來(lái)我
6、們?cè)O(shè)計(jì)完成數(shù)據(jù)庫(kù)之后我們可以開(kāi)始對(duì)C+代碼的設(shè)計(jì)。首先我們從最基本的也是最底層的數(shù)據(jù)庫(kù)訪問(wèn)層開(kāi)始。由于我們所有的操作都是要通過(guò)數(shù)據(jù)庫(kù)訪問(wèn)層執(zhí)行SQL語(yǔ)句完成的,因此數(shù)據(jù)庫(kù)訪問(wèn)層我們可以這樣描述。數(shù)據(jù)庫(kù)訪問(wèn)層用于和數(shù)據(jù)庫(kù)打交道,用于將應(yīng)用程序和SQL Server數(shù)據(jù)庫(kù)建立連接,并且執(zhí)行相應(yīng)的數(shù)據(jù)操作。如果有類(lèi)似于查詢(xún)的返回結(jié)果,則返回帶有查詢(xún)結(jié)果的記錄集。在完成數(shù)據(jù)庫(kù)操作之后我們可以關(guān)閉數(shù)據(jù)庫(kù)連接。小提示:每次執(zhí)行數(shù)據(jù)庫(kù)操作都必須要先打開(kāi)數(shù)據(jù)庫(kù)連接,完成操作之后,再將數(shù)據(jù)庫(kù)連接關(guān)閉。否則程序?qū)?huì)報(bào)錯(cuò)。在了解了上述的功能描述后我們可以建立一個(gè)類(lèi)描述數(shù)據(jù)庫(kù)訪問(wèn)層,例如DataBase。聲明的代碼如
7、下:#pragma once#ifndef DATABASE_H#define DATABASE_H#include <iostream>#include <afx.h>#include <comdef.h>#include <conio.h>#import "C:Program FilesCommon FilesSystemadomsado15.dll"no_namespace rename("EOF","adoEOF")using namespace std;class DataBa
8、sepublic:DataBase(_bstr_t DataBaseName);DataBase(void);int Excute(_bstr_t const &CommandString);/執(zhí)行非查詢(xún)的數(shù)據(jù)庫(kù)命令_RecordsetPtr & ExcuteSelect(_bstr_t const &CommandString);/執(zhí)行查詢(xún)的數(shù)據(jù)庫(kù)命令void Open();/打開(kāi)數(shù)據(jù)庫(kù)連接void Close();/關(guān)閉數(shù)據(jù)庫(kù)連接private:_ConnectionPtr MyConnection;/數(shù)據(jù)庫(kù)連接指針_RecordsetPtr Records;/數(shù)據(jù)
9、庫(kù)記錄集指針_bstr_t ConnectionString;/連接字符串;#endifDataBase函數(shù):DataBase函數(shù)是該類(lèi)的構(gòu)造函數(shù),通常構(gòu)造函數(shù)負(fù)責(zé)一些初始化的工作。為了能夠減少后期我們工作的麻煩,例如每次調(diào)用DataBase類(lèi)都需要獲取數(shù)據(jù)庫(kù)字符串。為了大家能夠更好的理解數(shù)據(jù)庫(kù)的連接字符串,我們?cè)谶@里不妨對(duì)數(shù)據(jù)庫(kù)的連接字符串進(jìn)行一些分析。有如下的連接字符串:Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Test;Data Source=(loca
10、l)其中Provider參數(shù)說(shuō)明連接數(shù)據(jù)庫(kù)所使用的驅(qū)動(dòng)引擎,由于我們使用的是ADO技術(shù),故此我們使用的SQLOLEDB.1驅(qū)動(dòng)。我們可以通過(guò)打開(kāi).udl文件,并且點(diǎn)擊“提供程序”選項(xiàng)卡進(jìn)行選擇。如下圖:此處我們可以看到所選擇的是“Micorosoft OLE DB Provider for SQL Server”,其含義相信大家都能夠明白吧!當(dāng)然,此處我需要再次解釋一下ADO其實(shí)是對(duì)OLE DB訪問(wèn)技術(shù)的又一次封裝,使得我們?cè)L問(wèn)數(shù)據(jù)庫(kù)變得更加的簡(jiǎn)單,因此說(shuō)到底ADO技術(shù)的本質(zhì)其實(shí)還是OLE DB。因此我們?cè)谶x擇提供程序時(shí)應(yīng)該選擇Micorosoft OLE DB Provider,由于我們使用
11、的數(shù)據(jù)庫(kù)為SQL Server,因此我們需要選擇的是for SQL Server。接下來(lái)我們需要知道的是“Initial Catalog”參數(shù),該參數(shù)用于描述應(yīng)用程序究竟應(yīng)該訪問(wèn)哪一個(gè)數(shù)據(jù)庫(kù),其后的等于號(hào)跟的是應(yīng)用程序需要訪問(wèn)的數(shù)據(jù)庫(kù)的名稱(chēng),即Test。另外我們還需要了解“Data Scource”參數(shù),該參數(shù)用于描述數(shù)據(jù)源,即數(shù)據(jù)庫(kù)服務(wù)器的地址,由于我們的電腦上已經(jīng)安裝了SQL Server 2008,此時(shí)我們的電腦也可以作為一個(gè)單獨(dú)的數(shù)據(jù)庫(kù)服務(wù)器,名稱(chēng)為(local)或者localhost。上述的兩個(gè)參數(shù)我們可以打開(kāi)udl文件在“連接”選項(xiàng)卡中查看。如下圖:為了我們每次編程的時(shí)候不需要去通
12、過(guò)udl文件獲取連接字符串,我們可以通過(guò)字符串的連接將連接字符串進(jìn)行相應(yīng)的處理。由于我們此時(shí)需要操作的信息基本固定,除了每次所訪問(wèn)的數(shù)據(jù)庫(kù)不同,因此我們只需要修改“Initial Catalog”參數(shù)后的值就可以了。代碼如下:this->ConnectionString = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;User ID=sa;Initial Catalog="this->ConnectionString += DataBaseName;/將該變量
13、的參數(shù)與Initial Catalog連接this->ConnectionString += "Data Source=(local)"接下來(lái)我們還需要在構(gòu)造函數(shù)中完成一件很重要的事情初始化COM環(huán)境。由于ADO也是COM組件,因此我們使用ADO之前都需要初始化COM組件,為了能夠完成自動(dòng)初始化環(huán)境,我們可以將初始化的代碼放置到構(gòu)造函數(shù)中(構(gòu)造函數(shù)在創(chuàng)建對(duì)象時(shí)自動(dòng)執(zhí)行)。初始化COM組件的代碼如下:/初始化COM編程環(huán)境if(FAILED(:CoInitialize(NULL)cout<<"初始化COM環(huán)境失??!"<<end
14、l;_getch();return;大致來(lái)說(shuō)構(gòu)造函數(shù)中所要完成的事情都是一些瑣碎的細(xì)枝末節(jié),例如對(duì)于類(lèi)中屬性的初始化,以及對(duì)于環(huán)境的初始化等。這些細(xì)枝末節(jié)通常是很多人都容易忘記的,也通常不在我們描述程序的范圍之內(nèi),畢竟客戶不需要知道這些技術(shù)細(xì)節(jié),因此我們需要在構(gòu)造函數(shù)中完成它們,讓構(gòu)造函數(shù)每次新建對(duì)象之時(shí)自動(dòng)為我們進(jìn)行初始化操作。DataBase類(lèi)的完整代碼如下:DataBase:DataBase(_bstr_t DataBaseName)this->MyConnection = NULL;/設(shè)置連接指針為空,防止野指針this->Records = NULL;/設(shè)置記錄集指針為空
15、,防止野指針/設(shè)定連接字符串,需要連接的數(shù)據(jù)庫(kù)通過(guò)構(gòu)造函數(shù)的形參指定this->ConnectionString = "Provider=SQLOLEDB.1;Integrated Security=SSPI;"this->ConnectionString += "Persist Security Info=False;User ID=sa;Initial Catalog="this->ConnectionString += DataBaseName;this->ConnectionString += "Data Sou
16、rce=(local)"/初始化COM編程環(huán)境if(FAILED(:CoInitialize(NULL)cout<<"初始化COM環(huán)境失敗!"<<endl;_getch();/使用C+標(biāo)準(zhǔn)的getch函數(shù)return;DataBase函數(shù):DataBase函數(shù)是DataBase類(lèi)的析構(gòu)函數(shù),析構(gòu)函數(shù)主要負(fù)責(zé)退出COM環(huán)境,以免每次新建對(duì)象時(shí)初始化環(huán)境失敗。析構(gòu)函數(shù)代碼如下:DataBase:DataBase(void):CoUninitialize();/退出COM環(huán)境Open函數(shù):Open函數(shù)是DataBase類(lèi)中由程序員所創(chuàng)建,負(fù)責(zé)創(chuàng)建
17、連接對(duì)象,設(shè)定連接參數(shù),并且打開(kāi)數(shù)據(jù)庫(kù)連接。代碼如下:void DataBase:Open()tryMyConnection.CreateInstance(_uuidof(Connection);/創(chuàng)建連接對(duì)象MyConnection->ConnectionString = this->ConnectionString;/指定連接字符串MyConnection->ConnectionTimeout = 10;/指定連接超時(shí)為10sdoMyConnection->Open("","","",adConnectUn
18、specified);/打開(kāi)連接while(MyConnection->State != adStateOpen);catch(_com_error e)其中trycatch(_com_error e)用于檢測(cè)該代碼是否會(huì)產(chǎn)生異常情況使得程序崩潰。這一步是很有必要的。當(dāng)然我們?cè)诖嗽O(shè)定只要連接狀態(tài)處于關(guān)閉狀態(tài),就不斷地向數(shù)據(jù)庫(kù)使用MyConnection->Open函數(shù)不斷的對(duì)數(shù)據(jù)庫(kù)進(jìn)行連接,直到連接上數(shù)據(jù)庫(kù)為止。Close函數(shù):Close函數(shù)負(fù)責(zé)關(guān)閉數(shù)據(jù)庫(kù)連接,為了能夠提高數(shù)據(jù)庫(kù)訪問(wèn)層的效率,我們可以先判斷MyConnection中的State屬性,如果處于打開(kāi)狀態(tài)(adState
19、Open)則調(diào)用Close函數(shù),關(guān)閉數(shù)據(jù)庫(kù)連接。代碼如下:void DataBase:Close()tryif(MyConnection->State = adStateOpen)/如果連接處于打開(kāi)狀態(tài)MyConnection->Close();/關(guān)閉數(shù)據(jù)庫(kù)連接catch(_com_error e)Excute函數(shù):對(duì)數(shù)據(jù)庫(kù)的操作通常分為查詢(xún)操作和非查詢(xún)操作,非查詢(xún)操作包括INSERT(插入)、UPDATE(更新)、DELETE(刪除),Excute函數(shù)用于執(zhí)行非查詢(xún)操作的SQL語(yǔ)句,由于SQL語(yǔ)句的變數(shù)還是很多的,因此我們可以將SQL語(yǔ)句作為Excute函數(shù)的形參。為了能夠檢測(cè)S
20、QL語(yǔ)句是否執(zhí)行成功,我們可以通過(guò)返回一個(gè)int類(lèi)型的值(其含義為影響多少行)。整體結(jié)構(gòu)如下:int DataBase:Excute(_bstr_t const &CommandString)此處我們將形參設(shè)定為const,防止程序員在使用CommandString參數(shù)時(shí)不小心改動(dòng)了這個(gè)參數(shù),而使用引用的目的則是為了節(jié)省該函數(shù)所占用的計(jì)算機(jī)內(nèi)存。如果我們直接使用值傳遞,則函數(shù)會(huì)在實(shí)參之外另外建立一個(gè)內(nèi)存空間保存CommandString的值?!袄速M(fèi)空間”這種事情對(duì)于一些配置較老的電腦來(lái)說(shuō)是萬(wàn)萬(wàn)不能做的。畢竟內(nèi)存的容量還是有限的,不可能所有的內(nèi)存都給你使用。Excute函數(shù)的代碼如下所示
21、:int DataBase:Excute(_bstr_t const &CommandString)try_variant_t RecordsAffected;/記錄影響的行數(shù)this->Open();/打開(kāi)數(shù)據(jù)庫(kù)連接this->MyConnection->CommandTimeout = 10;/設(shè)置命令失敗延時(shí)為10sthis->MyConnection->Execute(CommandString,&RecordsAffected,adCmdText);/執(zhí)行數(shù)據(jù)庫(kù)命令this->Close();/關(guān)閉數(shù)據(jù)庫(kù)連接return (int)
22、RecordsAffected;/返回影響行數(shù)catch(_com_error e)在此我們使用了剛剛已經(jīng)在類(lèi)中定義好的Open函數(shù)和Close函數(shù)負(fù)責(zé)打開(kāi)和關(guān)閉數(shù)據(jù)庫(kù)連接。這樣我們可以通過(guò)函數(shù)將代碼封裝起來(lái),避免了重復(fù)寫(xiě)代碼的麻煩。ExcuteSelect函數(shù):ExcuteSelect函數(shù)用于執(zhí)行查詢(xún)的操作,通常查詢(xún)的過(guò)程是通過(guò)MyConnection中的Excute函數(shù)執(zhí)行SQL語(yǔ)句,并且接收該函數(shù)返回的記錄集指針(類(lèi)型為_(kāi)RecordSetPtr)。接收完成之后我們可以將該記錄集的指針作為返回值返回。代碼如下:_RecordsetPtr & DataBase:ExcuteSele
23、ct(_bstr_t const &CommandString)try_variant_t RecordsAffected;this->Records.CreateInstance(_uuidof(Recordset);/創(chuàng)建數(shù)據(jù)集this->Open();/打開(kāi)數(shù)據(jù)庫(kù)連接this->Records = MyConnection->Execute(CommandString,&RecordsAffected,adCmdText);/執(zhí)行數(shù)據(jù)庫(kù)命令if(this->Records!=NULL)return Records;catch(_com_err
24、or e)/忽略異常至此,數(shù)據(jù)庫(kù)訪問(wèn)的構(gòu)建結(jié)束,最底層的工作也已經(jīng)做好了。讓我們來(lái)看看完整的DataBase類(lèi)的代碼吧!DataBase.h的內(nèi)容如下:#pragma once#ifndef DATABASE_H#define DATABASE_H#include <iostream>#include <afx.h>#include <comdef.h>#include <conio.h>#import "C:Program FilesCommon FilesSystemadomsado15.dll"no_namespace
25、rename("EOF","adoEOF")using namespace std;class DataBasepublic:DataBase(_bstr_t DataBaseName);DataBase(void);int Excute(_bstr_t const &CommandString);/執(zhí)行非查詢(xún)的數(shù)據(jù)庫(kù)命令_RecordsetPtr & ExcuteSelect(_bstr_t const &CommandString);/執(zhí)行查詢(xún)的數(shù)據(jù)庫(kù)命令void Open();/打開(kāi)數(shù)據(jù)庫(kù)連接void Close();/關(guān)閉
26、數(shù)據(jù)庫(kù)連接private:_ConnectionPtr MyConnection;/數(shù)據(jù)庫(kù)連接指針_RecordsetPtr Records;/數(shù)據(jù)庫(kù)記錄集指針_bstr_t ConnectionString;/連接字符串;#endifDataBase.cpp的內(nèi)容如下:#include "DataBase.h"DataBase:DataBase(_bstr_t DataBaseName)this->MyConnection = NULL;this->Records = NULL;this->ConnectionString = "Provide
27、r=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;User ID=sa;Initial Catalog="this->ConnectionString += DataBaseName;this->ConnectionString += "Data Source=(local)"/初始化COM編程環(huán)境if(FAILED(:CoInitialize(NULL)cout<<"初始化COM環(huán)境失敗!"<<endl;_getch();re
28、turn;DataBase:DataBase(void):CoUninitialize();/退出COM環(huán)境void DataBase:Open()tryMyConnection.CreateInstance(_uuidof(Connection);/創(chuàng)建連接對(duì)象MyConnection->ConnectionString = this->ConnectionString;/指定連接字符串MyConnection->ConnectionTimeout = 10;/指定連接超時(shí)為10sdoMyConnection->Open("","&quo
29、t;,"",adConnectUnspecified);/打開(kāi)連接while(MyConnection->State != adStateOpen);catch(_com_error e)void DataBase:Close()tryif(MyConnection->State = adStateOpen)/如果連接處于打開(kāi)狀態(tài)MyConnection->Close();/關(guān)閉數(shù)據(jù)庫(kù)連接catch(_com_error e)int DataBase:Excute(_bstr_t const &CommandString)try_variant_t
30、 RecordsAffected;this->Open();/打開(kāi)數(shù)據(jù)庫(kù)連接this->MyConnection->CommandTimeout = 10;this->MyConnection->Execute(CommandString,&RecordsAffected,adCmdText);/執(zhí)行數(shù)據(jù)庫(kù)命令this->Close();/關(guān)閉數(shù)據(jù)庫(kù)連接return (int)RecordsAffected;/返回影響行數(shù)catch(_com_error e)_RecordsetPtr & DataBase:ExcuteSelect(_bst
31、r_t const &CommandString)try_variant_t RecordsAffected;this->Records.CreateInstance(_uuidof(Recordset);/創(chuàng)建數(shù)據(jù)集this->Open();/打開(kāi)數(shù)據(jù)庫(kù)連接this->Records = MyConnection->Execute(CommandString,&RecordsAffected,adCmdText);/執(zhí)行數(shù)據(jù)庫(kù)命令if(this->Records!=NULL)return Records;catch(_com_error e)co
32、ut<<"錯(cuò)誤原因:"<<e.ErrorMessage()<<endl;【第二步:借助數(shù)據(jù)庫(kù)訪問(wèn)層完成任務(wù)的事務(wù)層】接下來(lái)我們需要構(gòu)造的是事務(wù)層,事務(wù)層我們也使用一個(gè)類(lèi)進(jìn)行描述,例如“Kernel”。事務(wù)層的函數(shù)通過(guò)調(diào)用數(shù)據(jù)庫(kù)訪問(wèn)層中的函數(shù)對(duì)數(shù)據(jù)庫(kù)進(jìn)行訪問(wèn),而數(shù)據(jù)庫(kù)訪問(wèn)層如何具體訪問(wèn)數(shù)據(jù)庫(kù)的細(xì)節(jié),事務(wù)層并不需要理會(huì)。本案例中的事務(wù)層只有一個(gè)功能,就是通過(guò)數(shù)據(jù)庫(kù)訪問(wèn)層的ExcuteSelect函數(shù)查找數(shù)據(jù)庫(kù)中是否有符合條件的記錄,然后將所得到的結(jié)果通過(guò)記錄集返回到事務(wù)層,事務(wù)層再通過(guò)對(duì)記錄集的“拆包”,取出返回的數(shù)據(jù),并通過(guò)該數(shù)據(jù)判斷是否可
33、以登錄。用于判斷用戶是否存在于數(shù)據(jù)表中,我們可以使用Select語(yǔ)句以及SQL語(yǔ)句中的聚合函數(shù)COUNT(*)完成。SQL語(yǔ)句如下:select COUNT(*) from Login_inf where UserName = 'USERNAME' and PasswordKey = 'PASSWORD'其中USERNAME指示需要查找的用戶名,PASSWORD指示用戶的密碼。例如:select COUNT(*) -符合條件的記錄數(shù)from Login_inf -查找的數(shù)據(jù)表where UserName = 'jianghanxin' and P
34、asswordKey = 'jiang_1994221' -查找條件接下來(lái)我們可以先在SQL Server Management Studio中執(zhí)行一下,看一下返回的記錄的樣子。執(zhí)行的結(jié)果如下圖所示:我們可以看到上圖中所寫(xiě)的列的名稱(chēng)是“(無(wú)列名)”,那對(duì)于這種沒(méi)有列名的表格的記錄集我們又應(yīng)該怎么訪問(wèn)呢?其實(shí)這些沒(méi)有列名的表格默認(rèn)從0開(kāi)始升序排序。因此我們可以使用該編號(hào)進(jìn)行訪問(wèn)。上圖中只有一個(gè)單元格,也就是第0列。好了,話題扯得有些遠(yuǎn)了,我們現(xiàn)在來(lái)看一下Kernel類(lèi)的聲明代碼吧!Kernel.h文件用于存放Kernel類(lèi)的聲明,事實(shí)上,通常類(lèi)的聲明都放置在頭文件中。代碼如下:#
35、pragma once#ifndef KERNEL_H#define KERNEL_H#include "DataBase.h"#include "User.h"#include <string>#include <iostream>using namespace std;class Kernelpublic:Kernel();Kernel();bool Login(User &user);private:DataBase *db;/第三層指針;#endif其中db是DataBase類(lèi)的指針,也就是指向數(shù)據(jù)庫(kù)訪問(wèn)層的指針,
36、接下來(lái)我們將會(huì)通過(guò)這個(gè)指針調(diào)用數(shù)據(jù)庫(kù)訪問(wèn)層的函數(shù),進(jìn)而完成訪問(wèn)數(shù)據(jù)庫(kù)的操作。接下來(lái)我們還是解析一下Kernel類(lèi)的函數(shù)吧!Kernel函數(shù):Kernel函數(shù)是Kernel類(lèi)的構(gòu)造函數(shù),用于初始化私有對(duì)象,也就是db。由于db只是一個(gè)指針,因此我們需要使用new關(guān)鍵字調(diào)用DataBase類(lèi)的構(gòu)造函數(shù)創(chuàng)建對(duì)象。當(dāng)然很多人有個(gè)疑問(wèn),為什么不能夠直接使用DataBase類(lèi)建立對(duì)象呢?那是因?yàn)樗接袑?duì)象不能夠直接初始化,而且DataBase類(lèi)沒(méi)有無(wú)參構(gòu)造函數(shù),但卻有有參構(gòu)造函數(shù),結(jié)果有參構(gòu)造函數(shù)先入為主,就不能夠直接完成初始化的操作了。Kernel類(lèi)的代碼如下:Kernel:Kernel()this-&g
37、t;db = new DataBase("Test");/創(chuàng)建數(shù)據(jù)庫(kù)訪問(wèn)層的對(duì)象Kernel函數(shù):Kernel函數(shù)是Kernel類(lèi)的析構(gòu)函數(shù),用于使用delete關(guān)鍵字釋放db所指向的數(shù)據(jù)庫(kù)訪問(wèn)層對(duì)象。代碼如下:Kernel:Kernel()delete db;/刪除數(shù)據(jù)庫(kù)對(duì)象Login函數(shù):Login函數(shù)是程序員自定義的函數(shù),用于判斷用戶是否登錄,代碼如下:bool Kernel:Login(User &user)bool flag = false;/flag變量指示用戶是否能夠登錄int count = 0;/保存查詢(xún)的結(jié)果/設(shè)置需要執(zhí)行的SQL語(yǔ)句string
38、 CommandString = "select COUNT(*) from Login_inf where UserName = '"CommandString += user.getUserName() + "' and PasswordKey = '"CommandString += user.getPassWord() + "'"/執(zhí)行SQL語(yǔ)句并且獲得記錄集_RecordsetPtr record = NULL;/創(chuàng)建指向記錄集的指針,默認(rèn)為空record = db->ExcuteSelect(_bstr_t)CommandString.
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 外檐保溫合同范本
- 廠房全租合同范本
- 勞務(wù)派遣合同范本南京
- 農(nóng)村煙酒供應(yīng)合同范本
- 臺(tái)歷打孔合同范本
- 出售舊鋼骨架合同范本
- 前期物業(yè)管理合同范例
- 單位購(gòu)買(mǎi)二手房合同范本
- 發(fā)票增額購(gòu)銷(xiāo)合同范例
- 合股經(jīng)營(yíng)學(xué)校合同范本
- CEO自戀及其經(jīng)濟(jì)后果研究:以格力電器為例
- 紅土鎳礦濕法冶煉技術(shù)綜述
- 六鑫伺服刀塔說(shuō)明書(shū)LS系列
- 19.骨折術(shù)后內(nèi)固定取出臨床路徑
- 隧道開(kāi)挖作業(yè)臺(tái)車(chē)計(jì)算書(shū)
- 水利水電工程金屬結(jié)構(gòu)與機(jī)電設(shè)備安裝安全技術(shù)規(guī)程
- 腎內(nèi)科臨床診療規(guī)范(南方醫(yī)院)
- 珍愛(ài)生命 安全第一 中小學(xué)主題教育班會(huì)
- 二十八星宿(課堂PPT)
- OQC出貨檢驗(yàn)報(bào)告
- 小學(xué)一年級(jí)硬筆書(shū)法入門(mén).ppt
評(píng)論
0/150
提交評(píng)論