一、数据库应用程序中常用的几个类 1。CrecordView类 一个CRecordView对象就是用一个视图中的控件来显示数据库中的记录。CRecordView类使用了动态数据交换(DDX)和数据库交换(RFX),在视图上的控件和数据源中的数据库中进行数据交换。 AppWizard 生成CRecordView和CRecordset类,并和相应的数据源关联。 2。CRecordset类 为了能够处理各种的数据库,最好从类CRecordset派生出一个子类来。数据库从数据源读取数据后,可以做以下的工作: 翻阅所有的记录。 修改记录,设定锁定状态。挑选有用的记录。给数据库排序。给定参数,让数据库在运行的时候自动选择数据。 3。CDatabase类 CDatabase在afxdb.h中定义。其对象是用来连接一个数据源的。为了使用CDatabase对象,需调用构造函数,并调用OpenEx或是Open函数,这将会打开一个连接。当构造一个CDatabase类完成后,可以向CRecordset类的对象传递这个CDatabase类的指针。连接数据源结束时,必须用Close函数关闭这个对象。 4。RFX 5。CDBException CDBException是用来处理从其它ODBC类传过来的异常情况的。这个类一般是和关键字CATCH连用的。同样的用户也可以用全局函数AfxThrowDBException抛出一个异常情况 二、实例步骤 1。用AppWizard来生成一个单文档的ODBC工程文件
添加菜单响应函数 void CODBCView::OnDeleteRecord() //删除记录 {CRecordsetStatus m_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); } void CODBCView::OnUpdateDeleteRecord(CCmdUI* pCmdUI) //删除后的刷新 { pCmdUI->Enable(!m_pSet->IsEOF()); } void CODBCView::OnUpdateRecord() { m_pSet->Edit(); UpdateData(TRUE); if(m_pSet->CanUpdate()) m_pSet->Update(); } void CODBCView::OnUpdateUpdateRecord(CCmdUI* pCmdUI) //刷新记录集 { pCmdUI->Enable(!m_pSet->IsEOF()); } void CODBCView::OnClearDomain() //清除域 { m_pSet->SetFieldNull(NULL); UpdateData(FALSE); }
long CODBCSet::GetMaxID() { MoveLast(); //移到最后一条记录 return m___ID; //返回该ID值 } void CODBCView::OnAddRecord() {CRecordset * pSet=OnGetRecordset();//获取指向数据库的指针 if(pSet->CanUpdate()&&!pSet->IsDeleted()) //确认对数据库的任何修改均已保存 { pSet->Edit(); if(!UpdateData()) return; pSet->Update(); } long m_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); //更新表单 }
void CODBCView::OnMoveToRecord() {CMoveToRecord dlgMoveTo; //创建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); //更新表单 } } 由于CRecordset类的对象或从CRecordset类继承的对象都拥有一个m_strSort成员,它决定了对记录的排序,在“记录”菜单中增加菜单项“按价格排序”,(ID_SORT_PRICE),并为它映射COMMAND消息处理函数OnSortPrice()。 void CODBCView::OnSortPrice() { m_pSet->Close(); //关闭数据库 m_pSet->m_strSort=“价格”; //指定排序字段 m_pSet->Open(); //再次打开数据库 UpdateData(FALSE); //更新已经排序过的记录 } 由于用了CRecordset类的成员m_strSort,因此对数据库记录的排序不用进行太多的代码干预。 最后在工具栏中增加Sort工具按钮,实现菜单项“按价格排序”的功能。 假设按“作者”字段进行查询,为菜单项“按作者查找”所映射的COMMAND消息处理函数代码如下: void CODBCView::OnSearch() { DoFilter("作者"); } void CODBCView::DoFilter(CString col) {CSearchDlg dlg; int result=dlg.DoModal(); if(result==IDOK) { CString str=col+"='"+dlg.m_Edit_Search+"'"; //接收查询字符串 m_pSet->Close(); //关闭原来的表单 m_pSet->m_strFilter=str; //将查询条件赋给过滤器 m_pSet->Open(); //打开经过过滤的表单 int recCount=m_pSet->GetRecordCount(); //计算满足条件的记录数 if(recCount==0) //如果没有找到相关记录 { MessageBox(“No matching records.”); m_pSet->Close(); //关闭表单 m_pSet->m_strFilter; //将过滤结果给过滤器 m_pSet->Open(); //据过滤结果打开表单(什么都没找到) } UpdateData(FALSE); //不论任何情况,都更新表单 } } |
|