实验五 数据库应用程序的开发.docx
- 文档编号:23123662
- 上传时间:2023-05-08
- 格式:DOCX
- 页数:13
- 大小:322.13KB
实验五 数据库应用程序的开发.docx
《实验五 数据库应用程序的开发.docx》由会员分享,可在线阅读,更多相关《实验五 数据库应用程序的开发.docx(13页珍藏版)》请在冰豆网上搜索。
实验五数据库应用程序的开发
实验五数据库应用程序的开发
1实验类型:
验证型实验4学时
2、实验目的
理解数据库应用程序设计的基本步骤和方法。
3、实验任务
●建立ODBC数据源
●连接数据源
●选择和处理记录
●数据库应用程序中的文档和视图
●CRecordView、CRecordset、CDatabase的使用
4、实验指导
在数据库应用程序中常用的几个类
1CRecordView类
一个CRecordView对象就是用一个视图中的控件来显示数据库中的记录。
CRecordView类使用了动态数据交换(DDX)和数据库交换(RFX),在视图上的控件和数据源中的数据库中进行数据交换。
AppWizard生成CRecordView和CRecordset类,并和相应的数据源关联。
【例1】创建一个数据库应用程序,可以显示Access数据库表中的记录。
步骤:
用AppWizard来生成一个单文档的ODBC工程文件
选择已创建好的数据库My_Access_db.mdb表单
用ClassWizard给相应的EditBox连接变量,注意,在AddMemberVariable对话框中的下拉组合框中已经有了相应表中的字段,只要选中相应的字段就可以了。
2CRecordset类
为了能够处理各种的数据库,最好从类CRecordset派生出一个子类来。
数据库从数据源读取数据后,可以做以下的工作:
●翻阅所有的记录。
●修改记录,设定锁定状态。
●挑选有用的记录。
●给数据库排序。
●给定参数,让数据库在运行的时候自动选择数据。
3CDatabase类
CDatabase在afxdb.h中定义。
其对象是用来连接一个数据源的。
为了使用CDatabase对象,需调用构造函数,并调用OpenEx或是Open函数,这将会打开一个连接。
当构造一个CDatabase类完成后,可以向CRecordset类的对象传递这个CDatabase类的指针。
连接数据源结束时,必须用Close函数关闭这个对象。
4RFX
RFX(RecordFieldExchange)是支持应用程序的一个交换机制,当从CRecordset类派生一个类,在交换数据的时候没有选择大容量交换的方式(BulkRFX)时,RFX机制将在数据交换中起作用。
RFX在视图和数据源之间自动交换数据,由于一次交换的数据可能不止一个,为此可能要多次调用DoFieldExchange函数,同时它也是应用程序框架和ODBC交流的媒介。
RFX机制能够安全的通过调用(例如ODBC函数SQLBindCol)来保存用户的工作。
下面代码就是【例1】工程文件中AppWizard自动加入的RFX代码,见粗斜体部分:
voidCODBCSet:
:
DoFieldExchange(CFieldExchange*pFX)
{
//{{AFX_FIELD_MAP(CODBCSet)
pFX->SetFieldType(CFieldExchange:
:
outputColumn);
RFX_Long(pFX,_T("[书籍ID]"),m___ID);
RFX_Text(pFX,_T("[作者]"),m_column1);
RFX_Text(pFX,_T("[出版社]"),m_column2);
RFX_Text(pFX,_T("[价格]"),m_column3);
//}}AFX_FIELD_MAP
}
函数DoFieldExchange是RFX机制的中枢,任何时候应用框架需要从数据源到数据库或是从数据库到数据源,都要调用DoFieldExchange函数。
下面是CRecordset派生类的头文件,其中关于RFX机制的部分已经用粗斜体显示:
classCODBCSet:
publicCRecordset
{…
//Field/ParamData
//{{AFX_FIELD(CODBCSet,CRecordset)
longm___ID;CStringm_column1;
CStringm_column2;CStringm_column3;
//}}AFX_FIELD
//Overrides
//ClassWizardgeneratedvirtualfunctionoverrides
//{{AFX_VIRTUAL(CODBCSet)
public:
……
virtualvoidDoFieldExchange(CFieldExchange*pFX);//RFXsupport
//}}AFX_VIRTUAL
…};
5CDBException
CDBException是用来处理从其它ODBC类传过来的异常情况的。
这个类一般是和关键字CATCH连用的。
同样的用户也可以用全局函数AfxThrowDBException抛出一个异常情况
●m_nRetCode:
它包含了一个结构体RETCODE,里面包含了ODBC的错误信息的描述。
●m_strError:
包含一个描叙异常情况的字符串。
●m_strStateNativeOrigin:
包含描述异常情况的字符串
●m_strStateNativeOrigin;如果变量包含多个错误的描述,错误会分行显示。
●CDBException类的成员变量
【例2】在【例1】的基础上增加“删除一个记录”、“更新记录”和“清除域”三个菜单项,并实现相应的操作。
1加入菜单项
2重载OnMove函数
BOOLCODBCView:
:
OnMove(UINTnIDMoveCommand)
{switch(nIDMoveCommand)
{caseID_RECORD_PREV:
m_pSet->MovePrev();
if(!
m_pSet->IsBOF())
break;//如果移到数据库的开始,自动执行MoveFirst函数
caseID_RECORD_FIRST:
m_pSet->MoveFirst();break;
caseID_RECORD_NEXT:
m_pSet->MoveNext();
if(!
m_pSet->IsEOF())break;
if(!
m_pSet->CanScroll())
{m_pSet->SetFieldNull(NULL);//清空屏幕
break;}
caseID_RECORD_LAST:
m_pSet->MoveLast();break;
default:
ASSERT(FALSE);//异常情况
}
UpdateData(FALSE);//交换数据
returnTRUE;
}
3添加菜单响应函数
voidCODBCView:
:
OnDeleteRecord()//删除记录
{CRecordsetStatusm_cStatus;
try{m_pSet->Delete();}
catch(CDBException*m_pEx)
{AfxMessageBox(m_pEx->m_strError);
m_pEx->Delete();
m_pSet->MoveFirst();//若失败,将记录指针移到首记录
UpdateData(FALSE);
return;
}
m_pSet->GetStatus(m_cStatus);
if(m_cStatus.m_lCurrentRecord==0)
m_pSet->MoveFirst();//删除了最后一个记录
else
m_pSet->MoveNext();
UpdateData(FALSE);
}
voidCODBCView:
:
OnUpdateDeleteRecord(CCmdUI*pCmdUI)
//删除后的刷新
{pCmdUI->Enable(!
m_pSet->IsEOF());}
voidCODBCView:
:
OnUpdateRecord()
{
m_pSet->Edit();
UpdateData(TRUE);
if(m_pSet->CanUpdate())
m_pSet->Update();
}
voidCODBCView:
:
OnUpdateUpdateRecord(CCmdUI*pCmdUI)
//刷新记录集
{
pCmdUI->Enable(!
m_pSet->IsEOF());
}
voidCODBCView:
:
OnClearDomain()//清除域
{
m_pSet->SetFieldNull(NULL);
UpdateData(FALSE);
}
【例3】在【例2】的基础上增加功能,使得程序能够向数据库中添加新记录。
增加一个菜单项“增加一个新记录”,其ID标识为ID_ADD_RECORD
在数据库中增加记录步骤:
●得到最后一条记录的ID号
●将其加1
●通过AddNew函数来添加记录
●把新的ID值设置为新增记录中的ID字段值
●用Update函数保存新记录
●调用Requery函数更新记录
●把输入控制滚动到数据库中的最后一条记录上
为了计算新的ID号,需增加CODBCSet类的成员函数GetMaxID
longCODBCSet:
:
GetMaxID()
{MoveLast();//移到最后一条记录
returnm___ID;//返回该ID值
}
voidCODBCView:
:
OnAddRecord()
{CRecordset*pSet=OnGetRecordset();//获取指向数据库的指针
if(pSet->CanUpdate()&&!
pSet->IsDeleted())
//确认对数据库的任何修改均已保存
{pSet->Edit();
if(!
UpdateData())return;
pSet->Update();
}
longm_lNewID=m_pSet->GetMaxID()+1;//获取新的ID值
m_pSet->AddNew();//添加一个新记录
m_pSet->m___ID=m_lNewID;//设置新的ID标识
m_pSet->Update();//保存新的记录
m_pSet->Requery();//刷新数据库
m_pSet->MoveLast();//游标移到最后一条记录
UpdateData(FALSE);//更新表单
}
【例4】在【例3】的基础上增加浏览记录的功能和对记录进行排序的功能。
创建对话框,通过在对话框中指定记录序号(记录序号不是记录的ID号标识)来浏览该条记录的内容。
voidCODBCView:
:
OnMoveToRecord()
{CMoveToRecorddlgMoveTo;//创建CMoveToRecord类的对象实例
if(dlgMoveTo.DoModal()==IDOK)
{CRecordset*pSet=OnGetRecordset();
//指向数据库记录的指针
if(pSet->CanUpdate()&&!
pSet->IsDeleted())
{//所有的修改保存否?
pSet->Edit();
if(!
UpdateData())return;
pSet->Update();
}
pSet->SetAbsolutePosition(dlgMoveTo.m_RecordID);
//设置新的位置
UpdateData(FALSE);//更新表单
}}
由于在视图中响应了对话框的操作,因此,还需要在ODBCView类的实现文件ODBCView.cpp中加入定义对话框类的头文件:
#include"MoveToRecord.h"
同样,为了使用工具栏按钮进行快速操作,在工具栏中定义一个Move按钮,其ID与菜单项“移到第…条记录”的ID一致,Move按钮的ID为ID_MoveToRecord。
由于CRecordset类的对象或从CRecordset类继承的对象都拥有一个m_strSort成员,它决定了对记录的排序,在“记录”菜单中增加菜单项“按价格排序”,(ID_SORT_PRICE),并为它映射COMMAND消息处理函数OnSortPrice()。
voidCODBCView:
:
OnSortPrice()
{m_pSet->Close();//关闭数据库
m_pSet->m_strSort=“价格”;//指定排序字段
m_pSet->Open();//再次打开数据库
UpdateData(FALSE);//更新已经排序过的记录
}
由于用了CRecordset类的成员m_strSort,因此对数据库记录的排序不用进行太多的代码干预。
最后在工具栏中增加Sort工具按钮,实现菜单项“按价格排序”的功能。
【例5】在【例4】的基础上增加查询功能
为了编写查找功能的代码,增加菜单项“按作者查找”(ID_Search),映射的COMMAND消息处理函数为OnSearch()。
假设按“作者”字段进行查询,为菜单项“按作者查找”所映射的COMMAND消息处理函数代码如下:
voidCODBCView:
:
OnSearch()
{
DoFilter("作者");
}
voidCODBCView:
:
DoFilter(CStringcol)
{CSearchDlgdlg;
intresult=dlg.DoModal();
if(result==IDOK)
{CStringstr=col+"='"+dlg.m_Edit_Search+"'";
//接收查询字符串
m_pSet->Close();//关闭原来的表单
m_pSet->m_strFilter=str;//将查询条件赋给过滤器
m_pSet->Open();//打开经过过滤的表单
intrecCount=m_pSet->GetRecordCount();
//计算满足条件的记录数
if(recCount==0)//如果没有找到相关记录
{MessageBox(“Nomatchingrecords.”);
m_pSet->Close();//关闭表单
m_pSet->m_strFilter;//将过滤结果给过滤器
m_pSet->Open();//据过滤结果打开表单(什么都没找到)
}
UpdateData(FALSE);//不论任何情况,都更新表单
}
}
由于上述代码都是在ODBCView.cpp中,即上述操作是在视图中完成的,但查询条件是在“查询”对话框中输入的,在视图中接收了对话框的输入内容,因此,需要在ODBCView.cpp中加入代码:
#include"SearchDlg.h"
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验五 数据库应用程序的开发 实验 数据库 应用程序 开发