65.9K
CodeProject 正在变化。 阅读更多。
Home

ADO MFC 包装类。

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.17/5 (10投票s)

2002年8月12日

3分钟阅读

viewsIcon

152228

downloadIcon

10378

类似于 CDatabase 和 CRecordset 的 ADO 类。

引言

为了完成一项工作任务,我需要创建一组类来使用 ADO 从数据库中读取数据。在过去的几个月里,我使用了大量来自 Code Project 的代码,我决定尝试回馈一些东西。

使用 ADO/OLE DB 优于 ODBC 的优点是:

  1. 速度提高,
  2. 提供程序的灵活性(如果您创建自定义 OLE DB 提供程序,您可以使用这些类来供您的使用者使用),
  3. 数据库访问的行业标准,...

如果您将要使用 VB,那么几乎没有理由不使用 ADO,因为 VB 提供了一个非常用户友好的 ADO 界面。

Visual C++ 没有提供用户友好的 ADO 界面。 MSDN 和其他站点(例如 Bob Place 在 CodeGuru 上的文章)上有代码示例,但 MFC 中没有内置支持。任何熟悉 MFC 和类向导的人,肯定会欣赏在使用 ODBC 进行静态绑定时所给予的帮助。当您将要从表中读取/更新多行时,静态绑定是一种更快地读取数据库的方法。就我的目的而言,这种效率至关重要。这些类和向导使这项工作变得轻而易举。

使用 CDatabaseCRecordsetCDBVariant 提供的界面非常适合执行动态绑定,并且是标准 MFC。我希望为使用 ADO 提供一个基本上等效的界面。

像所有喜欢代码重用的程序员一样,创建此界面的第一步是查看已经提供了什么。我在这里找到了 CodeProject 上的两篇文章,它们提供的几乎完全是我所需要的。它们是 Carlos Antollini 的 ADO 类和 Ly Nguyen 的 ADO 数据绑定类向导。

基本上,我的工作涉及集成这些并提供一个尽可能类似于 CRecordsetCDatabase 的界面。

这些类提供了动态绑定的所有功能(同时还将转换为 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 的应用程序略有修改)来生成从 CADORecordBindingCADORecordset 派生的类

在后面的步骤中,向导允许您指定一个表,向导为您生成绑定宏调用(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 日:初始版本

许可证

本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。

作者可能使用的许可证列表可以在此处找到。

© . All rights reserved.