ADO MFC 包装类。






4.17/5 (10投票s)
2002年8月12日
3分钟阅读

152228

10378
类似于 CDatabase 和 CRecordset 的 ADO 类。
引言
为了完成一项工作任务,我需要创建一组类来使用 ADO 从数据库中读取数据。在过去的几个月里,我使用了大量来自 Code Project 的代码,我决定尝试回馈一些东西。
使用 ADO/OLE DB 优于 ODBC 的优点是:
- 速度提高,
- 提供程序的灵活性(如果您创建自定义 OLE DB 提供程序,您可以使用这些类来供您的使用者使用),
- 数据库访问的行业标准,...
如果您将要使用 VB,那么几乎没有理由不使用 ADO,因为 VB 提供了一个非常用户友好的 ADO 界面。
Visual C++ 没有提供用户友好的 ADO 界面。 MSDN 和其他站点(例如 Bob Place 在 CodeGuru 上的文章)上有代码示例,但 MFC 中没有内置支持。任何熟悉 MFC 和类向导的人,肯定会欣赏在使用 ODBC 进行静态绑定时所给予的帮助。当您将要从表中读取/更新多行时,静态绑定是一种更快地读取数据库的方法。就我的目的而言,这种效率至关重要。这些类和向导使这项工作变得轻而易举。
使用 CDatabase
、CRecordset
和 CDBVariant
提供的界面非常适合执行动态绑定,并且是标准 MFC。我希望为使用 ADO 提供一个基本上等效的界面。
像所有喜欢代码重用的程序员一样,创建此界面的第一步是查看已经提供了什么。我在这里找到了 CodeProject 上的两篇文章,它们提供的几乎完全是我所需要的。它们是 Carlos Antollini 的 ADO 类和 Ly Nguyen 的 ADO 数据绑定类向导。
基本上,我的工作涉及集成这些并提供一个尽可能类似于 CRecordset
和 CDatabase
的界面。
这些类提供了动态绑定的所有功能(同时还将转换为 MFC 类型,从 VARIANT
类型)以及一个非常简单的静态绑定界面。
所有涉及 ADO 和 COM 的细节和异常都已被封装。
这是一个使用动态绑定类的非常简单的例子
// use the jet to read, we know the layout each
// record so we call the getfieldvalues w/
// the pre-known datatypes for the columns.
// CADODatabase db;
//
// BOOL bOpen = db.Open("s:\\tim\\climet.mdb", "Admin",
// "", "Microsoft.Jet.OLEDB.3.51");
// CADORecordset rs(&db);
//
// BOOL bRsOpen = rs.Open("select * from client_dim");
//
// int nRows = rs.GetRecordCount();
//
// int nKey;
// CString strCliNm, strCliDesc;
//
// BOOL fok = TRUE;
//
// fok = rs.GetFieldValue(0, nKey);
// fok = rs.GetFieldValue(1, strCliNm);
// fok = rs.GetFieldValue(2, strCliDesc);
//
// db.Close();
这是一个使用静态绑定类的非常简单的例子
首先,我们使用附带的向导(Ly Nguyen 的应用程序略有修改)来生成从 CADORecordBinding
和 CADORecordset
派生的类
在后面的步骤中,向导允许您指定一个表,向导为您生成绑定宏调用(ADO_FIXED_LENGTH_ENTRY
等)。当然,您需要在项目文件中添加标头,并在项目设置中添加 .dll 的标头路径
首先是 CADORecordset
派生类(向导的输出)
/////////////////////////////////////////////////////////////////////////////
// CClientPlanRS class
class CClientPlanRS : public CADORecordBinding, public CADORecordset
{
BEGIN_ADO_BINDING(CClientPlanRS)
ADO_FIXED_LENGTH_ENTRY ( 1,
adInteger, m_lClient_Key, m_ulClient_KeyStatus, TRUE)
ADO_VARIABLE_LENGTH_ENTRY2( 2,
adVarWChar, m_szClient_Name, sizeof(m_szClient_Name),
m_ulClient_NameStatus, TRUE)
ADO_VARIABLE_LENGTH_ENTRY2( 3,
adVarWChar, m_szClient_Description,
sizeof(m_szClient_Description),
m_ulClient_DescriptionStatus, TRUE)
END_ADO_BINDING()
//Attributes
public:
LONG m_lClient_Key;
ULONG m_ulClient_KeyStatus;
CHAR m_szClient_Name[51];
ULONG m_ulClient_NameStatus;
CHAR m_szClient_Description[256];
ULONG m_ulClient_DescriptionStatus;
CClientPlanRS(CADODatabase* pDb, int nCacheSize = -1) :
CADORecordBinding(),
CADORecordset(pDb, nCacheSize)
{ SetRecordBinding(this); }
};
现在使用它。我们将使用 Microsoft OLE DB for ODBC 提供程序,因此我们不必指定提供程序参数。此外,我们将使用 ODBC DSN 进行连接。
// bOpen = db.Open("CLIMET", "TDK2", "NOONHIGH");
//
// CClientPlanRS CliRs(&db);
//
//
// //read table:
// bRsOpen = CliRs.Open("select * from client_dim");
//
// while (!CliRs.IsEOF())
// {
// //do something w/ the records
// CliRs.MoveNext();
// }
//
// //update the first existing row:
// CliRs.MoveFirst();
//
// strcpy(CliRs.m_szClient_id_name, "MAYO999");
// BOOL bUpdate = CliRs.Update();
//
// //add a new row:
// CliRs.m_lClient_id = 999;
// strcpy(CliRs.m_szClient_id_name, "PICKLE");
// strcpy(CliRs.m_szClient_id_desc, "Pickle Inc");
// BOOL bAdd = CliRs.AddNew();
//
重要的是要注意,这些类不会抛出异常。相反,它们的方法返回 BOOL
。
代码本身有大量的注释,请仔细阅读以获取更多详细信息。
历史
- 2002 年 8 月 12 日:初始版本
许可证
本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。
作者可能使用的许可证列表可以在此处找到。