昨天晚上学MFC的ADO,跟着书上的讲解和例子,完成了ADO的初级使用。首先,在使用ADO变成之前,必须做必要的配置。在工程文件StdAfx.h的代码最后,添加一句配置代码,代码如下:[cpp] view plaincopyprint?#import "C:/Program Files/Common Files/System/ado/msado15.dll" no_namespace/ rename("EOF","DB_EOF")rename("BOF","DB_BOF") //导入ADO动态链接库 #import "C:/Program Files/Common Files/System/ado/msado15.dll" no_namespace/ rename("EOF","DB_EOF")rename("BOF","DB_BOF") //导入ADO动态链接库 然后,在工程中的应用程序类xxxApp的BOOL CxxxApp::InitInstance()函数中初始化COM环境。也就是在该函数中加入一句代码,代码如下:[cpp] view plaincopyprint?CoInitialize(NULL);//初始化COM环境 CoInitialize(NULL);//初始化COM环境当以上配置完全后,可以进行ADO操作,由于数据库操作方法类似,可以将数据库操作封装到某个ADO的类中,让每个需要ADO操作的类对其进行调用。这里,直接使用书籍上的实例代码,代码如下:DBBase.h[cpp] view plaincopyprint?// DBBase.h: interface for the DBBase class. // // #if !defined(AFX_DBBASE_H__08DE1FB3_6716_4CAD_B119_252BE6F58101__INCLUDED_) #define AFX_DBBASE_H__08DE1FB3_6716_4CAD_B119_252BE6F58101__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class DBBase { public: DBBase(); virtual ~DBBase(); void OnInitADOConn(); _RecordsetPtr& OpenRecordset(CString sql); //打开记录集 void CloseRecordset(); void CloseConn(); UINT GetRecordsetCount(_RecordsetPtr pRecrodset);//获得记录数 public: _ConnectionPtr m_pConnection; _RecordsetPtr m_pRecordset; }; #endif // !defined(AFX_DBBASE_H__08DE1FB3_6716_4CAD_B119_252BE6F58101__INCLUDED_) // DBBase.h: interface for the DBBase class.#if !defined(AFX_DBBASE_H__08DE1FB3_6716_4CAD_B119_252BE6F58101__INCLUDED_)#define AFX_DBBASE_H__08DE1FB3_6716_4CAD_B119_252BE6F58101__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000class DBBase {public:DBBase();virtual ~DBBase();void OnInitADOConn();_RecordsetPtr& OpenRecordset(CString sql); //打开记录集void CloseRecordset();void CloseConn();UINT GetRecordsetCount(_RecordsetPtr pRecrodset);//获得记录数public:_ConnectionPtr m_pConnection;_RecordsetPtr m_pRecordset;};#endif // !defined(AFX_DBBASE_H__08DE1FB3_6716_4CAD_B119_252BE6F58101__INCLUDED_) DBBase.cpp[cpp] view plaincopyprint?// DBBase.cpp: implementation of the DBBase class. // // #include "stdafx.h" #include "ADO.h" #include "DBBase.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif // // Construction/Destruction // DBBase::DBBase() { } DBBase::~DBBase() { } void DBBase::OnInitADOConn() { ::CoInitialize(NULL); try { m_pConnection.CreateInstance("ADODB.Connection"); //创建连接对象实例 _bstr_t strConnect="DRIVER={Microsoft Access Driver (*.mdb)};/ uid=;pwd=;DBQ=DataBase.mdb;"; m_pConnection->Open(strConnect,"","",adModeUnknown); //打开数据库 } catch(_com_error e) { AfxMessageBox(e.Description()); //弹出错误处理 } } _RecordsetPtr& DBBase::OpenRecordset(CString sql) { ASSERT(!sql.IsEmpty()); //SQL语句不能为空 try { m_pRecordset.CreateInstance(__uuidof(Recordset)); //创建记录集对象实例 m_pRecordset->Open(_bstr_t(sql), m_pConnection.GetInterfacePtr(), adOpenDynamic, adLockOptimistic, adCmdText); //执行SQL得到记录集 } catch(_com_error e) //捕获可能的异常 { AfxMessageBox(e.Description()); } return m_pRecordset; } void DBBase::CloseRecordset() { if(m_pRecordset->GetState() == adStateOpen) //判断当前的记录集状态 m_pRecordset->Close(); //关闭记录集 } void DBBase::CloseConn() { m_pConnection->Close(); //关闭数据库连接 ::CoUninitialize(); //释放COM环境 } UINT DBBase::GetRecordsetCount(_RecordsetPtr pRecordset) { int nCount = 0; //声明保存记录数的变量 try{ pRecordset->MoveFirst(); //将记录集指针移动到第一条记录 } catch(...) //捕捉可能出现的错误 { return 0; //产生错误时返回0 } if(pRecordset->DB_EOF) //判断记录集中是否没有记录 return 0; //无记录时返回0 while (!pRecordset->DB_EOF) //当记录集指针没有指向最后时 { pRecordset->MoveNext(); //将记录集指针移动到下一条记录 nCount = nCount + 1; //记录个数的变量加1 } pRecordset->MoveFirst(); //将记录集指针移动到第一条记录 return nCount; //返回记录数 } // DBBase.cpp: implementation of the DBBase class.#include "stdafx.h"#include "ADO.h"#include "DBBase.h"#ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE[]=__FILE__;#define new DEBUG_NEW#endif Construction/Destruction//DBBase::DBBase(){}DBBase::~DBBase(){}void DBBase::OnInitADOConn(){::CoInitialize(NULL);try{ m_pConnection.CreateInstance("ADODB.Connection"); //创建连接对象实例 _bstr_t strConnect="DRIVER={Microsoft Access Driver (*.mdb)};/uid=;pwd=;DBQ=DataBase.mdb;"; m_pConnection->Open(strConnect,"","",adModeUnknown); //打开数据库}catch(_com_error e){AfxMessageBox(e.Description()); //弹出错误处理}}_RecordsetPtr& DBBase::OpenRecordset(CString sql){ASSERT(!sql.IsEmpty()); //SQL语句不能为空try{m_pRecordset.CreateInstance(__uuidof(Recordset)); //创建记录集对象实例m_pRecordset->Open(_bstr_t(sql), m_pConnection.GetInterfacePtr(),adOpenDynamic, adLockOptimistic, adCmdText); //执行SQL得到记录集}catch(_com_error e) //捕获可能的异常{AfxMessageBox(e.Description());}return m_pRecordset;}void DBBase::CloseRecordset(){if(m_pRecordset->GetState() == adStateOpen) //判断当前的记录集状态m_pRecordset->Close(); //关闭记录集}void DBBase::CloseConn(){m_pConnection->Close(); //关闭数据库连接::CoUninitialize(); //释放COM环境}UINT DBBase::GetRecordsetCount(_RecordsetPtr pRecordset){int nCount = 0; //声明保存记录数的变量try{pRecordset->MoveFirst(); //将记录集指针移动到第一条记录}catch(...) //捕捉可能出现的错误{return 0; //产生错误时返回0}if(pRecordset->DB_EOF) //判断记录集中是否没有记录return 0; //无记录时返回0while (!pRecordset->DB_EOF) //当记录集指针没有指向最后时{pRecordset->MoveNext(); //将记录集指针移动到下一条记录nCount = nCount + 1; //记录个数的变量加1}pRecordset->MoveFirst(); //将记录集指针移动到第一条记录return nCount; //返回记录数}以上工作做好后,我们可以进行ADO的增删改查了,这里,仅将函数代码贴出,具体代码理解看个人能力:增加数据:[cpp] view plaincopyprint?void CADODlg::OnBtnAdd() { // TODO: Add your control notification handler code here UpdateData(TRUE); if(m_id.IsEmpty() || m_name.IsEmpty() || m_culture.IsEmpty() || m_test.IsEmpty()) { MessageBox("基础信息不能为空!"); return; } DBBase m_DBBase; m_DBBase.OnInitADOConn(); CString sql = "select * from employees"; m_DBBase.m_pRecordset = m_DBBase.OpenRecordset(sql); try { m_DBBase.m_pRecordset->AddNew(); m_DBBase.m_pRecordset->PutCollect("编号",(_bstr_t)m_id); m_DBBase.m_pRecordset->PutCollect("姓名",(_bstr_t)m_name); m_DBBase.m_pRecordset->PutCollect("学历",(_bstr_t)m_culture); m_DBBase.m_pRecordset->PutCollect("测试",(_bstr_t)m_test); m_DBBase.m_pRecordset->Update(); m_DBBase.CloseRecordset(); m_DBBase.CloseConn(); } catch(...) { MessageBox("数据库操作失败!"); return; } MessageBox("数据库添加数据成功!"); m_grid.DeleteAllItems(); AddToGrid(); } void CADODlg::OnBtnAdd() {// TODO: Add your control notification handler code hereUpdateData(TRUE);if(m_id.IsEmpty() || m_name.IsEmpty() || m_culture.IsEmpty() || m_test.IsEmpty()){MessageBox("基础信息不能为空!");return;}DBBase m_DBBase;m_DBBase.OnInitADOConn();CString sql = "select * from employees";m_DBBase.m_pRecordset = m_DBBase.OpenRecordset(sql);try{m_DBBase.m_pRecordset->AddNew();m_DBBase.m_pRecordset->PutCollect("编号",(_bstr_t)m_id);m_DBBase.m_pRecordset->PutCollect("姓名",(_bstr_t)m_name);m_DBBase.m_pRecordset->PutCollect("学历",(_bstr_t)m_culture);m_DBBase.m_pRecordset->PutCollect("测试",(_bstr_t)m_test);m_DBBase.m_pRecordset->Update();m_DBBase.CloseRecordset();m_DBBase.CloseConn();}catch(...){MessageBox("数据库操作失败!");return;}MessageBox("数据库添加数据成功!");m_grid.DeleteAllItems();AddToGrid();}修改数据:[cpp] view plaincopyprint?void CADODlg::OnBtnEdit() { // TODO: Add your control notification handler code here UpdateData(TRUE); if(m_id.IsEmpty() || m_name.IsEmpty() || m_culture.IsEmpty() || m_test.IsEmpty()) { MessageBox("基础信息不能为空!"); return; } int pos = m_grid.GetSelectionMark(); DBBase m_dbBase; m_dbBase.OnInitADOConn(); CString sql = "select * from employees"; m_dbBase.m_pRecordset = m_dbBase.OpenRecordset(sql); try { m_dbBase.m_pRecordset->Move(pos, vtMissing); m_dbBase.m_pRecordset->PutCollect("编号", (_bstr_t)m_id); m_dbBase.m_pRecordset->PutCollect("姓名", (_bstr_t)m_name); m_dbBase.m_pRecordset->PutCollect("学历", (_bstr_t)m_culture); m_dbBase.m_pRecordset->PutCollect("测试", (_bstr_t)m_test); m_dbBase.m_pRecordset->Update(); m_dbBase.CloseRecordset(); m_dbBase.CloseConn(); } catch(...) { MessageBox("修改数据失败!如果没有选中数据,请先选中!"); return; } MessageBox("修改数据成功!"); m_grid.DeleteAllItems(); AddToGrid(); } void CADODlg::OnBtnEdit() {// TODO: Add your control notification handler code hereUpdateData(TRUE);if(m_id.IsEmpty() || m_name.IsEmpty() || m_culture.IsEmpty() || m_test.IsEmpty()){MessageBox("基础信息不能为空!");return;}int pos = m_grid.GetSelectionMark();DBBase m_dbBase;m_dbBase.OnInitADOConn();CString sql = "select * from employees";m_dbBase.m_pRecordset = m_dbBase.OpenRecordset(sql);try{m_dbBase.m_pRecordset->Move(pos, vtMissing);m_dbBase.m_pRecordset->PutCollect("编号", (_bstr_t)m_id);m_dbBase.m_pRecordset->PutCollect("姓名", (_bstr_t)m_name);m_dbBase.m_pRecordset->PutCollect("学历", (_bstr_t)m_culture);m_dbBase.m_pRecordset->PutCollect("测试", (_bstr_t)m_test);m_dbBase.m_pRecordset->Update();m_dbBase.CloseRecordset();m_dbBase.CloseConn();}catch(...){MessageBox("修改数据失败!如果没有选中数据,请先选中!");return;}MessageBox("修改数据成功!");m_grid.DeleteAllItems();AddToGrid();} 删除数据:[cpp] view plaincopyprint?void CADODlg::OnBtnDel() { // TODO: Add your control notification handler code here int pos = m_grid.GetSelectionMark(); DBBase dbBase; dbBase.OnInitADOConn(); CString sql = "select * from employees"; dbBase.m_pRecordset = dbBase.OpenRecordset(sql); try { dbBase.m_pRecordset->Move(pos, vtMissing); dbBase.m_pRecordset->Delete(adAffectCurrent); dbBase.m_pRecordset->Update(); dbBase.CloseRecordset(); dbBase.CloseConn(); } catch(...) { MessageBox("删除数据失败!如果没有选中数据,请先选中!"); return; } MessageBox("删除数据成功!"); OnBtnClean(); m_grid.DeleteAllItems(); AddToGrid(); } void CADODlg::OnBtnDel() {// TODO: Add your control notification handler code hereint pos = m_grid.GetSelectionMark();DBBase dbBase;dbBase.OnInitADOConn();CString sql = "select * from employees";dbBase.m_pRecordset = dbBase.OpenRecordset(sql);try{dbBase.m_pRecordset->Move(pos, vtMissing);dbBase.m_pRecordset->Delete(adAffectCurrent);dbBase.m_pRecordset->Update();dbBase.CloseRecordset();dbBase.CloseConn();}catch(...){MessageBox("删除数据失败!如果没有选中数据,请先选中!");return;}MessageBox("删除数据成功!");OnBtnClean();m_grid.DeleteAllItems();AddToGrid();} 查找数据:[cpp] view plaincopyprint?void CSearchDlg::OnBtnSearch() { // TODO: Add your control notification handler code here UpdateData(TRUE); CString m_field; int pos = 0; if(m_combField.GetCurSel() == -1) pos = 0; m_combField.GetLBText(pos, m_field); if(m_content.IsEmpty() && m_field != "-1") { MessageBox("请填写要检索的数据"); return; } DBBase dbBase; CString sql = "select * from employees order by '编号' desc"; dbBase.OnInitADOConn(); dbBase.OpenRecordset(sql); CString str_search; str_search.Format("%s = '%s'", m_field, m_content); dbBase.m_pRecordset->Filter = (_bstr_t)str_search; dbBase.m_pRecordset->Requery(0); m_grid.DeleteAllItems(); int i = 0; while(!dbBase.m_pRecordset->DB_EOF) { m_grid.InsertItem(i, ""); m_grid.SetItemText(i, 0, (char *)(_bstr_t)dbBase.m_pRecordset->GetCollect("编号")); m_grid.SetItemText(i, 1, (char *)(_bstr_t)dbBase.m_pRecordset->GetCollect("姓名")); m_grid.SetItemText(i, 2, (char *)(_bstr_t)dbBase.m_pRecordset->GetCollect("学历")); m_grid.SetItemText(i, 3, (char *)(_bstr_t)dbBase.m_pRecordset->GetCollect("测试")); dbBase.m_pRecordset->MoveNext(); i++; } dbBase.CloseRecordset(); dbBase.CloseConn(); } void CSearchDlg::OnBtnSearch() {// TODO: Add your control notification handler code hereUpdateData(TRUE);CString m_field;int pos = 0;if(m_combField.GetCurSel() == -1)pos = 0;m_combField.GetLBText(pos, m_field); if(m_content.IsEmpty() && m_field != "-1"){MessageBox("请填写要检索的数据");return;}DBBase dbBase;CString sql = "select * from employees order by '编号' desc";dbBase.OnInitADOConn();dbBase.OpenRecordset(sql);CString str_search;str_search.Format("%s = '%s'", m_field, m_content);dbBase.m_pRecordset->Filter = (_bstr_t)str_search;dbBase.m_pRecordset->Requery(0);m_grid.DeleteAllItems();int i = 0;while(!dbBase.m_pRecordset->DB_EOF){m_grid.InsertItem(i, "");m_grid.SetItemText(i, 0, (char *)(_bstr_t)dbBase.m_pRecordset->GetCollect("编号"));m_grid.SetItemText(i, 1, (char *)(_bstr_t)dbBase.m_pRecordset->GetCollect("姓名"));m_grid.SetItemText(i, 2, (char *)(_bstr_t)dbBase.m_pRecordset->GetCollect("学历"));m_grid.SetItemText(i, 3, (char *)(_bstr_t)dbBase.m_pRecordset->GetCollect("测试"));dbBase.m_pRecordset->MoveNext();i++;}dbBase.CloseRecordset();dbBase.CloseConn();}以上代码中,均会使用到AddToGrid()函数,主要是将数据填充到列表视图控件中去,该函数代码为:[cpp] view plaincopyprint?void CSearchDlg::AddToGrid() { DBBase m_dbBase; m_dbBase.OnInitADOConn();//连接数据库 CString SQL = "select * from employees order by 编号 desc"; //设置查询字符串 m_dbBase.m_pRecordset = m_dbBase.OpenRecordset(SQL);//打开记录集 while(!m_dbBase.m_pRecordset->DB_EOF) { m_grid.InsertItem(0,""); m_grid.SetItemText(0,0,(char*)(_bstr_t)m_dbBase.m_pRecordset->GetCollect("编号")); m_grid.SetItemText(0,1,(char*)(_bstr_t)m_dbBase.m_pRecordset->GetCollect("姓名")); m_grid.SetItemText(0,2,(char*)(_bstr_t)m_dbBase.m_pRecordset->GetCollect("学历")); m_grid.SetItemText(0,3,(char*)(_bstr_t)m_dbBase.m_pRecordset->GetCollect("测试")); m_dbBase.m_pRecordset->MoveNext();//将记录集指针移动到下一条记录 } m_dbBase.CloseRecordset(); m_dbBase.CloseConn();//断开数据库连接 } void CSearchDlg::AddToGrid(){DBBase m_dbBase;m_dbBase.OnInitADOConn();//连接数据库CString SQL = "select * from employees order by 编号 desc"; //设置查询字符串m_dbBase.m_pRecordset = m_dbBase.OpenRecordset(SQL);//打开记录集while(!m_dbBase.m_pRecordset->DB_EOF){m_grid.InsertItem(0,"");m_grid.SetItemText(0,0,(char*)(_bstr_t)m_dbBase.m_pRecordset->GetCollect("编号"));m_grid.SetItemText(0,1,(char*)(_bstr_t)m_dbBase.m_pRecordset->GetCollect("姓名"));m_grid.SetItemText(0,2,(char*)(_bstr_t)m_dbBase.m_pRecordset->GetCollect("学历"));m_grid.SetItemText(0,3,(char*)(_bstr_t)m_dbBase.m_pRecordset->GetCollect("测试"));m_dbBase.m_pRecordset->MoveNext();//将记录集指针移动到下一条记录}m_dbBase.CloseRecordset();m_dbBase.CloseConn();//断开数据库连接} 至于OnBtnClean()函数则是将Edit控件的数据进行清除,代码如下:[cpp] view plaincopyprint?void CADODlg::OnBtnClean() { // TODO: Add your control notification handler code here m_id.Empty(); m_name.Empty(); m_culture.Empty(); m_test.Empty(); UpdateData(FALSE); } void CADODlg::OnBtnClean() {// TODO: Add your control notification handler code herem_id.Empty();m_name.Empty();m_culture.Empty();m_test.Empty();UpdateData(FALSE);} 注意:在做所有操作之前,需将数据先绑定到控件中