一致的数据访问技术ADO/OLE DB
一致的数据访问技术ADO/OLE DB
潘爱民 Microsoft新近推出的UDA(Universal Data Access,一致数据访问技术)为关系型或非关系型数据访问提供了一致的访问接口,为企业级Intranet应用多层软件结构提供了数据接口标准。一致数据访问包括两层软件接口,分别为ADO(Active Data Object)和OLED B,对应于不同层次的应用开发,ADO提供了高层软件接口,可在各种脚本语言(Script)或一些宏语言中直接使用;OLE DB提供了底层软件接口,可在C/C++语言中直接使用。ADO以OL E DB为基础,它对OLE DB进行了封装。一致数据访问技术建立在Microsoft的COM(组件对象模型)基础上,它包括一组COM组件程序,组件与组件之间或者组件与客户程序之间通过标准的COM接口进行通讯。 由于ADO建立在自动化(Automation)基础上,所以ADO的应用场合非常广泛,不仅可在Visual Basic这样的高级语言开发环境中使用,还可以在一些脚本语言中使用,这对于开发Web应用,在ASP(Active Server Page)的脚本代码访问数据库中提供了操作应用的捷径。本文将首先介绍ADO和OLE DB的结构模型,以便读者了解ADO与OLE DB之间的关系,然后介绍ADO的对象模型和ADO的一些特性,同时我们也将通过一些例子代码向读者展示ADO的用法。 一、一致数据访问介绍 随着网络技术和数据库技术的不断发展,现在的应用系统对数据集成的要求越来越高,这些数据有可能分布在不同的地方,并且使用不同的格式,例如关系型数据库和操作系统中的文件、电子表格、电子邮件、多媒体数据以及目录服务信息等等。传统的解决方案是使用大型的数据库系统,把所有这些数据都移到数据库系统中,然后按照操作数据库的办法对这些数据进行访问,这样做虽然能够按统一的方式对数据进行各种操作,但这种间接访问方式带来了很多问题,比如数据更新不及时、空间资源的冗余和访问效率低等等。 Microsoft公司推出的一致数据访问技术则较好地解决了这些问题,它使得应用通过一致的接口来访问各种各样的数据,而不管数据驻留在何处,也不需要进行数据转移或复制、转换,在实现分布式的同时也带来了高效率。并且UDA技术在统一数据访问接口的同时,它的多层结构使数据使用方有了更多的选择机会,而它强大的扩展能力也给数据提供方留下了更多的扩展余地,这种开放型的软件结构使它具有极强的生命力,所以,这种技术从一推出便获得了广泛的欢迎,可以说,UDA技术是继ODBC之后的又一数据访问技术的飞跃。 UDA技术包括OLE DB和ADO两层标准接口,OLE DB是系统级的编程接口,它定义了一组COM接口,这组接口封装了各种数据系统的访问操作,这组接口为数据使用方和数据提供方建立了标准,OLE DB还提供了一组标准的服务组件,用于提供查询、缓存、数据更新、事务处理等操作,因此,数据提供方只需实现一些简单的数据操作,在使用方就可以获得全部的数据控制能力。 ADO是应用层的编程接口,它通过OLE DB提供的COM接口访问数据,它适合于各种客户机/服务器应用系统和基于Web的应用,尤其在一些脚本语言中访问数据库操作是ADO的主要优势。ADO是一套用自动化技术建立起来的对象层次结构,它比其他的一些对象模型如DAO(Data Access Object)、RDO(Remote Data Object)等具有更好的灵活性,使用更为方便,并且访问数据的效率更高。 图1显示了统一数据访问的软件层次模型。图1 UDA的层次结构图 从图中我们可以看出,应用程序既可以通过ADO访问数据也可以直接通过OLE DB访问数据,而ADO则通过OLE DB访问底层数据。而且,OLE DB分成两部分,一部分由数据提供者实现,包括一些基本功能,如获取数据、修改数据、添加数据项等;另一部分由系统提供, 包括一些高级服务,如游标功能、分布式查询等等。这样的层次结构既为数据使用者即应用程序提供了多种选择方案,又为数据提供方简化了服务功能的实现手段,它只需按OLED B规范编写一个COM组件程序即可,使得第三方发布数据更为简便,而在应用程序方可以得到全面的功能服务,这充分体现了OLE DB两层结构的优势。 由于OLE DB和ADO都以COM组件的形式实现,所以COM组件的各种特性也使得构建数据应用更为灵活,而不仅仅局限于一般的客户机/服务器或Web应用模型,它既适合于以数据为中心的应用,也适合于多层结构的分布式软件系统。通过对COM组件的配置,我们可以建立各种复杂的应用系统。利用从COM到DCOM的位置透明技术,我们可以很方便地建立分布式应用系统;利用MTS(Microsoft Transaction Server)运行环境,我们也可以在数据访问一层增加安全性控制,并利用MTS的对象管理使数据访问效率更高。所有这些功能都无需数据提供方编写代码实现,只需在DCOM或MTS环境中进行常规的配置即可。 可以说一致的数据访问技术的核心是OLE DB,OLE DB建立了数据访问的标准接口,它把所有的数据源经过抽象形成行集(rowset)的概念。OLE DB模型主要包括以下一些COM对象: (1)数据源(Data Source)对象 数据源对象对应于一个数据提供者,它负责管理用户权限、建立与数据源的连接等初始操作。 (2)会话(Session)对象 在数据源连接的基础上建立会话对象,会话对象提供了事务控制机制。 (3)命令(Command)对象 数据使用者利用命令对象执行各种数据操作,如查询命令、修改命令等。 (4)行集(Rowset)对象 提供了数据的抽象表示,它可以是命令执行的结果,也可以直接由会话对象产生,它是应用程序主要的操作对象。 OLE DB的对象模型非常简单,这种简单性也带来了灵活性,从上面的几个COM对象也可以看出这一点。下面我们将从应用层角度出发,通过建立在OLE DB基础上的ADO对象模型结构的分析和使用以帮助读者进一步理解一致数据访问技术。 二、ADO对象模型 ADO对象模型定义了一组可编程的自动化对象,可用于Visual Basic、Visual C++、Java以及其他各种支持自动化特性的脚本语言。ADO最早被用于Microsoft Internet In formation Server中访问数据库的接口,与一般的数据库接口相比,ADO可更好地用于网络环境,通过优化技术,它尽可能地降低网络流量;ADO的另一个特性是使用简单,不仅因为它是一个面向高级用户的数据库接口,更因为它使用了一组简化的接口用以处理各种数据源。这两个特性使得ADO必将取代RDO和DAO,成为最终的应用层数据接口标准。 从图1我们也看到了ADO实际上是OLE DB的应用层接口,这种结构也为一致的数据访问接口提供了很好的扩展性,而不再局限于特定的数据源,因此,ADO可以处理各种OLE DB支持的数据源。 图2是ADO的对象模型图。图2 ADO对象模型 在ADO模型中,主体对象只有3个:Connection、Command和Recordset,其他4个集合对象Errors、Properties、Parameters和Fields分别对应Error、Property、Parameter和Field对象,整个ADO对象模型由这些对象组成。 一个典型的ADO应用使用Connection对象建立与数据源的连接,然后用一个Command对象给出对数据库操作的命令,比如查询或者更新数据等,而Recordset用于对结果集数据进行维护或者浏览等操作。Command命令所使用的命令语言与底层所对应的OLE DB数据源有关,不同的数据源可以使用不同的命令语言,对于关系型数据库,通常使用SQL作为命令语言。 在Connection、Command和Recordset 3个对象中,Command对象是个可选对象,它是否有效取决于OLE DB数据提供者是否实现了ICommand接口。由于OLE DB可提供关系型数据源也可以提供非关系型数据源,所以在非关系型数据源上使用传统的SQL命令查询数据有可能无效,甚至Command命令对象也不能使用。 从结构上看,ADO模型非常简单,但使用上又非常灵活,下面我们先从单个对象的角度进行讨论: (1) Connection对象 Connection对象代表与数据源之间的一个连接,ADO的Connec tion对象封装了OLE DB的数据源对象和会话对象。根据OLE DB提供者的不同性能,Conne ction对象的特性也有所不同,所以Connection对象的方法和属性不一定都可以使用。利用Connection对象,我们可以完成以下一些基本设置操作。 a.通过ConnectionString、ConnectionTimeOut和Mode属性设置连接串、超时信息、访问模式。 b.还可以设置CursorLocation属性以便指定使用客户端游标,以便在客户程序中使用批处理修改方式。 c.设置连接的缺省数据库属性DefaultDatabase。 d.设置OLE DB提供者的属性Provider。 e.通过Open和Close控制Connection对象与物理数据源的连接。 f.通过Execute方法执行命令。 g.提供事务机制,通过BeginTrans、CommitTrans和RollbackTrans方法实现事务控制。 h.通过Errors集合属性检查数据源的错误信息。 i.通过OpenSchema方法获取数据库的表信息。 Connection对象是ADO的基本对象之一,它独立于所有其他的对象。如果我们要对数据库进行查询操作,既可以使用Execute方法,也可以使用Command对象。使用Execute方法比较简便,但用Command对象可以保存命令的信息,以便多次查询。 (2) Command对象 Command对象代表一个命令,可以通过其方法执行针对数据源的有关操作,比如查询、修改等。Command对象的用法如下: a.通过CommandText属性设置命令串。 b.通过Parameters集合属性和Parameter对象定义参数化查询或存储过程的参数。 c.通过Execute方法执行命令,可能的话,返回Recordset对象。 d.在执行命令之前,可通过设置CommandType属性以便优化性能。 e.可以通过Prepared属性指示底层的提供者为当前命令准备一个编译过的版本,以后再执行时,速度会大大加快。 f.通过CommandTimeOut属性设置命令执行的超时值(以秒为单位)。 g.可以设置ActiveConnection属性,为命令指定连接串,Command对象将在内部创建C onnection对象。 h.可以设置Name属性,这样以后可以在相应的Connection对象上按Name属性指定的方法名执行。 Command对象执行时,既可以通过ActiveConnection属性指定相连的Connection对象,也可以独立于Connection对象,直接指定连接串,即使连接串与Connection对象的连接串相同,Command对象仍然使用其内部的数据源连接。(3)Recordset对象 Recordset对象代表一个表的记录集或者命令执行的结果,在记录集中,总是有一个当前的记录。记录集是ADO管理数据的基本对象,所有的Recordset对象都按照行列方式的表状结构进行管理,每一行对应一个记录(Record),每一列对应一个域(Field)。Recordset对象也通过游标对记录进行访问,在ADO中,游标分为以下4种: 静态游标提供对数据集的一个静态拷贝,允许各种移动操作,包括前移、后移等等,但其他用户所做的操作反映不出来。 动态游标允许各种移动操作,包括前移、后移等等,并且其他用户所做的操作也可以直接反映出来。 前向游标允许各种前向移动操作,不能向后移动,并且其他用户所做的操作也可以直接反映出来。 键集(keyset)游标 类似于动态游标,也能够看到其他用户所做的数据修改,但不能看到其他用户新加的记录,也不能访问其他用户删除的记录。 Recordset对象的用法如下: a.利用CursorType属性设置游标类型。 b.通过Open方法打开记录集数据,既可以在Open之前对ActiveConnection属性赋值, 指定Recordset对象使用连接对象,也可以直接在Open方法中指定连接串参数,ADO将创建一个内部连接,即使连接串与外部的连接对象相同,它也使用新的连接对象。 c.Recordset对象刚打开时,当前记录被定位在首条记录,并且BOF和EOF标志属性为F alse,如果当前记录集为空记录集,则BOF和EOF标志属性为True。 d.通过MoveFirst、MoveLast、MoveNext和MovePrevious方法可以对记录集的游标进行移动操作。如果OLE DB提供者支持相关功能的话,可以使用AbsolutePosition、Absol utePage和Filter属性对当前记录重新定位。 e.ADO提供了两种记录修改方式:立即修改和批修改。在立即修改方式下,一旦调用U pdate方法,则所有对数据的修改立即被写到底层的数据源。在批修改方式下,可以对多条记录进行修改,然后调用UpdateBatch方法把所有的修改递交到底层数据源。递交之后,可以用Status属性检查数据冲突。 Recordset对象是ADO数据操作的核心,它既可以作为Connection对象或Command对象执行特定方法的结果数据集,也可以独立于这两个对象而使用,由此可以看出ADO对象在使用上的灵活性。 上面3个对象都包含一个Property对象集合的属性,通过Property对象可使ADO动态暴露出底层OLE DB提供者的性能。由于并不是所有的底层提供者都有同样的性能,所以ADO 允许用户动态访问底层提供者的能力。这样既使得ADO很灵活,又提供了很好的扩展性。 ADO的其他集合对象及其元素对象,都用在特定的上下文环境中,比如Parameter对象一定要与某个Command对象相联系后,才能真正起作用。而另外三个对象Field、Error和Property对象只能依附于其父对象,不能单独创建这些对象。 三、在多种语言中使用ADO 以上介绍了ADO的对象模型,现在我们来讨论如何在不同的语言环境中使用ADO对象。 因为ADO是作为自动化组件程序实现的,所以我们可以在任何支持COM和自动化特性的语言环境中使用ADO,比如Visual Basic、Visual C++、ASP和Java等等,下面分别加以介绍。 1. 在Visual Basic应用中使用ADO Visual Basic应用在设计模式和运行模式下都可以创建和使用自动化对象,在设计模式下,像ADO这样的对象库可以作为内部对象来使用,我们只需在"Project"菜单下的"Ref erences"命令弹出的对话框中选中ADO对象库"Microsoft ActiveX Data Objects Libra ry",于是我们就可以在程序中直接声明或新建ADO对象,举例如下: Dim cn as New ADODB.Connection Dim cmd as New ADODB.Command Dim rs as New ADODB.Recordset 可以看出,在设计时使用ADO对象非常方便,而且Visual Basic设计环境中提供的对象浏览器(Object Browser)功能允许用户很方便地查看ADO对象的属性和方法。 我们也可以在运行时创建自动化对象,使用Visual Basic的CreateObject函数可以创建任意的自动化对象,由于ADO中只有Connection对象、Command对象和Recordset对象可以被独立创建,所以我们也只能创建这3种对象,举例如下: Dim cn Set rs=CreateObject("ADODB.Connection ") Dim cmd Set rs=CreateObject("ADODB.Command") Dim rs Set rs=CreateObject("ADODB.Recordset") 不管是设计模式还是运行模式,调用ADO对象的属性和方法都非常简单,直接调用即可。 2. 在ASP的VBScript中使用ADO ADO对象也可以用于HTML和Active Server Page的VBScript脚本代码,VBScript脚本代码与Visual Basic的代码很类似,它们内嵌在HTML或ASP文件的特定标记对内部。但VB Script引擎比Visual Basic的设计环境或运行库在功能上还是要弱一些,首先,在VBScri pt代码中,没有与设计环境类似的用法,VBScript引擎不能装入ADO类型库,所以不能使用New操作符创建ADO对象,但可以使用CreateObject函数创建对象;其次,ADO对象库中用到的常量只能通过包含文件引入,随ADO一起提供的Adovbs.inc文件包含所有ADO常量的定义,我们可在脚本代码中直接包含此文件。 因此,为了在VBScript代码中使用ADO,首先要包含Adovbs.inc文件,然后使用Create Object函数创建ADO对象,以后就可以调用这些对象的属性或方法了。下面的例子显示了在ASP文件中用ADO列出数据表中所有作者的姓名和职称,代码如下: Using ADO in a Visual Basic Script Web Page Using ADO in a Visual Basic Script Web Page myConnection.Open "DSN=MySamples;UID=sa" SQLQuery = "select AuthorName, Title from AuthorDB" set rs = myConnection.Execute(SQLQuery)% WIDTH=200 Title ID SIZE=1 Title "arial narrow" size=1 "arial narrow" size=1 3. 在Visual C++中使用ADO 在Visual C++中使用ADO有多种方法,第一种方法是我们使用CoCreateInstance函数创建ADO对象,并得到对象的IDispatch接口指针,然后调用其Invoke函数,用这种方法需要我们自己处理参数和返回值,ADO提供了Adoid.h和Adoint.h头文件分别定义了ADO对象的CLSID和接口ID;第二种方法是利用#import编译指示符(在Visual C++ 5.0及以后的版本中可以使用),可以方便地使用ADO对象;第三种方法是利用MFC(Microsoft Foundation C lass)库提供的IDispatch接口封装类COleDispatchDriver创建和调用ADO对象。 下面的代码显示了在Visual C++创建数据源连接的过程: GUID connectionCLSID; HRESULT hResult = ::CLSIDFromProgID(L"ADODB.Connection", &connectionCLSID); if (FAILED(hResult)) { ...... } IDispatch *pDispatch = NULL; hResult = CoCreateInstance(connectionCLSID, NULL, CLSCTX_SERVER, IID_IDispatch, (void **)&pDispatch); if (FAILED(hResult)) { ...... } COleDispatchDriver driver; driver.AttachDispatch(pDispatch, FALSE); TRY { BYTE parms =VTS_BSTR; driver.InvokeHelper(0xa, DISPATCH_METHOD, VT_EMPTY, &hResult, parms,L"Provider=SQLOLEDB; User ID=sa;Password=;" L"Initial Catalog=LEAVES; Data Source=NetTestServer"); } END_TRY driver.DetachDispatch(); ...... 4. 在Java中使用ADO 在Java程序中可以引入ADODB类,然后声明ADO变量,也可以使用new操作符创建ADO变量。下面的代码说明了如何在Java中打开与数据源连接: import msado10.*; _Connection m_conn = null; _Recordset m_rs = null; _Command m_cmd = null; void OpenConnection() { String s; Properties properties; try { properties = m_conn.getProperties(); m_conn.Open("dsn=MySamples", "sa", ""); properties = null; } catch (Exception e) { System.out.println("Unable to make a connection "); } } (作者地址:北京大学计算机科学技术研究所,100871,收稿日期:1999.02)
Tags:
作者:佚名评论内容只代表网友观点,与本站立场无关!
评论摘要(共 0 条,得分 0 分,平均 0 分)
查看完整评论