《2022年Ado_使用ADO封装类的数据库程序开发实例[参 .pdf》由会员分享,可在线阅读,更多相关《2022年Ado_使用ADO封装类的数据库程序开发实例[参 .pdf(11页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、使用 ADO 封装类的数据库程序开发实例(上)作者:成真下载本文示例源代码源代码运行效果图如下:一、前言用过 ADO的人都知道,调用 ADO要处理很多 麻烦 的事情,如异常处理等,要写很多try-catch块.有点不甚其烦。我干脆把常用的函数都封装起来,免去老是要写try-catch块的麻烦。做起来虽然没有什么技术含量,但也比较烦琐,所以只完成了一部分,且由于时间及个人水平有限,没有对封装的东西作全面测试,并必定有很多错误,但想到对某些朋友可能有用。所以先 捐出来了。-.在介绍这两个类之前,让我们先来了解一下ADO,本文假设你已有一定的编程能力:二、了解ADO的结构体系ADO(ActiveX
2、Data Object,Active 数据对象)是Microsoft提供的一种面向对象,与语言无关的数据访问应用编程接口。据大部分资料介绍,它有如下主要特点:一:易于使用。二:可以访问多种数据源。三:访问速度快,效率高:四:方便Web应用。五:技术编程接口丰富。六:低内存支出和占用磁盘空间较少.正是看到ADO这么多优点,使我对用 ADO开发数据库产生了兴趣.ADO用起来也如前面所说的一样,确实不难。总的来说,ADO模型包括了下列对象:连接(Connection)、命令 (Command)、记录集 (Recordset)、字段 (Field)、参数 (Parameter)、错误(Error)、属
3、性 (Property)、集合、事件.它们之间的关系如下图:(1)我们最常用的主要是Connection、Recordset及 Command 这三个对象.(2)对于访问一个数据库来说,我们一般先建立一个ADO连接.(3)ADO 连接可以直接执行SQL语句来操纵数据库,但如果我们要对数据在应用程序和数据源之间进行存取的话,就需要用到记录集对象。一个 ADO 连接可以有多个ADO 连接,但一个 ADO连接一般只能对应一个且必须对应一个ADO连接.(4)另外如果你可进行更高级别的访问的话,还可能要用到命令对象。例如要调用存储过程等。(5)一个记录集包含有一个字段集,一个字段集则包含有多个字段对象。
4、(6)同样一个命令对象也包含一个参数集,一个参数集则包含有多个参数对象。(7)连接对象也有一个错误集并包含有多个错误对象。名师资料总结-精品资料欢迎下载-名师精心整理-第 1 页,共 11 页 -这就是 ADO各对象之间大致的关系.三、了解ADO连接在使用数据库之前,要先建立连接.一般先用CreateInstance方法创建ADO连接对象,然后就可以用Open方法连接到数据库。它的原型是 Open(BSTR ConnectionString,BSTR UserID,BSTR Password,long Options);其中 UserID 和 Password 如果在 ConnectionSt
5、ring已经指明 了 用 户 名 和 密 码,一 般 就 可 以 不 必 管 它 们.Options指 的 是 是 以 同 步 方 式(adConnectUnspecified)还是以异步方式(adAsyncConnect)进行连接,默认为同步.这个函数的关键这处在于ConnectionString参数,它决定了我们将以什么方式连接到什么数据源,例如:如果是Access数据库,它的格式则一般为:Provider=Microsoft.Jet.OLEDB.4.0;Data Source=db.mdb;如果是SQL Server:Provider=SQLOLEDB.1;Data Source=sql
6、servername;Initial Catalog=master;UserID=sa;PWD=password;具体的内容视你的环境而定.要连接到其他数据库,请参考相关的资料.例如:_ConnectionPtr pConnection;LPCSTR strConnect=Provider=Microsoft.Jet.OLEDB.4.0;Data Source=test.mdb;/创建 Connection 对象-HRESULT hr=pConnection.CreateInstance(ADODB.Connection);/设置连接时间-pConnection-put_ConnectionT
7、imeout(long(5);if(SUCCEEDED(hr)/连接数据库-pConnection-Open(strConnect,adConnectUnspecified)四、了解ADO记录集创建了 ADO连接,我们就可以通过ADO记录集来访问数据库了.同样,在使用记录集之前要先创建对象.然后调用Open方法打开记录集.它不但可以执行普通的SQL语句,还可以调用存储过程等等:Open(VARIANT Source,VARIANT ActiveConnection,CursorTypeEnum CursorType,LockTypeEnum LockType,LONG Options).其中A
8、ctiveConnection参数为一个有效的 Connection 对象名,就是我们在上面所说过的ADO连接对象.CursorType 参数指的是记录集光标类型,在官方的资料中是这样说明它的取值类型的:1.adOpenForwardOnly 仅向前游标,默认值。除了只能在记录中向前滚动外,与静态游标相同。当只需要在记录集中单向移动时,使用它可提高性能。2.adOpenKeyset 键集游标。尽管从您的记录集不能访问其他用户删除的记录,但除无法查看名师资料总结-精品资料欢迎下载-名师精心整理-第 2 页,共 11 页 -其他用户添加的记录外,键集游标与动态游标相似。仍然可以看见其他用户更改的数
9、据。3.adOpenDynamic 动态游标。可以看见其他用户所作的添加、更改和删除。允许在记录集中进行所有类型的移动,但不包括提供者不支持的书签操作。4.adOpenStatic 静态游标。可以用来查找数据或生成报告的记录集合的静态副本。另外,对其他用户所作的添加、更改或删除不可见。我们现在可不用管这么多,就用默认的adOpenStatic类型吧.LockType 参数,用于指示在什么时候锁定记录:AdLockReadOnly(默认值)只读-不能改变数据。AdLockPessimistic 保守式锁定(逐个)-提供者完成确保成功编辑记录所需的工作,通常通过在编辑时立即锁定数据源的记录。AdL
10、ockOptimistic 开放式锁定(逐个)-提供者使用开放式锁定,只在调用Update 方法时才锁定记录。AdLockBatchOptimistic 开放式批更新-用于批更新模式(与立即更新模式相对)。Options 参数指的是操作类型:adCmdText 指示 strSQL 为命令文本,即普通的SQL语句.adCmdTable 指示 ADO生成 SQL查询以便从在strSQL 中命名的表中返回所有行.adCmdTableDirect 指示所作的更改在strSQL 中命名的表中返回所有行.adCmdStoredProc 指示 strSQL 为存储过程.adCmdUnknown 指示 str
11、SQL 参数中的命令类型为未知adCmdFile 指示应从在strSQL 中命名的文件中恢复保留(保存的)Recordset.adAsyncExecute 指示应异步执行strSQL.adAsyncFetch 指示在提取 Initial Fetch Size 属性中指定的初始数量后,应该异步提取所有剩余的行.如果所需的行尚未提取,主要的线程将被堵塞直到行重新可用.adAsyncFetchNonBlocking 指示主要线程在提取期间从未堵塞.如果所请求的行尚未提取,当前行自动移到文件末尾.唉又是一大串,如果你只是要执行SQL语句,就把它设为adCmdText 吧.这样 Source 就是你要执
12、行的SQL语句了.例如:LPCSTR strSQL=select*from vckbasetable;_RecordsetPtr pRecordset;pRecordset.CreateInstance(ADODB.Recordset);pRecordset-Open(_bstr_t(strSQL),_variant_t(IDispatch*)pConnection,true),adOpenStatic,AdLockOptimistic,adCmdText);ADO中读取记录集中指定字段的值一般有两种方法:第一种:FieldsPtr pFields;pRecordset-get_Fields(
13、&pFields);pFields-ItemLCOLUMN_NAME-Value;/或 pFields-Itemlong(index)-Value;名师资料总结-精品资料欢迎下载-名师精心整理-第 3 页,共 11 页 -/其中index为整型或长整型.GetFields()函数返回的是记录集对象的字段集合对象的指针.第二种:pRecordset-get_Collect(COLUMN_NAME);/或 pRecordset-get_Collect(long(index);它们都将返回一个_variant_t类型的值,推荐使用后一种方法.例如:int ncol=rset.GetFieldsCou
14、nt();while(!rset.IsEOF()for(int i=0;i get_Fields(&pFields);然后可以获得相应的字段对象:long lIndex=0;FieldPtr pf=pFields-GetItem(_variant_t(lIndex);/或:FieldPtr pf=pFields-GetItem(COLUMN_NAME);字 段 对 象 有 很 多 有 用 的 属 性,这 些 可 以 参 考 我 的 源 代 码 或 其 他 相 关 资 料.如:get_ActualSize(long*pl)/实际宽度get_Attributes(long*pl)/属性get_De
15、finedSize(long*pl)/定义宽度(以字节为单位,如整型为4,长整型为8.)get_Name(BSTR*pbstr)/字段名get_Type(DataTypeEnum*pDataType)/数据类型get_Value(VARIANT*pvar)/字段的值有了以上对ADO 的基本了解后,我们将正式开始编写应用程序,请看下文。使用 ADO 封装类的数据库程序开发实例(下)作者:成真在使用 ADO封装类的数据库程序开发实例(上)中详细介绍了ADO 的一些基本的概念,接下来让我们在此基础上进行具体的编程。名师资料总结-精品资料欢迎下载-名师精心整理-第 4 页,共 11 页 -五、开始编写
16、ADO 应用程序.使用ADO之前,我们另外还需要添加下面的语句,如此把ADO的库引入到工程中.#import c:program filescommon filessystemadomsado15.dll no_namespace rename(EOF,adoEOF)根据机器安装时候的设置不同具体的路径可能不一样。另外编译的时候会出现如下的警告信息:msado15.tlh(405):warning C4146:unary minus operator applied to unsigned type,result still unsigned MSDN 建议我们不要理会。如果你实在不想看到的话
17、可以在stdafx.h中加入一行下面的代码:#pragma warning(disable:4146)这样这个警告信息就不会再出现了。ADO使用了 COM,所以在使用ADO 之前,必须对COM 进行了初始化,否则无法使用.你可以使用 AfxOleInit()来初始化,但只能初始一次,你不能多次调用此函数,建议你在应用程序的APP类的 InitInstance方法中进行初始化.上面这些一般相关的资料都有详细说明,因此我就不细说了,下面我们来看看如何我封装的两个类。六、ADO 封装类:CAdoConnection 和 CAdoRecordSet 首先当然是要连接到数据源了,连接到数据源的函数是_C
18、AdoConnection 的 Connect 方法,它封装了 ADO连接对象的CreateInstance和 Open方法:我们来看看我是如何封装的:BOOL CAdoConnection:Connect(LPCTSTR strConnect,long lOptions)m_strConnect=strConnect;try /创建 Connection 对象-HRESULT hr=m_pConnection.CreateInstance(ADODB.Connection);if(SUCCEEDED(hr)/连接数据库-if(SUCCEEDED(m_pConnection-Open(strC
19、onnect,lOptions)return TRUE;catch(_com_error e)名师资料总结-精品资料欢迎下载-名师精心整理-第 5 页,共 11 页 -TRACE(_T(:(连接数据库发生错误:%sn),e.ErrorMessage();return FALSE;catch(.)TRACE(_T(:(连接数据库时发生未知错误:);return FALSE;使用之前先定义一个CAdoConnection 类对象如 m_adoConnection,例如:CString strSrcName=E:Accessdatebase.mdb;/假设在 e 盘有这样一个access 的数据库文
20、件CString strConnect=Provider=Microsoft.Jet.OLEDB.4.0;Data Source=+strSrcName;m_adoConnection.Connect(LPCSTR(strConnect);这样就连接到数据源了.接着就是要打开记录集了,下面我对它的open 方法的封装:使用进你可以忽略后面的三个参数,直接把一个SQL语句传给它.HRESULT CAdoRecordSet:Open(LPCTSTR strSQL,long lOption,CursorTypeEnum CursorType,LockTypeEnum LockType)try if(
21、m_pConnection=NULL)return-1;else if(m_pRecordset=NULL)m_pRecordset.CreateInstance(ADODB.Recordset);m_pRecordset-Open(_bstr_t(strSQL),_variant_t(IDispatch*)m_pConnection-GetConnection(),true),CursorType,LockType,lOption);if(m_pRecordset=NULL)return-1;return(m_pRecordset-adoEOF)?0:1;名师资料总结-精品资料欢迎下载-名师
22、精心整理-第 6 页,共 11 页 -catch(_com_error e)TRACE(_T(:(打开记录集发生错误:%sn),e.ErrorMessage();return-1;例如我们可以这样来用:CAdoRecordSet rset;rset.SetAdoConnection(&(GetDocument()-m_adoConnection);/记得要先指定相应的连接对象,否则会出错.m_strSQL=select*from city;/要执行的 SQL语句.rset.Open(m_strSQL);七.写一个数据查询工具(我对实现过程只稍作了介绍,具体内容请参考源代码):7.1 连接数据库
23、首先要编写连接到数据库的代码,为此,我写了一个对话框类(CLogoDig)用来选择不同的数据源,然后在视图类(这个视图类是从CFromView 类派生的)添加 CAdoConnection 类成员变量,并添加如下连接函数 void CAccessView:OnFileConnect()CLogoDig dlg;if(dlg.DoModal()=IDOK)if(dlg.m_nSrcType=0)CString strConnect=Provider=Microsoft.Jet.OLEDB.4.0;Data Source=+dlg.m_strSrcName;GetDocument()-m_adoC
24、onnection.Disconnect();if(!GetDocument()-m_adoConnection.Connect(LPCSTR(strConnect)AfxMessageBox(连接数据库失败!);return;else if(dlg.m_nSrcType=1)CString strConnect=Provider=SQLOLEDB.1;Data Source=+dlg.m_strSrcName+;Initial Catalog=+dlg.m_strDbName +;User ID=+dlg.m_strUserName+;PWD=+dlg.m_strPassWord;GetDo
25、cument()-m_adoConnection.Disconnect();if(!GetDocument()-m_adoConnection.Connect(LPCSTR(strConnect)名师资料总结-精品资料欢迎下载-名师精心整理-第 7 页,共 11 页 -AfxMessageBox(连接数据库失败!);return;(CMainFrame*)GetParentFrame()-m_wndLeftBar.InitTree();7.2 CCoolControlBar类和 CMSFlexGrid 类在这个数据查询工具中我们使用了另外两个类:CCoolControlBar类和 CMSFle
26、xGrid 类。.前者是我写的一个可以动态改变大小的控制条类,后者是系统自带一个网格控件,这个控件功能较少,但对于只用来显示一下查询结果已经够用了。在编辑CFromView 类对话框资源视图中,在正在编辑的对话框资源上点右键,选择插入ActiveX控件,然后选择Microsoft FlexGrid control控件。然后在类向导中在Member Variables页中为它添加变量,类向导会提示要引入向个头文件,确认,这时你的类视图中就会增加好几个类。先介绍一个要用到的几个函数:SetCols 设置总共拥有的列数SetFixedCols 设置固定的列数,即背景为灰色的那种SetRows 设置总
27、共拥有的行数SetCol 设置当前列SetRow 设置当前行SetText 设置当前格的文本。位置由上面两个函数决定。SetColWidth 设置列宽7.3 数据的显示与处理另外我们还需要两个编辑控件,用来输入SQL语句和显示错误信息.并在 OnSize 消息处理函数中动态设置它们的位置:void CAccessView:OnSize(UINT nType,int cx,int cy)CFormView:OnSize(nType,cx,cy);if(m_wndGrid.GetSafeHwnd()!=NULL)/控件是否已经创建 m_editError.MoveWindow(0,10,cx,cy
28、-50);m_wndGrid.MoveWindow(0,0,cx,cy-40);m_editSQL.MoveWindow(0,cy-40,cx,40);添 加 一 条 菜 单 项 并 添 加 相 应 响 应 函 数,用 于 开 始 执 行 输 入 的SQL 语 句:void CAccessView:OnRun()名师资料总结-精品资料欢迎下载-名师精心整理-第 8 页,共 11 页 -UpdateData();UpdateGrid();根据查询情况显示查询结果:void CAccessView:UpdateGrid()/连接对象是否打开-if(!GetDocument()-m_adoConne
29、ction.IsOpen()AfxMessageBox(数据库没有打开或已经关闭!);return;/先隐藏这两个控件-m_wndGrid.ShowWindow(SW_HIDE);m_editError.ShowWindow(SW_HIDE);CAdoRecordSet rset;rset.SetAdoConnection(&(GetDocument()-m_adoConnection);if(rset.Open(m_strSQL,adCmdText)!=1)/查询出错,取得出错信息并显示在编辑控件里面-m_strError=GetDocument()-m_adoConnection.GetL
30、astError();UpdateData(FALSE);m_editError.ShowWindow(SW_SHOW);return;/下面我用到的有些函数在类中可能没有封装,所以还是使用了try块,以防万一,:(try /取得记录集的字段数和行数-int nrow=rset.GetRecordCount();int ncol=rset.GetFields()-Count;/设置网格控件的列数和行数-m_wndGrid.SetCols(ncol);m_wndGrid.SetRows(nrow+1);/多留一行以显示字段名m_wndGrid.SetFixedCols(0);CString va
31、lue;/填充字段名-m_wndGrid.SetRow(0);for(int i=0;i 2000?2000:nwidth;m_wndGrid.SetColWidth(i,nwidth);/读取记录集-int n=1;while(!rset.IsEOF()m_wndGrid.SetRow(n);n+;for(int i=0;i m_adoConnection.GetConnection()-State!=adStateOpen)return;m_ctrlTree.DeleteAllItems();/取得数据库字段信息-rset=GetDocument()-m_adoConnection.Ope
32、nSchema(adSchemaColumns);while(!rset.IsEOF()CString strValue;/取得表名-rset.GetValueString(strValue,TABLE_NAME);if(strValue!=strTablename)strTablename=strValue;item=m_ctrlTree.InsertItem(LPCTSTR)strTablename,1,1);/取得字段名-Value=rset.GetFields()-ItemLCOLUMN_NAME-Value;m_ctrlTree.InsertItem(LPCTSTR)Value,2,2,item);rset.MoveNext();catch(_com_error e)当 然,你 一 样 可 以 查 询 看 数 据 库 还 拥 有 哪 些 视 图,索 引 等 信 息.这 里 还 用 到 了CCoolControlBar类,但如何使用这里就不细说了,毕竟现在主要谈的是ADO,如果你对它有什么兴趣可以真接找我.:)一个小查询器就差不多完成了。八、其他参考信息(有很多我在源代码里面已有详细注释,就不一一重复了)_Connection、_Recordset、_Field参考名师资料总结-精品资料欢迎下载-名师精心整理-第 11 页,共 11 页 -