第9章连接数据库连接数据库的方式ODBC(OpenDatabaseConnectivity,开放数据库互连)是微软公司开放服务结构中有关数据库的一个组成部分,它建立了一组规范,并提供了一组对数据库访问的标准API(应用程序编程接口)。这些API利用SQL来完成其大部分任务。ODBC本身也提供了对SQL语言的支持,用户可以直接将SQL语句送给ODBC。连接数据库的方式ODBC(OpenDataBaseConnectivity)应用程序使用ODBCAPI访问数据库时,是由ODBC管理器将应用程序的数据库访问请示传递给相应的数据库驱动程序,驱动程序再用SQL语句完成DBMS的访问任务。DAO(DataAccessObjects)DAO使用MicrosoftJet提供的数据库访问对象集直接访问DBMS,速度比ODBC要快。注册ODBC数据源应用程序要访问一个数据库,首先必须用ODBC管理器注册一个数据源,管理器根据数据源提供的数据库位置、数据库类型及ODBC驱动程序等信息,建立起ODBC与具体数据库的联系。这样,只要应用程序将数据源名提供给ODBC,ODBC就能建立起与相应数据库的连接。MFCODBC的构成ODBC管理器:位于控制面板驱动程序管理器:ODBC32.dllODBC驱动程序:以DLL文件形式出现MFC的ODBC类简介MFC的ODBC类对较复杂的ODBCAPI进行了封装,提供了简化的调用接口,从而大大方便了数据库应用程序的开发。程序员不必了解ODBCAPI和SQL的具体细节,利用ODBC类即可完成对数据库的大部分操作。MFC的ODBC类简介MFC的ODBC类主要包括:CDatabase类:主要功能是建立与数据源的连接。CRecordset类:该类代表从数据源选择的一组记录(记录集),程序可以选择数据源中的某个表作为一个记录集,也可以通过对表的查询得到记录集,还可以合并同一数据源中多个表的列到一个记录集中.通过该类可对记录集中的记录进行滚动、修改、增加和删除等操作。MFC的ODBC类简介CRecordView类:提供了一个表单视图与某个记录集直接相连,利用对话框数据交换机制(DDX)在记录集与表单视图的控件之间传输数据。该类支持对记录的浏览和更新,在撤销时会自动关闭与之相联系的记录集。通常情况下,CDatabase针对某个数据库,它负责连接数据源;CRecordset针对数据源中的记录集,它负责对记录的操作CRecordset类的数据成员CRecordset类的成员函数...CRecordset类的成员函数数据库应用程序的实现创建并注册数据源创建数据库应用框架设计记录操作界面更新记录排序和筛选创建并注册数据源ODBC管理器的使用用户DSN用户数据源只对当前用户可见,而且只能用于当前机器上系统DSN系统数据源对当前机器上的所有用户可见文件DSN文件数据源可以由安装了相同驱动程序的用户共享数据源创建示例创建数据库应用框架AppWizard的选项设置:step2CExam9_1Set类classCExam9_1Set:publicCRecordset{public:CExam9_1Set(CDatabase*pDatabase=NULL);DECLARE_DYNAMIC(CExam9_1Set)//Field/ParamData//{{AFX_FIELD(CExam9_1Set,CRecordset)longm_CustomerID;CStringm_LastName;CStringm_FirstName;CStringm_HomeCountry;CStringm_HomeState;CStringm_PhoneNumber;CStringm_Comments;//}}AFX_FIELD//Overrides//ClassWizardgeneratedvirtualfunctionoverrides//{{AFX_VIRTUAL(CExam9_1Set)public:virtualCStringGetDefaultConnect();//DefaultconnectionstringvirtualCStringGetDefaultSQL();//defaultSQLforRecordsetvirtualvoidDoFieldExchange(CFieldExchange*pFX);//RFXsupport//}}AFX_VIRTUAL//Implementation#ifdef_DEBUGvirtualvoidAssertValid()const;virtualvoidDump(CDumpContext&dc)const;#endif};记录集字段数据成员构造函数CExam9_1Set::CExam9_1Set(CDatabase*pdb):CRecordset(pdb){//{{AFX_FIELD_INIT(CExam9_1Set)m_CustomerID=0;m_LastName=_T();m_FirstName=_T();m_HomeCountry=_T();m_HomeState=_T();m_PhoneNumber=_T();m_Comments=_T();m_nFields=7;//}}AFX_FIELD_INITm_nDefaultType=snapshot;}记录集类型创建连接CStringCExam9_1Set::GetDefaultConnect(){return_T(ODBC;DSN=HotelInfo);}CStringCExam9_1Set::GetDefaultSQL(){return_T([tblCustomer]);}用于获得定义了数据源类型和数据源名的连接字符串定义SQL语句的字符串,本例的SQL语句定义了查询一张表的完整记录记录集与数据库的数据交换voidCExam9_1Set::DoFieldExchange(CFieldExchange*pFX){//{{AFX_FIELD_MAP(CExam9_1Set)pFX-SetFieldType(CFieldExchange::outputColumn);RFX_Long(pFX,_T([CustomerID]),m_CustomerID);RFX_Text(pFX,_T([LastName]),m_LastName);RFX_Text(pFX,_T([FirstName]),m_FirstName);RFX_Text(pFX,_T([HomeCountry]),m_HomeCountry);RFX_Text(pFX,_T([HomeState]),m_HomeState);RFX_Text(pFX,_T([PhoneNumber]),m_PhoneNumber);RFX_Text(pFX,_T([Comments]),m_Comments);//}}AFX_FIELD_MAP}设计记录操作界面视图控件与记录集字段数据成员更新记录AddNew()Delete()Edit()Update()CancelUpdate()Requery()进入添加模式voidCExam9_1View::OnRecordAdd(){//TODO:Addyourcommandhandlercodeherem_pSet-AddNew();//进入添加模式m_addflg=true;//设置添加模式标志CEdit*m_pCtrl=(CEdit*)GetDlgItem(IDC_CustomerID);//清除ID编辑框的只读属性m_pCtrl-SetReadOnly(false);//用新记录的字段数据成员值更新控件显示UpdateData(false);}通过移动记录保存添加的新记录BOOLCExam9_1View::OnMove(UINTnIDMoveCommand){//TODO:Addyourspecializedcodehereand/orcallthebaseclassif(m_addflg)//添加模式处理{m_addflg=false;UpdateData(true);//使用控件值更新记录集字段数据成员if(m_pSet-CanUpdate())//将记录集更新保存到表中m_pSet-Update();m_pSet-Requery();//重新查询记录集UpdateData(false);//以更新后的记录集数据成员更新控件显示CEdit*m_pCtrl=(CEdit*)GetDlgItem(IDC_CustomerID);m_pCtrl-SetReadOnly(true);//设置ID编辑框为只读returntrue;}elsereturnCRecordView::OnMove(nIDMoveCommand);}删除记录voidCExam9_1View::OnRecordDelete(){//TODO:Addyourcommandhandlercodeherem_pSet-Delete();//删除当前记录m_pSet-MoveNext();//移到下一记录if(m_pSet-IsEOF())//删除记录为最后一条记录处理m_pSet-MoveLast();if(m_pSet-IsBOF())//删空记录集处理m_pSet-SetFieldNull(NULL);UpdateData(false);//更新控件显示}排序和筛选m_strFilterm_strSort排序voidCExam9_1View::OnViewSortId(){//定义排序关键字按ID排序m_pSet-m_strSort=CustomerID;m_pSet-Requery();//重新查询UpdateData(false);//更新控件显示}查询voidCExam9_1View::OnViewFilter(){//TODO:AddyourcommandhandlercodehereCFilterDlgdlg;CStringstr;if(dlg.DoModal()==IDOK)//调用筛选对话框,按OK按钮返回{if(dlg.m_Filter.IsEmpty())//编辑框为空,显示整个记录集str=;elsetr=HomeCountry='+dlg.m_Filter+';//定义筛选字符串m_pSet-m_strFilter=str;m_pSet-Requery();//重新查询记录集UpdateData(false);//更新控件显示}}实现书中例题:例9-1例9-2例9-3例9-4