Database Application Developing 第13章 数据库及其应用 Database Application Developing DATA Database Server 清华大学计算机与信息管理中心---黄维通
1 Database Basics Hierachy Network Relational DB Model OO 第13章 数据库及其应用 1 Database Basics Hierachy Network Relational OO DB Model Big DB: Oracle、SQL Server, Small DB: Access Relational 清华大学计算机与信息管理中心---黄维通
第13章 数据库及其应用 2 Introduction to ODBC 清华大学计算机与信息管理中心---黄维通
2.1 ODBC Introduction Transparency 第13章 数据库及其应用 2.1 ODBC Introduction ODBC(Open Database Connectivity) 开放数据库互连 Provided by Microsoft. Includes ODBC-Drivers to various DBs. Can process all DBs in the same way(by invoking functions provided by ODBC) ODBC driver Dlls are dynamically linked when invoking ODBC functions. ODBC base applications don’t rely on and DBMS(like Oracle etc.) All DB-operations are achieved by ODBC drivers. Transparency 清华大学计算机与信息管理中心---黄维通
ODBC APIs are independent of any DBMS。 第13章 数据库及其应用 ODBC Data Source Console is where Windows manages Data Sources, and where Data Drivers & Data sources are registered. With ODBC API & MFC ODBC Classes,we can access any Data Resources(including DBs, files,etc.), so long as ODBC drivers are installed. ODBC APIs are independent of any DBMS。 清华大学计算机与信息管理中心---黄维通
ODBC Cursor Library: another dll。 第13章 数据库及其应用 ODBC is one part of Microsoft Windows Database Service. It’s components include: ODBC API :function set、error code set、standard SQL set (used to access data in DBs)。 ODBC Driver Manager:ODBC32.DLL---used in load ODBC drivers(Transparent to you) ODBC database drivers:one or more DLLs,including ODBC APIs,called by according DBMS。 ODBC Cursor Library: another dll。 ODBC Administrator :ODBC console,managint various data sources . 清华大学计算机与信息管理中心---黄维通
2.2 MFC ODBC Encapsulation 第13章 数据库及其应用 2.2 MFC ODBC Encapsulation 清华大学计算机与信息管理中心---黄维通
2.3 Access Database Set up ODBC DataSource Connect to DataSource 第13章 数据库及其应用 2.3 Access Database Set up ODBC DataSource Connect to DataSource Select and process Data(Tables) View&Document---Interface of Data DB Access 清华大学计算机与信息管理中心---黄维通
2.4 MFC ODBC Classes 1 CRecordView 第13章 数据库及其应用 2.4 MFC ODBC Classes 1 CRecordView A CRecordView object is used to display records in DB with controls in Views. CRecordView uses Dynamical Data Exchange(DDX)and Record Field Exchange(RFX),to exchanges data in DB and Controls in Views。 AppWizard creates CRecordView & CRecordset objects,and associates DBs with them。 清华大学计算机与信息管理中心---黄维通
Create a DB Application, Displaying records in Access。 第13章 数据库及其应用 【Example 1】 Create a DB Application, Displaying records in Access。 清华大学计算机与信息管理中心---黄维通
Procedure: 1. Using AppWizard to create an SDI ODBC project(step2) 第13章 数据库及其应用 Procedure: 1. Using AppWizard to create an SDI ODBC project(step2) 清华大学计算机与信息管理中心---黄维通
Selected an Access DB file My_Access_db.mdb 第13章 数据库及其应用 Selected an Access DB file My_Access_db.mdb 清华大学计算机与信息管理中心---黄维通
The RecordView Dialog IDC_BOOK_ID IDC_BOOK_PRICE IDC_BOOK_AUTHOR IDC_BOOK_PRESS
第13章 数据库及其应用 作者 出版社 单价 Using ClassWizard to associate member variables Edit Box with EditBoxes. In Add Member Variable Dialog, table Fields are in,Just select them. 清华大学计算机与信息管理中心---黄维通
第13章 数据库及其应用 2 CRecordset You’d better derived a class from CRecordset. After reading data from DB, you can use it to: Read Records。 Alter Records。 Select Records。 Sort Records。 Etc. 清华大学计算机与信息管理中心---黄维通
第13章 数据库及其应用 3 CDatabase CDatabase is declared in afxdb.h.Its instances are used to connect to DSN. After creation, the object can invoke OpenEx/Open to open a link to Database. Then its address can be sent to a CRecordset object. When all finishes, it must be closed by Close(). 清华大学计算机与信息管理中心---黄维通
第13章 数据库及其应用 4 RFX RFX (Record Field Exchange) is used to support data exchange with Controls and Database. RFX invokes DoFieldExchange to achieve this. The function can be called many times for more than one data. 清华大学计算机与信息管理中心---黄维通
Some codes from【Example1】AppWizard auto-generated RFX codes,See: 第13章 数据库及其应用 Some codes from【Example1】AppWizard auto-generated RFX codes,See: void CODBCSet::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 } 清华大学计算机与信息管理中心---黄维通
Abstracted from CRecordset-Derived Class: 第13章 数据库及其应用 DoFieldExchange is the pivot of RFX mechanism,any time when App Framework needs data exchange, it’s invoked。 Abstracted from CRecordset-Derived Class: class CODBCSet : public CRecordset { … // Field/Param Data //{{AFX_FIELD(CODBCSet, CRecordset) long m___ID; CString m_column1; CString m_column2; CString m_column3; //}}AFX_FIELD // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CODBCSet) public: …… virtual void DoFieldExchange(CFieldExchange* pFX); // RFX support //}}AFX_VIRTUAL … }; 清华大学计算机与信息管理中心---黄维通
第13章 数据库及其应用 5 CDBException CDBException is used for Exception Processing。User can use ::AfxThrowDBException to throw an Exception: m_nRetCode:has a structure: RETCODE ,with details of ODBC error information。 m_strError:Exception information string。 m_strStateNativeOrigin: m_strStateNativeOrigin CDBException Member vars 清华大学计算机与信息管理中心---黄维通
响应命令UPDATE_COMMAND_UI 第13章 数据库及其应用 【Example 2】Add MenuItems to【Example 1】 “删除一个记录”、“更新记录”和“清除域” for deletion, updating, and clearing records。 1 add: 响应COMMAND命令 响应命令UPDATE_COMMAND_UI 清华大学计算机与信息管理中心---黄维通
2 OnMove Overloading(virtual) 第13章 数据库及其应用 2 OnMove Overloading(virtual) 清华大学计算机与信息管理中心---黄维通
BOOL CODBCView::OnMove(UINT nIDMoveCommand) {switch(nIDMoveCommand) 第13章 数据库及其应用 BOOL CODBCView::OnMove(UINT nIDMoveCommand) {switch(nIDMoveCommand) { case ID_RECORD_PREV: m_pSet->MovePrev(); if(!m_pSet->IsBOF()) break; //如果移到数据库的开始,自动执行MoveFirst函数 case ID_RECORD_FIRST: m_pSet->MoveFirst(); break; case ID_RECORD_NEXT: m_pSet->MoveNext(); if(!m_pSet->IsEOF()) break; if(!m_pSet->CanScroll()) { m_pSet->SetFieldNull(NULL); //清空屏幕 break; } case ID_RECORD_LAST: m_pSet->MoveLast(); break; default: ASSERT(FALSE); //异常情况 } UpdateData(FALSE); //交换数据 return TRUE; 清华大学计算机与信息管理中心---黄维通
3 Menu Commands: void CODBCView::OnDeleteRecord() //删除记录 第13章 数据库及其应用 3 Menu Commands: 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(); 清华大学计算机与信息管理中心---黄维通
void CODBCView::OnUpdateDeleteRecord(CCmdUI* pCmdUI) //删除后的刷新 第13章 数据库及其应用 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(); } 清华大学计算机与信息管理中心---黄维通
pCmdUI->Enable(!m_pSet->IsEOF()); } 第13章 数据库及其应用 void CODBCView::OnUpdateUpdateRecord(CCmdUI* pCmdUI) //刷新记录集 { pCmdUI->Enable(!m_pSet->IsEOF()); } void CODBCView::OnClearDomain() //清除域 m_pSet->SetFieldNull(NULL); UpdateData(FALSE); 清华大学计算机与信息管理中心---黄维通
增加一个菜单项“增加一个新记录”,其ID标识为ID_ADD_RECORD 第13章 数据库及其应用 【Example 3】enable Adding New Record to【Example 2】 增加一个菜单项“增加一个新记录”,其ID标识为ID_ADD_RECORD 清华大学计算机与信息管理中心---黄维通
在数据库中增加记录步骤: Get the last record’s ID Increase by 1 第13章 数据库及其应用 在数据库中增加记录步骤: Get the last record’s ID Increase by 1 Invoke AddNew to add a record Set the new ID for the new Record Update database Requery to update recordset Scroll to the last record 清华大学计算机与信息管理中心---黄维通
GetMaxID :to calculate the new ID 第13章 数据库及其应用 GetMaxID :to calculate the new ID long CODBCSet::GetMaxID() { MoveLast(); //移到最后一条记录 return m___ID; //返回该ID值 } 清华大学计算机与信息管理中心---黄维通
long m_lNewID=m_pSet->GetMaxID()+1;//获取新的ID值 第13章 数据库及其应用 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); //更新表单 清华大学计算机与信息管理中心---黄维通
IDD_MOVE_RECORD IDC_RECORD_ID 第13章 数据库及其应用 【Example 4】add positioning and Sorting to【example 3】。 1.create a dialog for record positioning. Note:the input is not the book-ID. IDD_MOVE_RECORD IDC_RECORD_ID 清华大学计算机与信息管理中心---黄维通
{ CRecordset *pSet=OnGetRecordset(); //指向数据库记录的指针 第13章 数据库及其应用 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); //更新表单 } } 清华大学计算机与信息管理中心---黄维通
Add to ODBCView’s Implementation file ODBCView.cpp: 第13章 数据库及其应用 Add to ODBCView’s Implementation file ODBCView.cpp: #include "MoveToRecord.h" Toolbar: add an Move Button,ID==ID_MoveToRecord。 清华大学计算机与信息管理中心---黄维通
void CODBCView::OnSortPrice() { m_pSet->Close(); //关闭数据库 第13章 数据库及其应用 CRecordset has an member variable:m_strSort,which decides how to sort the records. Add MenuItem ID_SORT_PRICE(“按价格排序”),add COMMAND handler: OnSortPrice()。 void CODBCView::OnSortPrice() { m_pSet->Close(); //关闭数据库 m_pSet->m_strSort=“价格”; //指定排序字段 m_pSet->Open(); //再次打开数据库 UpdateData(FALSE); //更新已经排序过的记录 } In Toolbar: add Sort button for “按价格排序” 清华大学计算机与信息管理中心---黄维通
【Example 5】add to【Example 4】search function 第13章 数据库及其应用 【Example 5】add to【Example 4】search function Add MenuItem “按作者查找” (ID_Search) , COMMAND handler :OnSearch()。 For example, search”作者”: void CODBCView::OnSearch() { DoFilter("作者"); } 清华大学计算机与信息管理中心---黄维通
void CODBCView::DoFilter(CString col) {CSearchDlg dlg; 第13章 数据库及其应用 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.”); 第13章 数据库及其应用 if(recCount==0) //如果没有找到相关记录 { MessageBox(“No matching records.”); m_pSet->Close(); //关闭表单 m_pSet->m_strFilter; //将过滤结果给过滤器 m_pSet->Open(); //根据过滤结果打开表单(什么都没找到) } UpdateData(FALSE); //不论任何情况,都更新表单 Add to ODBCView.cpp the header for Search Dialog Class: #include "SearchDlg.h" 清华大学计算机与信息管理中心---黄维通