本文的目的是让你感到ADO没有什么可怕的,而不是ADO的细节。我甚至没有告诉你ADO能做什么。ADO比DAO更快、更容易使用、更强大。
完美的ADO
我们都很熟悉CDatabase和CDaoDatabase。它们相对比较容易去使用,它们很好地配合我们的应用程序,and they are easily distributed.使用CRecordset类,你很容易建立强大的数据库运用。
现在,当你刚刚感到用c++开发数据库项目有点把握的时候,微软推出一个叫UDA(Univeral Data Access数据统一访问)和一个相对简单,但缺乏文档说明的ADO(ActiveX Data Object)。非常不幸,微软的家伙们认为没有必要提供任何样子的文档Visual C开发人员。如果你试图从网上搜索,你会发现很难找倒有关ADO的好例子。
和ADO相处几个月后,我开始对ADO产生好感,可能将来我不用其它而只用ADO开发数据库。当你认识到ADO是多么容易使用、多么强大,你可能就会和我想的一样了。当我用DAO编写通用Recordset时,有一简单的方法使用数据动态绑定,那就是在查询(query)而不是表(table)上建立recordset。而对于ADO,缺省使用的就是数据动态绑定,这正是我喜欢ADO的原因之一。
开始
在你使用ADO之前,你必须让你的应用程序知道你将使用它。在stdfx.h文件中,你必须加入以下代码:
这行代码的基本意思是使用ADO,但不使用命名空间,并且将EOF改成adoEOF。你必须重命名EOF,是因为常量冲突。加入上述代码后,你不需要在#include,不需要连接别的什么到你的应用程序中了。
先看看ADO的部件(pieces):_ConnectionPtr, _CommandPtr, and _RecordsetPtr (本文不涉及_CommandPtr)
像相应的DAO和CDatabase一样,ADO也有几个部件。和DAO、CDatabase不同,ADO是基于COM的。一个令人不那么愉快的事情是学习ADO,你被迫学习一些COM知识(这也是好事,因为作为windows开发人员,你迟早会走上这条不归路)。ADO的三个部件是Connection、Command、Recordset。
Connection返回recordset或者NULL。一般来说,你使用它连接数据库,并(或)执行SQL语句,而不返回任何东西。当Connection对象返回一个recordset,那不是一个最好的方法。像CDaoDatabase一样,你(大多数情况)使用Connection对象连接数据库,而用其它对象访问数据。
Command返回一个recordset,并允许你运行返回一个recordset的存储程序(stored procedures)或任何SQL语句。你可以使用全局的Connetcion连接数据库,或者你可以在打开command的时候告诉它连接语句。当你进行一次性连接时,这是一个好特性。但如果你需要建立大量recordset,你会用Connection对象去连接数据库,而用Command对象运行存储程序。
而Recordset是...噢,就是recordset。它提供多一些对于recordset的控制(例如锁定、光标等...)。有了Command你不需要一个打开的connection。如果包含一个connection语句,而不是指向connection对象的指针,你的Recordset就可以使用了。如果你使用多个recordset,最好的方法是Connection对象连接数据库,用recordset对象处理recordset。
我在本文要说的两个部件是Connection和Recordset。
_ConnectionPtr,是Connection接口。类似于CDatabaseCDaoDatabase。它们的使用方法基本上一样。你先建立_ConnectionPtr的一个实例,通过ODBC或数据提供者指向数据库,然后打开它。看看它和CDaoDatabase有多类似:
现在看看ado:
_RecordsetPtr,是recordset接口。和CDaoRecordset类似。一旦你发现_RecordsetPtr和CDaoRecordset是这么类似,你会后悔不早点使用ADO。让我们看看它们如何工作(我们将用前面代码的数据库和connection)
ADO是相对辣手一点,但使用ADO的优点(不在本文讨论范围之内)值得你去使用它。
现在我们有了一个connection和一个recordset,让我们读取一些数据吧。我们使用recordset中的数据去填充列表筐(假设我们已经有一个名为m_list的列表筐)。
DAO:
ADO:
需要特别注意的是:没有文档提到GetCollect方法,我搜索了任何地方,没有人提到它。另外一个返回数据的方法是:
我更喜欢GetCollect。
动态绑定 vs DFX:
动态绑定允许你使用任何合法的SQL语句建立一个记录集并返回一些东西。例如,想象一下用DFX建立一个允许你求几个域的和记录集:
SELECT (SUM(field_1) + SUM(field_2)) AS answer FROM some_table
这不是一个容易的任务,这正是动态绑定的优点。另外一个优点是代码的精简。动态绑定使你的应用程序更小并容易维护。最后,根据微软所说,动态绑定是推荐的从数据源获取数据的方法。既然动态绑定更具弹性、更快、更容易维护,我们还要求什么?
大部分的应用,你可以使用单一(全局)的connetction连接数据库,然后建立多个recordset。如果你已经用大量recordset写了一些应用程序,那么你知道DFX在你的应用程序中加入了大量的代码。全部这些代码的结果是动态绑定。
_variant和_bstr_t不好么?
不幸的是,CString变成了COM所需要的类型(叹气,CStringEx也是)。因为COM是跨开发平台的,它需要一个更通用的方法去处理字符串和另外的数据。这个通用的方法是什么?答案是VARIANT类型和BSTR类型。VARIANT基本上是你能想到的所有数据类型(除了char*)的联合。BSTR基本上是一个字符串和串长的变量(代替char*)。
处理它们真的会令屁股非常的痛。因此键入_variant_t和_bstr_t。基本上(非常基本),_variant_t类封装了VARIANT类型并允许我们简单地使用类型转换。这简化了使用VARIANT。_bstr_t做BSTR同样的事情。在例子中,你可以看到我怎样从GetCollect方法中取得VARIANT,然后将它放入_bstr_t,接着转换成char*类型,或者我将_variant_t转换成long、double或任何东西。
对比不使用_variant和_bstr_t:
相当不同。
修改、插入和删除:
进行修改、插入和删除操作的时候,通常我喜欢使用Connection对象或Command对象。原因是这样似乎就是简单地用CString建立SQL语句,然后执行它们。但是你可以使用Recordset对象的三个方法:
Update方法可以在使用下面三种方法之一的基础上修改记录:
1、给Field对象的Value属性赋值,然后调用Update方法;
2、调用Update方法时,传输域名和值作为参数;
3、调用Update方法时,传输一个域名数组和一个值数组作为参数。
AddNew方法使用一个域数组和相对应的值数组作为参数。
Delete方法删除当前记录或者当前过滤器过滤的记录。
在三个方法中,你必须使用Requery方法刷新记录。
简单的代码:
本文包含的简单代码是一个MFC简单应用程序。在CWinApp中,我声明了_connectionPtr、_CommandPtr和_RecordsetPtr接口。
有趣的是,(在vc6.0中),当键入"m_pConnection.",你将得到一个函数和成员的下拉列表;但是你键入"m_pConnection->"时,你会得到另外一个完全不同的函数和成员列表。这是因为你实际上指向两个不同的东西。当键入"."时,你看到的是一个智能指针;而"->"是你建立的东西的指针(_ConnetctionPtr等)。这就是为什么你看到两行代码的原因,一行使用".",另外一行使用"->"。
回到例子代码。在应用程序初始化实例时,我打开了连接。它指向我的系统中的一个数据库。你可能必须修改它指向你的数据库(ODBC)或者使用UDA提供者提供一个数据库。
如果你打开about对话框,你会看到一个列表框。你会看到一个叫button1的按纽,这个按纽正是ADO这块肥肉的落脚点。我先建立recordset接口的实例,然后在我想要的查询中我打开recordset,然后遍历记录集。
记得使用try和catch,否则ADO会粉碎你的应用程序。你应该catch _com_error 和...,在任何时候。
我必须尝试让它简单些。我省略了大量的细节,忽略了一些好的编程习惯(例如,检查大部分COM方法都返回的HRESULT)。本文的目的是让你感到ADO没有什么可怕的,而不是ADO的细节。我甚至没有告诉你ADO能做什么。ADO比DAO更快、更容易使用、更强大。
有两本好书帮助你开始使用ADO。一本是免费的(免费的噢),在http://www.mcp.com/;另外一本你得掏钱。(两本我都要,除非你在浴室和床上有一台电脑)。
这是WROC出版社的"ADO 2.0"。这本书,像其它书一样,很少c++例子。但是它是所有的方法和属性的好参考。你使用ADO之后,将例子代码转化成c++代码十分简单。另外一本,是"Learning Programming with Visual C++ in 21 days"。是的,我知道那些"in 21 days"的书很臭,当另外的程序开发人员在你身边的时候,你买这样的书是很尴尬的,你会将书藏到书架中。但这本书不是这样的,它里面的信息很好。或者你可以在http://www.mcp.com/读这本书。两本都很好。"21 Days"让你明白怎样去使用ADO(好东西),另外一本告诉你怎样设计数据库等等(也很好,基本资料)。