Visual C++ 提供提供了多種數據庫訪問技術,其中最主要的是開放式數據庫連接(Open Database Connectivity, ODBC)和數據存取對象(Data Access Object, DAO)兩種數據庫訪問技術。
ODBC是技術上成熟的可靠標準接口,這裏介紹它的使用。
1. ODBC概述
ODBC建立了一組數據庫訪問規範,爲用戶提供簡單、標準、透明和統一的數據庫訪問的編程接口(API),使應用程序獨立於DBMS(數據庫管理系統)。ODBC API作爲數據庫的一種底層訪問技術,支持SQL語言,並且用戶可以直接將SQL語句提交給ODBC。
ODBC體系的4大組件:
(1) 應用程序:執行處理並調用ODBC API函數,提交SQL語句並獲取結果
(2) 驅動程序管理器(driver manager):根據應用程序的需要加載或卸載驅動程序,處理ODBC API函數調用,或將函數調用轉交給ODBC驅動程序。包括一組ODBC API函數,它們位於ODBC32.dll動態連接庫中
(3) ODBC驅動程序(driver):處理ODBC API函數調用,提交SQL請求到一個指定的數據源,並把結果返回給應用程序。ODBC驅動程序通常是一個DLL文件。
(4) 數據源(data source):應用程序要連接一個數據庫,首先必須設置一個數據源。一個數據源包含了用戶要訪問的數據庫以及相關的DBMS、網絡平臺等信息。
ODBC技術對數據庫的操作不依賴於具體的DBMS,不直接與DBMS打交道,所有的數據庫操作由對應的DBMS的ODBC驅動程序完成。
但注意ODBC API並不能直接訪問數據庫。驅動程序管理器負責將應用程序對ODBC API的調用傳遞給對應的ODBC驅動程序,由驅動程序完成相應的操作(安全性考慮)。
2. MFC ODBC數據庫類
MFC的ODBC類對複雜的ODBC API進行了封裝,提供了簡化的調用接口,從而方便了開發使用。如果要對數據庫底層操作,也可以直接調用ODBC API。
MFC的ODBC數據庫類主要包括:
(1)CDatabase:建立與數據源的連接
(2)CRecordSet:從數據源中提取的記錄集。CRecordSet類對象有動態行集和快照集兩種形式,每一種在記錄集被打開時都提供一組記錄。動態行集:能保持與其他用戶所做的更改同步,快照集:數據的靜態視圖。
(3)CRecordView:連接到CRecordSet對象的表單視圖,CFormView的派生類,用於顯示數據庫記錄。
(4)CFieldExchange:支持記錄字段交換
(5)CDBException:用於處理ODBC類產生的異常。
總之,CDatabase針對某個數據庫,負責連接數據源;CRecordSet針對數據源中的記錄集,負責對記錄的操作;CRecordView負責可視化界面;CFieldExchange負責CRecordSet與數據源的數據交換。
3. 編程示例
要使用ODBC對數據庫操作,首先利用ODBC數據源管理器配置與數據庫相對應的數據源,然後再設計應用程序的實現。
(1)數據庫應用程序
CRecordView使用:提供ID_RECORD_FIRST、ID_RECORD_LAST、ID_RECORD_NEXT、ID_RECORD_PREV等命令的支持,用於滾動記錄,成員函數OnMove()處理這些命令消息。
BOOL CRecordView::OnMove(UINT nIDMoveCommand)
{
CRecordSet *pSet = OnGetRecordSet();
if(pSet->CanUpdate())
{
pSet->Edit();//進入編輯模式
if(!UpdateData())//將控件中數據更新到記錄集對象的域數據成員(field dtaa)中
return TRUE;
pSet->Update();//域數據成員(field dtaa)的值寫入數據源
}
switch(nIDMoveCommand)//處理4個不同命令
{
case ID_RECORD_PREV:
pSet->MovePrev();
if(!pSet->IsBOF())
break;
case ID_RECORD_FIRST:
pSet->MoveFirst();
break;
case ID_RECORD_NEXT:
pSet->MoveNext();
if(!pSet->IsEOF())
break;
if(!pSet->CanScroll())//Clear out screen since we're sitting on EOF
{
pSet->SetFieldNull(NULL);
break;
}
case ID_RECORD_LAST:
pSet->MoveLast();
break;
default:
ASSERT(FALSE);
}
// show the result of move operation
UpdateData(FALSE); // 把新的當前記錄(move操作之後)的內容直入表單視圖的控件內
return TRUE;
}
調用了CRecordSet類的多種用於滾動記錄的成員函數,它們在滾動到一個新的紀錄時會把該記錄傳遞到域數據成員中。OnMove()函數完成了兩次表單控件和數據源的數據交換。
(2)支持刪除和添加記錄功能
上面是對數據庫的瀏覽功能,除此以外,還有修改功能、添加和刪除記錄功能。
pSet->AddNew(); // 添加記錄
pSet->Delete(); // 刪除記錄
UpdateData(FALSE); // 更新表單視圖
pSet的滾動操作:
pSet->MoveNext();
if(pSet->IsEOF())//滾出了記錄集的邊界,則滾動到最後一個記錄
pSet->MoveLast();
if(pSet->IsBOF())//如果記錄變空了,則清除域數據成員
pSet->SetFieldNull(NULL);
UpdateData(FALSE);//更新表單視圖
查詢
pSet->Query();