從我接觸的數據庫編程方式來說, 我覺得在vc開發連接數據庫是比較難的, 也是很容易出錯. 在android中, 系統自帶sqlite數據庫,只需要使用SQLiteOpenHelper抽象類即可完成與數據庫的操作. 在java中, 使用jdbc連接mysql數據庫, 下載相應jar調用相應接口,傳入數據庫類型與用戶名密碼進行數據庫的操作. 但是ado連接數據庫比較複雜, 接下來我們看一下如何使用ado連接數據庫.
一. 安裝mysql
首先你需要確保電腦上已經安裝了mysql數據庫, 並使用用戶名與密碼成功使用mysql. 如何安裝配置mysql, 這裏不做詳細介紹.
如果不瞭解如何安裝配置mysql可以參考這個地址: 點擊打開鏈接
二. ADO方式連接MySql
1. 導入ado數據庫, 在你的程序中添加下面語句來導入ado數據庫
- // no_namespace rename("EOF", "adoEOF")防止命名重複,將EOF重命名爲adoEOF
- #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環境
//初始化com環境
AfxOleInit();
3. 創建數據表結構,用來保存從數據庫中獲取的內容
假設數據表只有兩個字段:用戶ID與用戶名
typedef struct _OBJ_USER
{
int User_ID;
TCHAR User_Name[32];
}OBJ_USER;
4.創建操作數據庫的類operator類
- 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;
- };
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類的定義
- 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;
- }
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;
}
獲取連接字符串的方法:
- strConnectionName.Format(_T("DATABASE=%s;DSN=myodbc;OPTION=0;PWD=%s;PORT=0;SERVER=localhost;UID=%s;"),
- 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語句操作的接口
- 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;
- }
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. 從數據庫中獲取數據
- 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;
- }
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語句可以實現往數據中插入數據, 但是插入圖片或二進制大數據這種方式並不適合.所以單獨將插入與更新操作實現,支持大數據的操作
- 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;
- }
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. 更新數據庫中的數據
- 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;
- }
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可以很方便開發程序.