VC++程序设计与应用--数据库编程
Posted Abro.
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VC++程序设计与应用--数据库编程相关的知识,希望对你有一定的参考价值。
目录
前言
本篇文章介绍数据库编程
一、数据库编程
1.1 概述
Visual C++提供4种不同的技术来使应用程序访问数据库:
- DAO(Data Access Objects)
- ODBC(Open Database Connectivy)
- OLE DB
- ADO (ActiveX Data Objects)
1.1.1 数据库和数据库管理系统
数据库:
是以一定的组织方式将相关的数据组织在一起,存放在计算机外存储器上,能为多个用户共享的与应用程序彼此独立的一组相关数据的集合。
数据库管理系统:
是一种操纵和管理数据库的软件系统,简称DBMS,例如FoxPro、SQL Server、Oracle、Sybase、Access等都是比较常见的数据库管理系统。在数据库管理系统的支持下,数据完全独立于应用程序,并且能被多个用户或程序共享,其关系如图所示。
1.1.2 关系数据库
关系数据库由多个相关的表组成,用户可在有相关数据的多个表之间建立联系。
在关系数据库中,数据被分散到不同的表中。表是一个二维对象,是由行和列组成的数据集合。表中的每一列称为一个字段,表中的每一行称为一条记录。
1.1.3 SQL语言
SQL语言又称结构化查询语言,是关系数据库系统的标准语言。SQL向数据库提供了完善而一致的接口,它不是独立的计算机语言,需要DBMS的支持方能执行。
SQL最常用的功能有数据定义、数据操纵和数据查询。
1. 数据定义
使用CREATE TABLE语句来定义一个表。例如:
CREATE TABLE student
( 学号 CHAR(8),
姓名 CHAR(8),
性别 CHAR(2),
年龄 INTEGER,
系别 CHAR(8)
)
2. 数据操控
SQL中的数据操纵语言是一组操纵表中数据的语句,包括插入记录语句INSERT、删除记录语句DELETE和更新记录语句UPDATE。
- 插入记录语句INSERT
在指定表的尾部添加一条包含指定字段值的新记录。一般格式:
INSERT INTO<表名>[(<属性列1>[,<属性列2>]...)]
VALUES(<常量1>[,<常量2>]...)
例如下面的语句可向student表中插入一条记录:
insert into student values(‘11111111’,’苏培’,’男’,20,’计算机’)
- 删除记录语句DELETE
为指定表中满足条件的记录加逻辑删除标记。
DELETE FROM<表名>[WHERE<条件>]
下面的语句将student表中所有男生的记录逻辑删除:
delete from student where性别=’男’
- 更新记录语句INSERT
用指定的值更新记录。一般格式如下:
UPDATE<表名>SET<列名>=<表达式>[,<列名>=<表达式>]...
[WHERE<条件>]
例如,如果要更改上面刚插入的记录,则语句如下:
update student set 姓名=’苏江’,系别=’机电工程’where姓名=’苏培’
3.数据查询
在SQL语言的所有功能中,数据查询是它的核心,也称做SQL-SELECT命令。
通过使用SQL-SELECT命令,可以对数据源进行各种组合,有效地筛选记录、管理数据,并对结果排序及指定输出去向等。其命令的基本格式为:
SELECT 子句 FROM 子句 [WHERE 子句]
[GROUP BY 子句] [ORDER BY 子句]
下面是几个简单的例子:
(1) 查询学生表student中的所有记录。
select * from student
(2) 查询所有学生的姓名。
select from student
(3) 查询王明的系别。
select 系别from student where 姓名=’王明’
(4) 将表student中所有人按年龄由大到小排序。
select * from student order by 年龄 desc
1.2 ODBC技术
1.2.1 ODBC概述
开放数据库互连ODBC是微软公司开放服务结构中有关数据库的一个组成部分,它建立了一组规范,并提供了一组对数据库访问的标准应用程序编程接口API(应用程序编程接口)。
一个基于ODBC的应用程序对数据库的操作不依赖任何DBMS,不直接与DBMS打交道,所有的数据库操作由对应的DBMS的ODBC驱动程序完成。ODBC的最大优点是能以统一的方式处理所有的数据库。
一个完整的ODBC由下列几个部件组成:
- 应用程序(Application)
- ODBC管理器(Administrator)
该程序位于Windows控制面板(Control Panel)的32位ODBC内,其主要任务是管理安装的ODBC驱动程序和管理数据源。
- 驱动程序管理器(Driver Manager)。
驱动程序管理器包含在ODBC32.DLL中,对用户是透明的。其任务是管理ODBC驱动程序,是ODBC中最重要的部件。
- ODBC API
- ODBC 驱动程序:是一些DLL,提供ODBC和数据库之间的接口。
- 数据源:包含数据库位置和数据库类型等信息,实际上是一种数据连接的抽象。
1.2.2 MFC ODBC数据库类
MFC的ODBC类主要包括:
(1) CDatabase类
主要功能是建立与数据源的连接。
(2) CRecordset类
该类代表从数据源中提取的记录集。程序可以选择数据源中的某个表作为一个记录集,也可以通过对表的查询得到记录集,还可以合并同一数据源中多个表的列到一个记录集中.通过该类可对记录集中的记录进行滚动、修改、增加和删除等操作。
(3) CRecordView类
是连到一个CRecordset对象的表单视图,用于显示数据库记录。利用对话框数据交换机制DDX在记录集与表单视图的控件之间传输数据。
(4) CFieldExchange类
支持记录字段数据交换RFX,即记录集字段数据成员与相应数据库的表的字段之间的数据交换。
(5) CDBException类
用于处理ODBC类产生的异常。
1.2.3 CRecordset类
1.打开和关闭记录集
要建立记录集,首先要构造一个CRecordset派生类对象,然后调用CRecordset类的Open()成员函数查询数据源中的记录并建立记录集。
virtual BOOL Open(UINT nOpenType=
AFX_DB_USE_DEFAULT_TYPE,
LPCTSTR lpszSQL=NULL,
DWORD dwOptions=none);
如果记录集对象被成功打开,则返回非0值,否则返回0值。
第1个参数是记录集的类型;第2个参数是用来给记录集赋值的SQL语句;第3个参数是一组标志,用来指定检索记录集的方式。
建立记录集后,用户可以随时调用Requery()成员函数来重新查询和建立记录集。Requery()有两个重要用途:
- 使记录集能反映用户对数据源的改变
- 按照新的查找条件或排序方法查询记录并重新建立记录集
2.在记录集中定位
如果记录集是空的,那么调用上述函数将产生异常。另外,必须保证滚动没有超出记录集的边界。调用IsEOF()和IsBOF()可以进行这方面的检测。
- IsEOF()函数: 如果记录集为空或滚动过了最后一个记录,那么函数返回TRUE,否则返回FALSE。
- IsBOF() 函数:如果记录集为空或滚动过了第一个记录,那么函数返回TRUE,否则返回FALSE。
3. 更新记录集
在增加记录、删除记录和修改记录时,必须遵循一些特定步骤才能得到正确结果。
要修改当前记录,应该按下列步骤进行:
- 调用Edit()成员函数:调用该函数后就进入了编辑模式,程序可以修改字段数据成员。注意不要在一个空的记录集中调用Edit(),否则会产生异常。
- 设置字段数据成员的新值。
- 调用Update()完成编辑:把变化后的记录写入数据源并结束编辑模式。
要向记录集中添加新的记录,应该按下列步骤进行:
- 调用AddNew()成员函数:调用该函数后就进入了添加模式,该函数把所有的字段数据成员都设置成NULL。
- 设置字段数据成员。
- 调用Update():把字段数据成员中的内容作为新记录写入数据源,从而结束了添加。
要删除记录集的当前记录,应按下面两步进行:
- 调用Delete()成员函数:该函数会同时给记录集和数据源中当前记录加上删除标记。注意不要在一个空记录集中调用Delete()函数,否则会产生一个异常。
- 滚动到另一个记录上以跳过删除记录。
4. 记录集的查找和排序
在CRecordset类中提供了两个公有数据成员m_strFilter和m_strSort,分别用来设置对记录的查找和排序。
数据成员m_strFilter用于指定查找条件。m_strFilter实际上包含了SQL的WHERE子句的内容,但它不含WHERE关键字。
下面是查找记录集对象stuSet中年龄为20的记录:
stuSet.m_strFilter=”年龄=20”;
数据成员m_strSort用于指定排序字段。m_strSort实际上包含了ORDER BY子句的内容,但它不含ORDER BY关键字。
按“年龄”字段降序排列记录集对象stuSet中的记录:
stuSet.m_strSort=”年龄DESC”;
其中,参数DESC表示降序,升序的参数用ASC表示。
如果字段名中包含有空格,则必需用方括号将字段名括起来。例如,如果有一字段名为“学号”,则应该写成“[学号]”。示例代码如下:
stuSet.m_strSort=”[学号] ASC";
1.3 创建MFC ODBC数据库应用程序
1.3.1 准备数据库
【例1】利用Visual FoxPro6.0创建一个数据库StudentDB.dbc,其中包含一个表student.dbf。
1.3.2 注册数据源
建立了数据库之后,必须配备ODBC数据源,使其指向刚刚建立的数据库。
如果操作系统是Windows 95/98,则运行控制面板中的“ODBC数据源(32位)”。
如果操作系统是Windows 2000/XP,则运行控制面板中管理工具下的“数据源ODBC”。
为Visual FoxPro 6.0数据库StudentDB.dbc注册数据源步骤:
(1)双击ODBC图标,进入ODBC数据源管理器。在这里用户可以设置ODBC数据源的一些信息,其中的用户DSN选项卡中可以让用户定义的在本地计算机使用的数据源名(DSN)。
(2)单击添加按钮,弹出创建新数据源对话框,为新的数据源选择数据库驱动程序。
由于使用的是Visual FoxPro6.0数据库,所以选择Microsoft Visual FoxPro Driver,并单击完成按钮,如下图所示。
(3) 在ODBC Visual FoxPro Setup对话框中,为该数据源起一个简短的名称。
对于本例,给该数据源命名为Student,并在下一个编辑框中输入对该数据库的说明。
(4) 指定数据库的位置。单击Browse按钮,出现Select Database文件选择对话框,定位并选择StudentDB.dbc文件。
(5) 单击打开按钮完成数据库选择,在ODBC Visual FoxPro Setup对话框中单击OK按钮,完成数据源的创建。最后,单击ODBC数据源管理器对话框中的确定按钮,退出数据源管理器。
1.3.3 创建应用程序框架
【例2】
创建一个支持数据库的标准SDI风格的应用程序TestODBC。
(1) 用MFC AppWizard(exe)创建一个SDI 应用程序TestODBC。
(2) 在MFC AppWizard-Step 2 of 6对话框中选择Database view without file suport,如下图所示,应用程序向导将生成浏览数据库的类。该应用程序除了使用数据库之外,不使用任何附加文件,所以它不需要文件支持。
(3)单击Data Source按钮,打开Database Options(数据源选择)对话框,将该应用程序与数据源相连接。在Database Options对话框中,选择ODBC接口,在下拉列表中选择Student数据源。
(4)单击OK按钮,在出现的Select Database Tables(选择数据库中的数据表)对话框中选择student表,如图所示,单击OK完成数据源选择。
(5)单击OK按钮,关闭该对话框并返回到应用程序向导的第二步。
(6)继续应用程序向导的工作,保留默认设置,生成应用程序框架。
在MFC AppWizard-Step 6 of 6对话框中显示了应用程序中所创建的类,如下图所示。
从图中可以看出,MFC AppWizard为应用程序加入了一些与数据库有关的代码,它创建了记录集类CRecordset的派生类CTestODBCSet和记录视图类CRecordView的派生类CTestODBCView。
应用程序框架通过CDatabase对象自动进行数据源的连接和使用结束后的断开,这些代码对用户是透明的,在源程序中并没有出现。
(7) 编辑、链接并运行程序,得到如图所示的结果。
1.3.4 实现数据库程序的基本功能
记录视图类CRecordView是CFormView的派生类,它提供了一个表单视图来显示当前记录。
【3】完善例2的应用程序TestODBC,增加浏览记录集的功能。运行效果如下图所示。
(1) 打开例2中应用程序TestODBC,在主对话框中添加如上图所示的控件。
(2) 更改记录集类的字段数据成员名。
MFC AppWizard不仅为应用程序自动生成了一个记录集类CRecordset的派生类CTestODBCSet,还为CTestODBCSet类自动生成了若干个字段数据成员,其数量与相对应的表中字段数量相同,这些字段数据成员分别命名为m_columnl、m_column2、…。这些名称在编程中不便于理解,也不利于记住其对应的是表中的哪一个字段,因此应该将它们的名称改为与表中字段意义相同的名称,起到见名知意的作用。
更改CTestODBCSet类的字段数据成员名称的步骤:
- 选择View菜单的ClassWizard命令,弹出ClassWizard对话框,从对话框中选择Member Variables选项卡,单击Class name组合框的下拉按钮,从下拉类名列表中选择CTestODBCSet。
- 选择需要更名的字段数据成员,先单击Delete Variable按钮删除该成员,再单击Add Variable按钮或双击需要更名的字段数据成员项,在弹出的对话框中输入新的成员变量名后,单击OK按钮。
- 在所有需要更名的字段数据成员都更名完毕并返回ClassWizard对话框时,单击OK按钮完成更名操作。
(3) 为视图类添加与控件关联的成员变量。
选择View菜单下的ClassWizard,单击Member Variables标签。选择IDC_NUMBER,单击Add Variable按钮,出现Add Member Variable对话框,单击Member variable name下方的下拉列表,选择m_pSet->m_number,如下图所示。图中所示的m_pSet是指向CTestODBCSet对象的指针。
(4)用同样方法将其他成员变量与对应的编辑控件相关联。完成后,ClassWizard属性表中的Member Variables界面如图所示。
(5) 编译、链接并运行程序。
1.3.5 实现数据库程序的高级功能
1.增加、删除和修改记录
例4】完善例11.3的应用程序TestODBC,使其支持记录的增加、删除和修改。
(1) 打开例11.3中应用程序TestODBC,在记录菜单项中添加三个子菜单项:添加记录、删除记录及修改记录。
(2) 插入如下图所示的对话框资源,接受系统默认ID,将Caption改为“学生信息”。在对话框中添加控件,并设置其属性。
(3)利用ClassWizard类向导为“学生信息”对话框定义连接类CStudentDlg,并为对话框中的编辑控件添加关联变量。
(4)利用ClassWizard类向导在CTestODBCView类中为“添加记录”、“删除记录”及“修改记录”三个菜单项添加COMMAND命令消息处理函数,并添加代码。
增:
void CTestODBCView::OnRecordAdd()
CStudentDlg dlg;
if(dlg.DoModal()==IDOK)
m_pSet->AddNew();//在表的末尾增加新记录
m_pSet->m_number=dlg.m_number1;
m_pSet->m_name=dlg.m_name1;
m_pSet->m_sex=dlg.m_sex1;
m_pSet->m_age=dlg.m_age1;
m_pSet->m_department=dlg.m_department1;
m_pSet->Update();//将新记录存入数据库
m_pSet->Requery();//重建记录集
删:
void CTestODBCView::OnRecordDele()
// TODO: Add your command handler code here
m_pSet->Delete();//删除当前记录
m_pSet->MoveNext();//记录下移
if(m_pSet->IsEOF())//如果移到记录集的尾部
m_pSet->MoveLast();//移向最后一条记录
if(m_pSet->IsBOF())//如果无记录
m_pSet->SetFieldNull(NULL);//当前记录中的指定字段的值为NULL
m_pSet->Requery();
UpdateData(false);//更新表单视图
改:
void CTestODBCView::OnRecordEdit()
CStudentDlg dlg;
dlg.m_number1=m_pSet->m_number;
dlg.m_name1=m_pSet->m_name;
dlg.m_sex1=m_pSet->m_sex;
dlg.m_age1=m_pSet->m_age;
dlg.m_department1=m_pSet->m_department;
if(dlg.DoModal()==IDOK)
m_pSet->Edit();
m_pSet->m_number=dlg.m_number1;
m_pSet->m_name=dlg.m_name1;
m_pSet->m_sex=dlg.m_sex1;
m_pSet->m_age=dlg.m_age1;
m_pSet->m_department=dlg.m_department1;
m_pSet->Update();
UpdateData(false);
(5) 在TestODBCView.cpp文件的开始处添加文件包含语句:
#include "StudentDlg.h"
(6) 编译、链接并运行程序。
2. 记录的排序与查找
【例5】完善例4的应用程序TestODBC,使其支持记录的排序与查找。
(1)打开例4中应用程序TestODBC,在主菜单中添加“排序”、“查找”两个菜单项,并为每个菜单项添加“学号”、“系别”两个子菜单项。
(2) 插入如下图所示的对话框资源,接受系统默认ID,将Caption改为“查找”。
(3)在“查找”对话框中添加一个静态文本控件及一个编辑框控件。设置静态文本控件的Caption为空。
(4)利用ClassWizard类向导为“查找”对话框定义连接类CFindDlg,并为对话框中的控件添加关联变量。如下图所示。
(5)利用ClassWizard类向导在CTestODBCView类中为步骤(1)中增加的四个菜单项添加COMMAND命令消息处理函数,并添加代码。
//按学号排序
void CTestODBCView::OnSortNumber()
m_pSet->Close();//关闭记录集
m_pSet->m_strSort="学号";//设置排序字段
m_pSet->Open();//打开排序后的记录集
UpdateData(false);
//按系别排序
void CTestODBCView::OnSortDep()
m_pSet->Close();
m_pSet->m_strSort="系别";
m_pSet->Open();
UpdateData(false);
//查找学号
void CTestODBCView::OnFindNumber()
CFindDlg dlg;
dlg.m_strfind="学号:";
CString str="学号";
if(dlg.DoModal()==IDOK)
str=str+"='"+dlg.m_findvalue+"'";
m_pSet->Close();
m_pSet->m_strFilter=str;//设置过滤字符串
m_pSet->Open();
if(m_pSet->GetRecordCount()==0)
MessageBox("没有匹配的记录!","查找", MB_ICONWARNING);
m_pSet->Close();
m_pSet->m_strFilter="";
m_pSet->Open();
UpdateData(false);
//查找部门
void CTestODBCView::OnFindDepartment()
CFindDlg dlg;
dlg.m_strfind="系别:";
CString str="系别";
if(dlg.DoModal()==IDOK)
str=str+"='"+dlg.m_findvalue+"'";
m_pSet->Close();
m_pSet->m_strFilter=str;
m_pSet->Open();
if(m_pSet->GetRecordCount()==0)
MessageBox("没有匹配的记录!","查找", MB_ICONWARNING);
m_pSet->Close();
m_pSet->m_strFilter="";
m_pSet->Open();
UpdateData(FALSE);
(6)在TestODBCView.cpp文件的开始处添加文件包含语句:
#include "FindDlg.h"
(7) 编译、链接并运行程序。
总结
懂得天空是蓝色的,心灵就不应该终日被灰色覆盖;懂得年轻是美丽的,青春就不应该被恶行锈蚀;懂得人生之旅多坎坷,信念就不应该在挫折中消失!
以上是关于VC++程序设计与应用--数据库编程的主要内容,如果未能解决你的问题,请参考以下文章
学号20182335 2019-2020-1 《数据结构与面向对象程序设计》实验四报告