
该实验主要采用了ADO(ActiveX Data Objects)数据库访问技术,以开发图书管理系统为例,逐一介绍VC++ 6.0开发数据库的基本方法。主要任务是连接MFC程序和数据库,完成基本的图书信息的操作。
1、创建图书管理系统主框架
创建主框架是设计图书信息管理系统的第一步,有了框架以后才可以在其中添加对话框、控件、菜单等并实现相关功能。
单击Data Source按钮,
按“下一步”按钮
测试成功后,按确定键。
选择数据库表
之后的返回VC创建工程界面,单击“完成”按钮,进入VC++编程框架
2、VC++程序和数据库连接的桥梁。ADO有最重要的三个对象:Connection、Command和Recordset,分别代表“连接”对象、“命令”对象和“记录集”对象。首先要添加ADO Data Control控件。
(1)选择菜单项的“工程”--“增加到工程”---“Components And Controls…”,选择Registered ActiveX Controls文件夹
(2)再选择Microsoft ADO Data Control 6.0 (SP4) (OLEDB)控件,然后Insert,选择Microsoft DataGrid Control 6.0 (SP5) (OLEDB)控件。后文将这两个控件简称ADODC和DataGrid控件。
(3)在资源视图上单击Dialog文件夹左边的小加号,定位到IDD_LIB_FORM,选中“TODO: 在这个对话框里设置表格控制。”,按“Delete”键将其删除。从工具栏拉人ADODC和DataGrid控件到该对话框上。右键单击ADODC控件,单击“属性”项,打开ADODC的属性页,选择“control”页,设置Use Connection String属性。单击“Build”(生成连接字符串)按钮。此后的操作如上面Data Source设置步骤一样。
(4)选择“RecordSource”页,设置ADODC的RecorSource属性。后操作如下:
(5)打开DataGrid控件的属性对话框,定位到“ALL”页。然后选择“DataSource”一栏右边的“数值”设置为绑定的ADODC控件ID。如下图:
(6)设置ADODC控件
(7)然后compile、Build、BuildExecute运行程序。(保证数据库服务器已经连接)
BOOK基本信息录入
目的要求:了解并掌握MFC利用OLE DB访问数据库的基本使用方法,实现记录的增、删、查功能。
界面创建:
(1)打开IDD_LIB_FORM窗体对话框。删除“DataGrid”控件,将“ADODC”控件的General页,将“显示”选项不勾选,这样运行后界面中该控件将不显示。
(2)在窗体上添加如下控件:6个静态文本控件Static Text,用于显示书名、作者等信息;5个编辑框控件Edit Box;1个日期时间选取器控件Date Time Picker,用于设置出版时间;5个按钮控件Button,分别进行添加、查找等。所有控件的标题设置如下:
为相应控件修改ID并设置其标题。如下表,用户可逐一进行设置。
| 添加的控件 | ID号 | 标题 |
| 编辑框(书名) | IDC_BKNAME | |
| 编辑框(书ISBN) | IDC_BKISBN | |
| 编辑框(书作者) | IDC_AUTHOR | |
| 编辑框(价格) | IDC_BKPRICE | |
| 编辑框(书出版日期) | IDC_PUBLISHTIME | |
| 编辑框(购买册数) | IDC_BKNUM | |
| 按钮 | IDC_ADD | 添加 |
| 按钮 | IDC_SEARCH | 查找 |
| 按钮 | IDC_DELETE | 删除 |
| 按钮 | IDC_EXIT | 退出 |
| 按钮 | IDC_CHECK | 检查您输入的书ISBN是否存在 |
主要代码:
(1)添加并修改StdAfx.h中如下加底纹部分代码:
………
//#include #endif // _AFX_NO_DAO_SUPPORT #include …….. #endif // _AFX_NO_AFXCMN_SUPPORT #import "c:\\Program Files\\Common Files\\System\\ado\\msado15.dll"\\ /*使用import指令引入ADO2组件*/ no_namespace rename("EOF 以上语句的解释: 微软在Micrsoft Studio 6中提供的ADO2,可以在Visual C++中使用ADO接口操纵SQL SERVER数据库。 #import "c:\\program files\\common files\\system\\ado\\msado15.dll" no_namespace rename("EOF 这一语句有何作用呢?其最终作用同我们熟悉的#include类似,编译的时候系统会为我们生成msado15.tlh,ado15.tli两个C++头文件来定义ADO库。 几点说明: (1) 您的环境中msado15.dll不一定在这个目录下,请按实际情况修改 (2) 在编译的时候肯能会出现如下警告,对此微软在MSDN中作了说明,并建议我们不要理会这个警告。 msado15.tlh(405) : warning C4146: unary minus operator applied to unsigned type, result still unsigned (2)建立头文件LibConStr.h,在其中定义本应用系统在后续编程中要一直使用的连接字符串宏常量SQLCONSTR。 步骤:“新建”按钮中选择“C/C++ Header File”文件名输入“LibConStr”。代码如下: #ifndef _LIBCONSTR_H_ #define _LIBCONSTR_H_ #define SQLCONSTR "provider=SQLOLEDB.1;Password=0000;Persist Security Info=True;User ID=sa;Initial Catalog=LibraryLib;Data Source=lhh" #endif 其中加粗部分代码用户可以从ADODC控件属性的“Use Connection String”中复制。 在LibView.cpp文件中加入头文件: #include "LibConStr.h" (3)打开LibView.h文件,在其中定义全局变量: public: //{{AFX_DATA(CXSCJView) enum { IDD = IDD_XSCJ_FORM }; ……… //}}AFX_DATA _RecordsetPtr pRs; // 声明Recordset对象指针 _ConnectionPtr pConnection; //声明Connection对象指针 (4)双击“添加”按钮或打开MFC ClassWizard,在Object IDs、Class name、Messages中选择如下图: 按下Add Function按钮,添加了OnAdd()函数,单击“Edit Code”按钮。编辑函数: 知识注解: 数据库连接的3个对象 1.Connection对象 它代表与数据库的链接。 先要创建一个Connection对象 _Connection m_pConnection; m_pConnection.CreateInstance(“ADODB.Connection”); 对象创建完之后,还需设置具体属性链接到指定的数据库。 常用属性: (1)ConnectionString属性。指定数据源。 (2)ConnectionTimeout属性。指定在终止和产生错误之前执行命令需要等待的时间,默认为30s。 (3)Mode属性。对象修改数据的权限。 (4)State属性。返回Connection对象的状态。 (5)Open方法。用于打开到数据源的连接。语法结构:connection.Open(ConnectionString,UserId, Password, Options); (6)Close方法。关闭到数据库的连接。 2.Command对象 定义了将对数据源执行的命令。常用属性和方法: (1)ActiveConnection属性。通过设置该属性使打开的Connection连接与Command对象关联。 (2)CommandText属性。定义命令的可执行文本。 (3)Execute方法。执行CommandText定义的可执行文本。 3.Recordset对象 表示来自基本表或命令执行结果的记录全集。其常用属性和方法: (1)AbsolutePosition属性。指定Recordset对象当前记录的序号位置。 (2) adoBOF,adoEOF属性。前者指示当前记录位置位于Recordset对象的第一个记录之前;后者指示当前记录位置位于Recordset对象的最后一个位置之后。常用来判断记录指针是否越界。 (3)MaxRecord属性。指定通过查询返回Recordset的记录的最大数目。 (4)GetCollect方法。返回当前记录集中指定的字段值。 (5)Move方法。在记录集中移动指针。 (6)MoveFirst,MoveLast,MoveNext,MovePrevious方法。 (7)Open方法。打开基本表、查询结果或Recordset中记录的游标。 格式:Recordset对象.Open( Source, ActiveConnection, CursorType, LockType, Options) 下面将解释五个参数的作用: 1、Source Recordset对象可以通过Source属性来连接Command对象。Source参数可以是一个Command对象名称、一段SQL命令、一个数据表名称、一个存储过程或是一个Recordset文件名。 2、ActiveConnection Recordset对象可以通过ActiveConnection属性来连接Connection对象。这里的ActiveConnection可以是一个Connection对象或是一串包含数据库连接信息(ConnectionString)的字符串参数。 3、CursorType Recordset对象Open方法的CursorType参数表示将以什么样的游标类型启动数据,包括adOpenForwardOnly、adOpenKeyset、adOpenDynamic及adOpenStatic,分述如下: 常数 常数值 说明 adOpenForwardOnly 0 缺省值,启动一个只能向前移动的静态游标。 adOpenKeyset 1 类似动态游标,允许任意移动,并且允许更改记录集。其他用户对记录集的添加和删除,这个游标反映不出来。但它能反映出其他用户对记录集的更改。 adOpenDynamic 2 动态游标,允许所有操作,其他用户对记录集的添加、删除、更改在此记录集中都是可见的。 adOpenStatic 3 静态游标,允许在记录集中进行各种类型的移动,其他用户所做的添加、删除、更改将不可见。 4、LockType Recordset对象Open方法的LockType参数表示要采用的Lock类型,LockType参数包含adLockReadOnly、adLockPessimistic、adLockOptimistic及adLockBatchOptimistic等,分述如下: 常数 常数值 说明 adLockReadOnly 1 缺省值,Recordset对象以只读方式启动。 adLockPessimistic 2 通常编辑记录是立即锁定数据源的该记录。当数据源正在更新时,系统会暂时锁住其他用户的动作,以保持数据一致性。 adLockOptimistic 3 只在调用Update方法时才锁定记录。当数据源正在更新时,系统并不会锁住其他用户的动作,其他用户可以对数据进行增、删、改的操作。 adLockBatchOptimistic 4 当数据源正在更新时,其他用户必须将CursorLocation属性改为adUseClient才能对数据进行增、删、改的操作。 5、Options Recordset对象Open方法的Options参数表示对数据库请求的类型,Options参数包含adCmdText、adCmdTable、adCmdStoredProc及adCmdUnknown等,分述如下: 常数 常数值 说明 adCmdUnknown -1 缺省值,表示指定的CommandText参数类型无法确定 adCmdText 1 表示指定的CommandText参数是一般的命令类型 adCmdTable 2 表示指定的CommandText参数是一个存在的表的名称 adCmdStoredProc 3 表示指定的CommandText参数是存储过程的名称 COM两个数据类型: _variant_t和_bstr_t这两个类分别封装并管理VARIANT和BSTR这两种数据类型,VARIANT和BSTR这两种类型是COM中使用的数据类型。为了C++中的变量应用到ADO编程中,只能进行数据类型的转换。_variant_t和_bstr_t这两个类,就可以方便的把C++类型变量转换成COM中的变量了 (5)双击“删除”按钮执行以下函数 (6)双击“查找”按钮执行以下函数 自己补充完成 void CLibView::OnSearch() { _variant_t varFld; /*此处代码自己根据“添加”按钮的设置模拟完成,实现建立ADO数据库连接、实例化记录集对象,完成查询。查询是根据编辑框输入的BookISBN查询书的基本信息。*/ if(!pRs->RecordCount==0) { varFld=pRs->Fields->GetItem("BookName")->Value; //获取书名 CString strBN(_T(varFld.bstrVal)); strBN.TrimRight(); m_BKName=strBN; /*此处代码完成pRS记录集对象中作者、价格、出版日期、购买册数赋予给相对应的编辑框*/ UpdateData(FALSE); //自动更新控件显示的内容 } else { AfxMessageBox("没有您想要找的书!");} } (7)双击“退出”按钮执行以下函数 void CLibView::OnExit() { // TODO: Add your control notification handler code here PostQuitMessage(0); }
