C++ ADO操作mysql數據庫

 對於軟件開發其實說白了就是在不停地和數據打交道, 所以數據庫的操作是必不可少的, 接下來介紹VC開發中利用ADO建立ODBC數據源來訪問MySQL數據庫.

       從我接觸的數據庫編程方式來說, 我覺得在vc開發連接數據庫是比較難的, 也是很容易出錯. 在android中, 系統自帶sqlite數據庫,只需要使用SQLiteOpenHelper抽象類即可完成與數據庫的操作. 在java中, 使用jdbc連接mysql數據庫, 下載相應jar調用相應接口,傳入數據庫類型與用戶名密碼進行數據庫的操作. 但是ado連接數據庫比較複雜, 接下來我們看一下如何使用ado連接數據庫.

一. 安裝mysql

       首先你需要確保電腦上已經安裝了mysql數據庫, 並使用用戶名與密碼成功使用mysql. 如何安裝配置mysql, 這裏不做詳細介紹.

          如果不瞭解如何安裝配置mysql可以參考這個地址:  點擊打開鏈接


二.  ADO方式連接MySql

1. 導入ado數據庫, 在你的程序中添加下面語句來導入ado數據庫

  1. // no_namespace rename("EOF", "adoEOF")防止命名重複,將EOF重命名爲adoEOF  
  2.   
  3. #import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF", "adoEOF")   
// no_namespace rename("EOF", "adoEOF")防止命名重複,將EOF重命名爲adoEOF

#import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF", "adoEOF") 

 2. 初始化com環境


  1. //初始化com環境  
  2. AfxOleInit();  
//初始化com環境
AfxOleInit();

3. 創建數據表結構,用來保存從數據庫中獲取的內容
假設數據表只有兩個字段:用戶ID與用戶名

  1. typedef struct _OBJ_USER  
  2. {  
  3.     int User_ID;  
  4.     TCHAR User_Name[32];  
  5. }OBJ_USER;  
typedef struct _OBJ_USER
{
	int User_ID;
	TCHAR User_Name[32];
}OBJ_USER;
4.創建操作數據庫的類operator類

  1. class CDataOperator  
  2. {  
  3. public:  
  4.     CDataOperator();  
  5.     ~CDataOperator();  
  6. public:  
  7.     //打開指定的數據庫  
  8.     BOOL OpenDatabase(CString strDbName, CString strUserName, CString strUserPwd);  
  9. public:  
  10.     //執行sql語句,增加數據,刪除數據  
  11.     BOOL ExecuteSQL(CString sql);  
  12.     //查詢數據  
  13.     BOOL Select_From_User(vector<OBJ_USER> &vecObjUser);  
  14.     //插入數據, 可以插入圖片,二進制數據(大數據)  
  15.     BOOL Insert_Into_User(OBJ_USER &objUser);  
  16.     //更新數據, 可更新大數據  
  17.     BOOL Update_For_User(OBJ_USER &objUser);  
  18. public:  
  19.     //連接對象  
  20.     _ConnectionPtr m_pConnection;  
  21. };  
class CDataOperator
{
public:
	CDataOperator();
	~CDataOperator();
public:
	//打開指定的數據庫
	BOOL OpenDatabase(CString strDbName, CString strUserName, CString strUserPwd);
public:
	//執行sql語句,增加數據,刪除數據
	BOOL ExecuteSQL(CString sql);
	//查詢數據
	BOOL Select_From_User(vector<OBJ_USER> &vecObjUser);
	//插入數據, 可以插入圖片,二進制數據(大數據)
	BOOL Insert_Into_User(OBJ_USER &objUser);
	//更新數據, 可更新大數據
	BOOL Update_For_User(OBJ_USER &objUser);
public:
	//連接對象
	_ConnectionPtr m_pConnection;
};

5. operator類的定義

  1. CDataOperator::CDataOperator()  
  2. {  
  3.     try  
  4.     {  
  5.         //創建連接對象  
  6.         HRESULT hr = m_pConnection.CreateInstance(_T("ADODB.Connection"));  
  7.         if (FAILED(hr))  
  8.         {  
  9.             m_pConnection = NULL;  
  10.         }  
  11.     }  
  12.     catch (_com_error &e)  
  13.     {  
  14.         e.ErrorMessage();  
  15.     }  
  16. }  
  17.   
  18. CDataOperator::~CDataOperator()  
  19. {  
  20.     if (m_pConnection)  
  21.     {  
  22.         try  
  23.         {  
  24.             //將連接對象關閉  
  25.             HRESULT hr = m_pConnection->Close();  
  26.         }  
  27.         catch (_com_error &e)  
  28.         {  
  29.             e.ErrorMessage();  
  30.         }  
  31.         //釋放連接對象  
  32.         m_pConnection.Release();  
  33.         m_pConnection = NULL;  
  34.     }  
  35. }  
  36.   
  37. //打開數據庫的操作  
  38. BOOL CDataOperator::OpenDatabase(CString strDbName, CString strUserName, CString strUserPwd)  
  39. {  
  40.     if (NULL == m_pConnection)  
  41.     {  
  42.         return FALSE;  
  43.     }  
  44.     if (m_pConnection)  
  45.     {  
  46.         try  
  47.         {  
  48.             CString strConnectionName;  
  49.             strConnectionName.Format(_T("DATABASE=%s;DSN=myodbc;OPTION=0;PWD=%s;PORT=0;SERVER=localhost;UID=%s;"),  
  50.                 strDbName, strUserPwd, strUserName);  
  51.             HRESULT hr = m_pConnection->Open(_bstr_t(strConnectionName.GetBuffer(0)),  
  52.                 _T(""), _T(""), -1);  
  53.             if (FAILED(hr))  
  54.             {  
  55.                 m_pConnection = NULL;  
  56.             }  
  57.         }  
  58.         catch (_com_error &e)  
  59.         {  
  60.             e.ErrorInfo();  
  61.             return FALSE;  
  62.         }  
  63.     }  
  64.     return true;  
  65. }  
CDataOperator::CDataOperator()
{
	try
	{
		//創建連接對象
		HRESULT hr = m_pConnection.CreateInstance(_T("ADODB.Connection"));
		if (FAILED(hr))
		{
			m_pConnection = NULL;
		}
	}
	catch (_com_error &e)
	{
		e.ErrorMessage();
	}
}

CDataOperator::~CDataOperator()
{
    if (m_pConnection)
    {
        try
        {
            //將連接對象關閉
            HRESULT hr = m_pConnection->Close();
        }
        catch (_com_error &e)
        {
            e.ErrorMessage();
        }
        //釋放連接對象
        m_pConnection.Release();
        m_pConnection = NULL;
    }
}

//打開數據庫的操作
BOOL CDataOperator::OpenDatabase(CString strDbName, CString strUserName, CString strUserPwd)
{
    if (NULL == m_pConnection)
    {
        return FALSE;
    }
    if (m_pConnection)
    {
        try
        {
            CString strConnectionName;
            strConnectionName.Format(_T("DATABASE=%s;DSN=myodbc;OPTION=0;PWD=%s;PORT=0;SERVER=localhost;UID=%s;"),
                strDbName, strUserPwd, strUserName);
            HRESULT hr = m_pConnection->Open(_bstr_t(strConnectionName.GetBuffer(0)),
                _T(""), _T(""), -1);
            if (FAILED(hr))
            {
                m_pConnection = NULL;
            }
        }
        catch (_com_error &e)
        {
            e.ErrorInfo();
            return FALSE;
        }
    }
    return true;
}

獲取連接字符串的方法:

  1. strConnectionName.Format(_T("DATABASE=%s;DSN=myodbc;OPTION=0;PWD=%s;PORT=0;SERVER=localhost;UID=%s;"),  
  2.                 strDbName, strUserPwd, strUserName);  
strConnectionName.Format(_T("DATABASE=%s;DSN=myodbc;OPTION=0;PWD=%s;PORT=0;SERVER=localhost;UID=%s;"),
                strDbName, strUserPwd, strUserName);
連接字符串中包含的信息包括數據庫的類型, 數據庫的用戶名與密碼, 在這裏和java用jdbc連接數據庫類似, 獲取連接字符串:

"DATABASE=%s;DSN=myodbc;OPTION=0;PWD=%s;PORT=0;SERVER=localhost;UID=%s;" 的方式如下:

(1) 首先需要安裝mysql-connector-odbc-3.51.26-win32.ini, 才能連接mysql數據庫
(2) 新建一個txt文件,後綴名改爲.udl,雙擊打開
(3) 提供程序-->Microsoft OLE DB Provider for ODBC Drivers,點擊‘下一步’,選擇‘使用連接字符串’,
     點擊‘編譯’,選擇‘機器數據源’,點擊‘新建’,點擊‘下一步’,選擇MYSQL(如果你安裝了第一步中的應用會有MYSQL驅動程序)點擊‘下一步’,
     然後填寫相應的內容,需要連接的數據庫,server,用戶名,密碼等,點擊test按鈕,測試是否連接成功,連接成功,保存。
(4) 用記事本打開文件就獲取到了連接字符串。


6. CDataOperator類執行sql語句操作的接口

  1. BOOL CDataOperator::ExecuteSQL(CString sql)  
  2. {  
  3.     if (NULL == m_pConnection)  
  4.     {  
  5.         return FALSE;  
  6.     }  
  7.     if (m_pConnection)  
  8.     {  
  9.         try  
  10.         {  
  11.             HRESULT hr = m_pConnection->Execute(_bstr_t(sql), NULL, 1);  
  12.             if (FAILED(hr))  
  13.             {  
  14.                 m_pConnection = NULL;  
  15.             }  
  16.         }  
  17.         catch (_com_error &e)  
  18.         {  
  19.             e.ErrorMessage();  
  20.             return FALSE;  
  21.         }  
  22.     }  
  23.     return true;  
  24. }  
BOOL CDataOperator::ExecuteSQL(CString sql)
{
	if (NULL == m_pConnection)
	{
		return FALSE;
	}
	if (m_pConnection)
	{
		try
		{
			HRESULT hr = m_pConnection->Execute(_bstr_t(sql), NULL, 1);
			if (FAILED(hr))
			{
				m_pConnection = NULL;
			}
		}
		catch (_com_error &e)
		{
			e.ErrorMessage();
			return FALSE;
		}
	}
	return true;
}

7. 從數據庫中獲取數據

  1. BOOL CDataOperator::Select_From_User(vector<OBJ_USER> &vecObjUser)  
  2. {  
  3.     if (NULL == m_pConnection)  
  4.         return FALSE;  
  5.     //記錄集對象  
  6.     _RecordsetPtr m_pRecordSet;  
  7.     HRESULT hr = m_pRecordSet.CreateInstance(_T("ADODB.Recordset"));  
  8.     if (FAILED(hr))  
  9.     {  
  10.         return FALSE;  
  11.     }  
  12.     //獲取數據前先清空  
  13.     vecObjUser.clear();  
  14.     CString strSQL = _T("select User_ID, User_Name from user");  
  15.     hr = m_pRecordSet->Open(_bstr_t(strSQL),m_pConnection.GetInterfacePtr(),  
  16.         adOpenStatic, adLockOptimistic, adCmdText);  
  17.     if (FAILED(hr))  
  18.     {  
  19.         m_pRecordSet.Release();  
  20.         return FALSE;  
  21.     }  
  22.     //獲取當前遊標的位置  
  23.     VARIANT_BOOL bRet = m_pRecordSet->GetadoEOF();  
  24.     //如果遊標在末尾返回失敗  
  25.     //遍歷數據  
  26.     while(!bRet)  
  27.     {  
  28.         _variant_t varUserID = m_pRecordSet->GetCollect("User_ID");  
  29.         _variant_t varUserName = m_pRecordSet->GetCollect("User_Name");  
  30.         OBJ_USER objUser;  
  31.         objUser.User_ID = varUserID.intVal;  
  32.         _tcscpy_s(objUser.User_Name, (TCHAR*)(_bstr_t)varUserName);  
  33.         vecObjUser.push_back(objUser);  
  34.         //遊標下移  
  35.         m_pRecordSet->MoveNext();  
  36.         bRet = m_pRecordSet->GetadoEOF();  
  37.     }  
  38.     m_pRecordSet->Close();  
  39.     m_pRecordSet.Release();  
  40.     m_pRecordSet = NULL;  
  41.     return true;  
  42. }  
BOOL CDataOperator::Select_From_User(vector<OBJ_USER> &vecObjUser)
{
	if (NULL == m_pConnection)
		return FALSE;
	//記錄集對象
	_RecordsetPtr m_pRecordSet;
	HRESULT hr = m_pRecordSet.CreateInstance(_T("ADODB.Recordset"));
	if (FAILED(hr))
	{
		return FALSE;
	}
	//獲取數據前先清空
	vecObjUser.clear();
	CString strSQL = _T("select User_ID, User_Name from user");
	hr = m_pRecordSet->Open(_bstr_t(strSQL),m_pConnection.GetInterfacePtr(),
		adOpenStatic, adLockOptimistic, adCmdText);
	if (FAILED(hr))
	{
		m_pRecordSet.Release();
		return FALSE;
	}
	//獲取當前遊標的位置
	VARIANT_BOOL bRet = m_pRecordSet->GetadoEOF();
	//如果遊標在末尾返回失敗
	//遍歷數據
	while(!bRet)
	{
		_variant_t varUserID = m_pRecordSet->GetCollect("User_ID");
		_variant_t varUserName = m_pRecordSet->GetCollect("User_Name");
		OBJ_USER objUser;
		objUser.User_ID = varUserID.intVal;
		_tcscpy_s(objUser.User_Name, (TCHAR*)(_bstr_t)varUserName);
		vecObjUser.push_back(objUser);
		//遊標下移
		m_pRecordSet->MoveNext();
		bRet = m_pRecordSet->GetadoEOF();
	}
	m_pRecordSet->Close();
	m_pRecordSet.Release();
	m_pRecordSet = NULL;
	return true;
}

8. 往數據庫中插入數據(可以插入圖片,二進制大數據等)

我們通過CDataOperator::ExecuteSQL方法, 通過傳入插入sql語句可以實現往數據中插入數據, 但是插入圖片或二進制大數據這種方式並不適合.所以單獨將插入與更新操作實現,支持大數據的操作

  1. BOOL CDataOperator::Insert_Into_User(OBJ_USER &objUser)  
  2. {  
  3.     if (NULL == m_pConnection)  
  4.         return FALSE;  
  5.     //記錄集對象  
  6.     _RecordsetPtr m_pRecordSet;  
  7.     HRESULT hr = m_pRecordSet.CreateInstance(_T("ADODB.Recordset"));  
  8.     if (FAILED(hr))  
  9.     {  
  10.         return FALSE;  
  11.     }  
  12.     CString strSQL = _T("select User_ID, User_Name from user");  
  13.     hr = m_pRecordSet->Open(_bstr_t(strSQL), m_pConnection.GetInterfacePtr(),  
  14.         adOpenStatic, adLockOptimistic, adCmdText);  
  15.     if (FAILED(hr))  
  16.     {  
  17.         m_pRecordSet.Release();  
  18.         return FALSE;  
  19.     }  
  20.       
  21.     try  
  22.     {  
  23.         //增加一行  
  24.         m_pRecordSet->AddNew();  
  25.     }  
  26.     catch (_com_error &e)  
  27.     {  
  28.         e.ErrorMessage();  
  29.         return FALSE;  
  30.     }  
  31.     try  
  32.     {  
  33.         m_pRecordSet->PutCollect(_T("User_ID"), _variant_t(objUser.User_ID));  
  34.         m_pRecordSet->PutCollect(_T("User_Name"), _variant_t(objUser.User_Name));  
  35.     }  
  36.     catch (_com_error &e)  
  37.     {  
  38.         m_pRecordSet->Close();  
  39.         m_pRecordSet.Release();  
  40.         e.ErrorMessage();  
  41.         return FALSE;  
  42.     }  
  43.     m_pRecordSet->Update();  
  44.     m_pRecordSet->Close();  
  45.     m_pRecordSet.Release();  
  46.     m_pRecordSet = NULL;  
  47.     return TRUE;  
  48. }  
BOOL CDataOperator::Insert_Into_User(OBJ_USER &objUser)
{
	if (NULL == m_pConnection)
		return FALSE;
	//記錄集對象
	_RecordsetPtr m_pRecordSet;
	HRESULT hr = m_pRecordSet.CreateInstance(_T("ADODB.Recordset"));
	if (FAILED(hr))
	{
		return FALSE;
	}
	CString strSQL = _T("select User_ID, User_Name from user");
	hr = m_pRecordSet->Open(_bstr_t(strSQL), m_pConnection.GetInterfacePtr(),
		adOpenStatic, adLockOptimistic, adCmdText);
	if (FAILED(hr))
	{
		m_pRecordSet.Release();
		return FALSE;
	}
	
	try
	{
		//增加一行
		m_pRecordSet->AddNew();
	}
	catch (_com_error &e)
	{
		e.ErrorMessage();
		return FALSE;
	}
	try
	{
		m_pRecordSet->PutCollect(_T("User_ID"), _variant_t(objUser.User_ID));
		m_pRecordSet->PutCollect(_T("User_Name"), _variant_t(objUser.User_Name));
	}
	catch (_com_error &e)
	{
		m_pRecordSet->Close();
		m_pRecordSet.Release();
		e.ErrorMessage();
		return FALSE;
	}
	m_pRecordSet->Update();
	m_pRecordSet->Close();
	m_pRecordSet.Release();
	m_pRecordSet = NULL;
	return TRUE;
}

9. 更新數據庫中的數據

  1. BOOL CDataOperator::Update_For_User(OBJ_USER &objUser)  
  2. {  
  3.     if (NULL == m_pConnection)  
  4.         return FALSE;  
  5.     //記錄集對象  
  6.     _RecordsetPtr m_pRecordSet;  
  7.     HRESULT hr = m_pRecordSet.CreateInstance(_T("ADODB.Recordset"));  
  8.     if (FAILED(hr))  
  9.     {  
  10.         return FALSE;  
  11.     }  
  12.     CString strSQL;  
  13.     strSQL.Format(_T("select User_ID, User_Name from user where User_ID=%d"), objUser.User_ID);  
  14.     hr = m_pRecordSet->Open(_bstr_t(strSQL), m_pConnection.GetInterfacePtr(),  
  15.         adOpenStatic, adLockOptimistic, adCmdText);  
  16.     if (FAILED(hr))  
  17.     {  
  18.         m_pRecordSet.Release();  
  19.         return FALSE;  
  20.     }  
  21.     try  
  22.     {  
  23.         m_pRecordSet->PutCollect(_T("User_Name"), _variant_t(objUser.User_Name));  
  24.     }  
  25.     catch (_com_error &e)  
  26.     {  
  27.         m_pRecordSet->Close();  
  28.         m_pRecordSet.Release();  
  29.         e.ErrorMessage();  
  30.         return FALSE;  
  31.     }  
  32.     m_pRecordSet->Update();  
  33.     m_pRecordSet->Close();  
  34.     m_pRecordSet.Release();  
  35.     m_pRecordSet = NULL;  
  36.     return TRUE;  
  37. }  

BOOL CDataOperator::Update_For_User(OBJ_USER &objUser)
{
	if (NULL == m_pConnection)
		return FALSE;
	//記錄集對象
	_RecordsetPtr m_pRecordSet;
	HRESULT hr = m_pRecordSet.CreateInstance(_T("ADODB.Recordset"));
	if (FAILED(hr))
	{
		return FALSE;
	}
	CString strSQL;
	strSQL.Format(_T("select User_ID, User_Name from user where User_ID=%d"), objUser.User_ID);
	hr = m_pRecordSet->Open(_bstr_t(strSQL), m_pConnection.GetInterfacePtr(),
		adOpenStatic, adLockOptimistic, adCmdText);
	if (FAILED(hr))
	{
		m_pRecordSet.Release();
		return FALSE;
	}
	try
	{
		m_pRecordSet->PutCollect(_T("User_Name"), _variant_t(objUser.User_Name));
	}
	catch (_com_error &e)
	{
		m_pRecordSet->Close();
		m_pRecordSet.Release();
		e.ErrorMessage();
		return FALSE;
	}
	m_pRecordSet->Update();
	m_pRecordSet->Close();
	m_pRecordSet.Release();
	m_pRecordSet = NULL;
	return TRUE;
}

至此, ado方式連接MySQL數據庫的步驟介紹完畢, 最難的地方我覺得是獲取連接字符串和數據庫連接對象的使用. 數據庫類CDataOperator,實現了數據庫連接,

數據庫操作:增, 刪, 改, 查操作. 以後在vc開發時用到數據庫時, 使用CDataOperator可以很方便開發程序.

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