mfc採用ado連mysql數據庫

ADO數據庫開發的基本流程:

(1)初始化com庫,引入ADO庫定義文件

(2)用Connection對象連接數據庫

(3)利用建立好的連接,通過Connection、Command對象執行SQL命令,或利用Recordset對象取得結果記錄集進行查詢處理

(4)使用完畢後關閉連接釋放對象



1)COM 庫的初始化

必須注意的是,ADO庫是一組COM動態庫, 這意味着應用程序在調用ADO之前,必須初始化OLE/COM庫環境。在MFC應用程序裏, 一個比較好的方法是在應用程序朱磊的InitInstance成員函數裏初始化OLE/COM庫環境。

我們可以使用AfxOleInit()來初始化COM庫,這項工作通常在InitInstance()的重載函數中完成,放在第一句的後面

BOOL CADOAPP::InitInstance()

{

AfxEnableControlContainer();

if(!AfxOleInit())

{

AfxMessageBox("OLE初始化出錯!");

return FALSE;

}

}


2) 用#import指令引入ADO類型庫

我們在stdafx.h中加入如下語句,放到stdafx.h最後面 

#import "C:\program files\common files\system\ado\msado15.dll" no_namespace rename("EOF", "adoEOF");

這一語句有何作用呢?其最終作用同我們熟悉的#include類似,編譯的時候系統會爲我們生成msado15.tlh, ado15.tlli兩個C++頭文件來定義ADO庫

這行語句生命在工程中使用ADO,但不使用ADO的名字空間,並且爲了避免常數衝突,將常數EOF改名爲adoEOF

現在不需添加另外的頭文件,就可以使用ADO接口了。

3)創建Connection對象並連接數據庫  

首先我們需要添加一個指向Connection對象的指針

在APP類中的.h的APP定義裏面加入代碼:


class CADOAPP: public CWinApp

{

public:

CADOApp();

_ConnectionPtr  m_pConnection;


}

在BOOL CADOApp::InitInstance()加入代碼:

HRESULT hr;

try

{

hr = m_pConnection.CreateInstance("ADODB.Connection");//創建Connection對象

if(SUCCEEDED(hr))

{

hr = m_pConnection->Open("Provider=Microsoft.jet.OLEDB.4.0;Data Source=student.mdb","","",adModeUnkonwn);

//連接數據庫///上面一句中連接字符串中的Provider是針對Access2000環境的,對於ACCESS97,需要改爲:Provider=Microsoft.Jet.OLEDB.3.5.1;

}

}

catch(_com_error e){//捕捉異常

CString errormessage;

errormessage.Format("連接數據庫失敗!\r\n錯誤信息:%s", e.ErrorMessage());

AfxMessageBox(errormessage);//顯示錯誤信息

        return FALSE;

}


在這段代碼中我們是通過Connection對象的Open方法來連接數據庫的,下面是該方法的原型


HRESULT Connection15::

Open(_bstr_t ConnectionString, _bstr_t UserID, _bstr_t Password, long Options)


ConnectionString爲連接選項,用於指定Connection對象對數據的更新許可權


Option可以是如下幾個常量:

adModeUnknown:缺省。當前的許可權未設置

adModeRead:只讀

adModeWrite:只寫

adModeReadWrite:可以讀寫

adModeShareDenyRead:阻止其它Connection對象以讀權限打開連

adModeShareDenyWrite:阻止其它Connection對象以寫權限打開連接

adModeShareExclusive:  阻止其它Connection對象打開連接

adModeShareDenyNone:允許其它程序或對象以任何權限建立連接


給出一些常用的連接方式供參考:

(1)通過Jet數據庫引擎對ACCESS2000數據庫的連接m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\test.mdb","","",adModeUnknown);

(2)通過DSN數據源對任何支持ODBC的數據庫進行連接:

m_pConnection->Open("Data Source=adotest;UID=sa;PWD=;","","",adModeUnknown);

(3)不通過DSN對SQL SERVER數據庫進行連接:

m_pConnection->Open("driver={SQLServer};Server=127.0.0.1;DATABASE=vckbase;UID=sa;PWD=139","","",adModeUnknown);

  其中Server是SQL服務器的名稱,DATABASE是庫的名稱


執行SQL命令並取得結果記錄集的方法有三個,下面分別介紹:

方法一:利用Connection對象的Execute方法執行SQL命令

Execute方法的原型如下所示:

_RecordsetPtr Connection15:: Execute(_bstr_t CommandText, VARIANT  *RecordsAffected,long Options)

其中CommandText是命令字符串,通常是SQL命令

參數RecordsAffected是操作完成後所影響的行數

參數Options表示CommandText中內容的類型,Options可以去如下值之一:

adCmdText:表明CommandText是文本命令

adCmdTable:表明CommandText是一個表名

adCmdProc:表明CommandText是一個存儲過程

adCmdUnknown :未知

Execute執行完後返回一個指向記錄集的指針,下面給出具體的代碼

_variant_t RecordsAffected;

例1.執行SQL命令CREATE TABLE 創建表格users, users包含四個字段:整型ID,字符username,整型old,日期型birthday

m_pConnection->Execute("CREATE TABLE users(ID INTEGER, username TEXT,old INTEGER, birthday DATETIME)", &RecordsAffected, adCmdText);

例2.往表格裏面添加記錄

m_pConnection->Execute("INSERT INTO users(ID, username, old, birthday) VALUES(1,"Washington",25, "1970/1/1")", &RecordsAffected, adCmdText);

例3.將所有記錄old字段的值加1

m_pConnection->Execute("UPDATE users SET old = old +1", &RecordsAffected, adCmdText);

例4.執行SQL統計命令得到包含記錄條數的記錄集

(1)爲了取得結果記錄集,我們定義一個指向Recordset對象指針:

_RecordsetPtr m_pRecordset;

(2) 併爲其創建Recordset對象的實例:

m_pRecordset.CreateInstance ("ADODB.Recordset");

(3)m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users", &RecordsAffected, adCmdText


方法二:利用Command對象來執行命令

 先定義Command對象的指針

_CommandPtr m_pCommand;

m_pCommand.CreateInstance("ADODB.Command");


例5.執行SQL命令得到users表的記錄集

 (1)將建立的連接賦值給它,非常關鍵的一句

m_pCommand->ActiveConnection = m_pConnection;

(2)命令字串

m_pCommand->CommandText = "SELECT * FROM users";

(3)執行命令,取得記錄集

m_pRecordset = m_pCommand->Execute(NULL, NULL,adCmdText);

 在這段代碼中我們只是用Command對象來執行了SELECT查詢語句, Command對象在進行存儲過程的調用中能真正體現它的作用。

例6.執行SQL命令刪除學號爲3的記錄

CString strSql;

strSql.Format("delete from student where stuid = '%s'", 3);

_variant_t strSQL = strSql;

this->m_pCommand->ActiveConnection = this->m_pConnection;

this->m_pCommand->CommandType = adCmdText;

this->m_pCommand->CommandText = (_bstr_t)strSQL;

this->m_pCommand->Execute(NULL, NULL, adCmdText);

_variant_t 和_bstr_t這兩個類,分別封裝並管理VARIANT和BSTR這兩種數據類型,VARIANT和BSTR這兩種數據類型是COM中使用的數據類型。爲了C++中的變量應用到ADO編程中,只能進行數據類型的轉換。

通過 _variant_t和_bstr_t這兩個類,就可以方便的把C++類型變量轉換成COM中的變量。


方法三:直接用Recordset對象進行查詢取得記錄集

(1)爲了取得結果記錄集,我們定義一個指向Recordset對象的指針:

_RecordsetPtr m_pRecordset;

(2)併爲其創建Recordset對象的實例:

m_pRecordset.CreateInstance("ADODB.Recordset");


例7.打開一個數據庫表

m_pRecordset->Open("SELECT * FROM users", _variant_t((IDispatch *)m_pConnection, true),adOpenStatic, adLockOptimistic, adCmdText);

或者theApp.m_pRecordset->Open(strSql, theApp.m_pConnection.GetInterfacePtr(),adOpenStatic, adLockOptimistic, adCmdUnknown);


Open方法的原型是這樣的:

HRESULT Recordset15::Open(const  _variant_t & Source, const  _variant _t & ActiveConnection, enum CursorTypeEnum CursorType, enum LockType LockType, long Options)


其中:

1 Source是數據查詢字符串

2 ActiveConnection是已經建立好的連接(我們需要用Connection對象指針來構造一個_variant_t對象)

3 CursorType 光標類型,它可以是以下值之一,請看這個枚舉結構:

enum CursorTypeEnum

{

adOpenUnspecified = -1,

//不做特別限定

adOpenForwardOnly = 0,

//前滾靜態光標。這種光標只能向前瀏覽記錄集,比如用MoveNext 向前滾動,這種方式可以提高瀏覽速度。但諸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用

adOpenKeyset=1,

//採用這種光標的記錄集看不到其他用戶的新增、刪除操作,但對於更新原有記錄的操作對你是課件的。

adOpenDynamic=2,

//動態光標。所有數據庫的操作都會立即在個用戶記錄集上反應出來

adOpenStatic=3

//靜態光標。它爲你的記錄集產生一個靜態備份,但其它用戶的新增、刪除、更新操作對你的記錄集來說是不可見的。

};

4LockType鎖定類型,它可以是以下值之一,請看如下枚舉結構:

enum LockTypeEnum

{

adLockUnspecified = -1,

//未指定

adLockReadOnly = 1,

//只讀記錄集

adLockpessimistic = 2,

//悲觀鎖定方式。數據在更新時鎖定其它所有鎖定,這是最安全的鎖定機制

adLockOptimistic=3,

//樂觀鎖定方式。只有在你調用Update方法時才鎖定記錄。在此之前仍然可以做數據的更新、插入、刪除等操作

adLockBatchOptimistic=4,

//樂觀分批更新。編輯時記錄不會鎖定,更改,插入及刪除是在批處理模式下完成的。

}

5Options請參考對Connection對象的Execute方法的介紹

例題8 關閉記錄集

m_pRecord->Close();

例題9 取得第一個字段的值放入vCount變量

//兩條語句的效果一樣

_variant_t vIndex = (long)0;

_variant_t vCount = _pRecordset->GetCollect(vIndex);


例題10:打開記錄集,遍歷所有記錄,刪除第一條記錄,添加三條記錄,移動光標到第二條記錄,更改其年齡,保存到數據庫

_variant_t vUsername,vBirthday,vID,vOld;

_RecordsetPtr m_pRecordset;

m_pRecordset.CreateInstance("ADODB.Recordset");

m_pRecordset->Open("SLECT *FROM users",_variant_t((IDispacth *)m_pConnection, true),adOpenStatic,adLockOptimistic,adCmdText);

while(!m_pRecordset->adoEOF)//這裏爲什麼是adoEOF而不是EOF呢?還記得rename("EOF","adoEOF")這一句

{

vID= m_pRecordset->GetCollect(_variant_t((long)0));//取得第一列的值,從0開始計數(0代表第一列),也可以直接給出列的名稱,如下一行

vUsername= m_pRecordset->GetCollect("username");

//取得username字段的值

vOld = m_pRecordset->getCollect("old");

        vBirthday = m_pRecordset->GetCollect("birthday");

m_pRecordset->MoveNext();//移到下一條記錄   


}

m_pRecordset->MoveFirst();//移到首條記錄

m_pRecordset->Delete(adAffectCurrent);//刪除當前記錄

//添加三條新記錄並賦值

for(int i=0;i<3;i++)

{

m_pRecordset->AddNew();///添加新記錄

m_pRecordset->PutCollect("ID", _variant_t((long)(i+10)));

m_pRecordset->PutCollect("username", _variant_t("yeliqin"));

m_pRecordset->PutCollect("old", _variant_t((long)71));

m_pRecordset->PutCollect("birthday", _variant_t("1930-3-15"));

}

m_pRecordset->Move(1, _variant_t((long)adBookmarkFirst));//從第一條記錄往下移動一條記錄,即移動到第二條記錄

m_pRecordset->PutCollect(_variant_t("old"), _variant_t((long)45));

//修改年齡

m_pRecordset->Update();//保存到庫中







因爲這個問題經常忘記,總是不記得流程,故把具體流程寫在這裏供以後參考。


首先建立mfc應用程序,把你想要拿上去的空間貼上去

之後在stdafx.h裏添加這樣一句話:#import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename ("EOF", "adoEOF")   



接下來就可以定義你所需要的指針對象了

        _ConnectionPtr m_pConnection;

         _RecordsetPtr  m_pRecordset;
_CommandPtr    m_pCommand;


這些指針的用途就不做詳細介紹了,這裏只是記錄一下必須的流程。

 在初始化裏面需要調用:AfxOleInit();

這個是用來初始化com庫的必不可少。


另外注意用odbc鏈接數據庫的時候一定要打開mysql服務並且還要安裝odbc的連接器。這個都是必不可少的,否則是無法連上數據庫的。


之後就是創建連接了,方便你的程序能正常訪問數據庫,這個在我轉載的一篇文章裏面也有詳細介紹,就不細說了。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章