MFCODBC访问数据库.docx
- 文档编号:6208910
- 上传时间:2023-01-04
- 格式:DOCX
- 页数:21
- 大小:29.74KB
MFCODBC访问数据库.docx
《MFCODBC访问数据库.docx》由会员分享,可在线阅读,更多相关《MFCODBC访问数据库.docx(21页珍藏版)》请在冰豆网上搜索。
MFCODBC访问数据库
主要内容撒:
的撒旦
ØMFCODBC将ODBCAPI封装在类CDatabase、CRecordSet、CFieldExchange、CRecordView和CDBException中
Ø使用MFCODBC开发数据库应用程序的一般步骤
Ø使用AppWizard访问数据库
Ø使用类CDatabase连接数据库
Ø使用类CRecordSet打开记录集、获取数据
Ø使用类CRecordSet的函数MoveFirst()、MoveLast()、MoveNext()、MovePrev()、IsBOF()和IsEOF()进行记录集的遍历
Ø使用类CRecordSet的函数AddNew和Update增加记录
Ø使用类CRecordSet的函数Edit和Update修改记录
Ø使用类CRecordSet的函数Delete删除记录
Ø使用类CDatabase的函数ExecuteSQL直接执行SQL命令
Ø使用类CDatabase的函数BeginTrans、CommitTrans和Rollback处理事务
MFCOBDC技术
概述
MFC的ODBC类对较复杂的ODBCAPI进行了封装,提供了简化的调用接口。
MFC的ODBC类主要包括以下5个类:
✧CDatabase类:
主要功能是建立与数据源的连接
✧CRecordset类:
代表从数据源选择的一组记录(记录集)
✧CRecordView类:
提供了一个表单视图与某个记录集直接相连,利用对话框数据交替机制(DDX)在记录集与表单视图的控件之间传输数据
✧CFieldExchange类:
支持记录字段数据交换(RFX),即记录集字段数据成员与相应的数据库的表的字段之间的数据交换。
✧CDBException类:
代表ODBC类产生的异常。
CDatabase类操作数据源
CDatabase类型的对象表示一个到数据源的连接,通过它可以操作数据源。
该类的成员函数如下表:
函数
说明
CDatabase
构造一个对象
Close
关闭数据源连接
Open
通过一个ODBC驱动程序创建到数据源的连接
OpenEx
通过一个ODBC驱动程序创建到数据源的连接
BeginTrans
开始事务
BindParameters
允许在调用CDatabase:
:
ExecuteSQL前绑定参数
Cancel
取消异步操作或第二条线程中的过程
CommitTrans
执行事务
ExecuteSQL
执行SQL语句,不返回记录
Rollback
回滚事务,数据源返回先前的状态
该类的属性属性如下表:
属性
说明
CanTransact
如果数据源支持事务,返回非零
CanUpdate
如果CDatabase可以更新,返回非零
GetBookmarkPersistence
获得书签对记录集对象的持久性
GetConnect
返回ODBC连接串
GetCursorCommitBehavior
获得提交事务对记录集对象的影响
GetCursorRollbackBehavior
获得回滚事务对记录集对象的影响
GetDatabaseName
返回当前使用的数据库名
IsOpen
如果当前CDatabase对象连接到数据源,返回非零
SetLoginTimeout
设置数据源连接的超时数(秒为单位)
SetQueryTimeout
设置查询操作的超时数(秒为单位)
应用程序可使用多个CDatabase类型的对象。
构造一个对象并调用Open()成员函数打开一个连接。
接着构造CRecordset类型的对象以操作连接的数据源,构造时向记录集对象传递CDatabase类型的指针。
完成使用后,用Close()成员函数销毁CDatabase类型的对象。
一般情况下并不需要直接使用CDatabase类型的对象,因为CRecordset类型的对象可以实现大多数的功能、但是在进行事务处理时,CDatabase就起到关键作用。
事务(Transaction)指的是将一系列对数据源的更新放在一起,同时提交或一个都不提交,为的是确保多用户对数据源同时操作时的数据正确性。
CRecordset类操作记录集
一个CRecordset类型的对象代表从数据源选择的一组记录的集合——记录集,通过该类的方法实现对数据库中记录的各种操作。
该类常用的数据成员如下表:
成员
说明
m_hstmt
包含记录集的ODBC陈述句柄,类型为HSTMT
m_nFields
包含记录集中字段数据成员的数量,类型为UNIT
m_nParams
包含记录集中参数数据成员的数量,类型为UNIT
m_pDatabase
包含一个CDatabase对象指针,通过它访问数据源
m_strFilter
包含CString对象,定义SQL中WHERE子句
m_strSort
包含CString对象,定义SQL中ORDERBY子句
该类的构造方法如下表:
构造方法
说明
Close
关闭记录集和与之相关的HSTMT
CRecordset
构造一个CRecordset对象
Open
通过获得表或执行记录集所代表的查询来打开记录集
CRecordset类记录集属性如下表:
属性
说明
CanAppend
如果新记录可以通过Addnew添加到记录集,返回非零
CanBookmark
如果记录集支持书签,返回非零
CanRestart
如果Requery可以被调用来再次运行记录集查询,返回非零
CanScroll
如果可以在记录中回滚,返回非零
CanTransact
如果数据源支持事务,返回非零
CanUpdate
如果记录集可以被更新,返回非零
GetODBCFieldCount
返回记录集中字段的数量
GetRecordCount
返回记录集中记录的数量
GetSQL
获得SQL字符串
GetStatus
获得记录集的状态
GetTableName
获得记录集所属的表名
IsBOF
如果记录集定位在第一条记录之前,返回非零
IsDeleted
如果记录集定位在一条删除的记录,返回非零
IsEOF
如果记录集定位在最后一条记录之后,返回非零
IsOpen
如果调用过Open函数,返回非零
CRecordset类更行操作如下表:
更新操作
说明
AddNew
准备增加一条新纪录,调用Update之后完成添加
CancelUpdate
取消任何未完成的更新
Delete
从记录集中删除当前记录
Edit
准备对当前记录进行修改,调用Update后完成修改
Update
通过将新记录或编辑的数据存入数据源来完成AddNew或Edit操作
记录集有两种形式:
snapshot(表示数据的静态视图)和dynaset(表示记录集与其他用户对数据库的更新保持同步)。
CFieldExchange类处理数据交换
CFieldExchange类支持数据库类所使用的记录集字段交换(RFX)程式。
如果使用自定义的数据类型写数据交换程式,会使用这个类。
否则不会直接使用此类。
RFX在记录集对象的字段数据成员与数据源中当前记录的相应字段之间交换数据。
CRecordView类显示记录
CRecordView对象用于在控件中显示数据库记录的视图。
这种视图是一种直接连到一个CRecordView对象的格式视图,它从一个对话框模板创建资源,并将CRecordView对象的字段显示在对话框模版的控件里。
对象利用DDX和RFX机制,使窗体上的空间和记录集的字段值之间数据移动自动化,也就是说,用户不需要编写一行代码就可以完成简单的数据库记录查看程序。
CDBException类处理异常
由CException类派生,以3个继承的成员变量反映对数据库操作时的异常:
✧m_nRetCode:
以ODBC返回代码(SQL_RETURN)的形式表明造成一场的原因
✧m_strError:
字符串,描述造成抛出异常的错误原因
✧m_strStateNativeOrigin:
字符串,用以描述以ODBC错误代码表示的异常错误
使用MFCODBC编程建立应用程序
MFCODBC编程模型概述
使用MFCODBC访问数据库比直接使用ODBCAPI简单得多,编程步骤如下:
✧使用CDatabase打开数据源的连接,如果利用AppWizard生成一个ODBC数据库应用程序,则会自动完成操作。
✧使用ClassWizard向导加入由CRecordset类派生的用户记录集类,完成对数据库的绑定。
✧创建记录集类对象,如果利用AppWizard生成一个ODBC数据库应用程序,则会自动在文档类中创建。
✧使用记录及对象对数据库进行遍历、增加、删除、修改等操作。
✧使用CDatabase类的ExecuteSQL函数直接执行SQL命令。
✧使用CDatabase类的BeginTrans、CommitTrans和Rollback函数进行事务处理
✧使用CDatabase类的Close函数关闭数据源连接。
通过AppWizard建立数据库应用程序
“New”-->”MFCAppWizard(EXE)”-->”OK”->”Singledocument(单文档)”-->NEXT-->”选择需要对什么样的数据库类型支持做出选择:
None(不要任何数据支持,今后再添加很麻烦)、Headerfilesonly(该工程需要数据库支持,但不清楚细节时选择。
工程会添加所要求的头文件和链接库,但必须自己在创建数据库类)、Databaseviewwithoutfilesupport(表示包含数据库头文件和链接库,并创建记录集和记录视图,应用程序虽有文档支持,但不支持串行化)、Databaseviewwithfilesupport(表示包含数据库头文件、记录集和视图外,程序还支持串行化)-->”DataOptions对话框:
在”Datasource”中选择ODBC单选按钮,选择一个已经注册号的数据源(实例程序Sample中使用的数据源叫students)。
在”Recordsettype”(记录类型)中有三个选项:
Snapshot(快照:
它是当前表的一个静态视图。
表打开之后,表中的所有数据马上被载入到应用程序中。
其他用户或程序对表的修改只有在下次打开表时才会体现出来,看不到其他用户对表的”即时”修改,因此它是静态的。
Snapshot适用于用户查询信息(例如生成报表等)而不适用于数据编辑。
)、Dynaset(动态集:
这个选项创建指向所请球的每个记录的实际指针。
只有屏幕需要显示记录时,才从数据库中提取数据。
这种方式的好处是动态、即时的浏览到当前的记录。
而其他用户也会即时看到你对记录所做出的修改。
该选项适合于创建用户要发费很多时间来编辑数据的应用程序,并且,如果正在编写大型数据库应用程序,他也是最佳选择)、Table(表:
表方法(仅使用DAO访问数据库时可用)把所做查询的内容放进一个临时表。
这样做不但减小了从服务器下载的信息量,还意味着程序员有了更大的灵活性,因为可以直接操作临时表字段和记录。
但缺点是你看不到别人的修改。
使用DAO且用户会执行同等数量的数据查询和数据编辑时,它是最佳选择。
)”-->”SeleteDatabaseTable(选择数据库表)”-->”Finish”.
通过AppWizard创建了一个MFCODBC数据库工程后,该工程与一般的应用程序工程有所不同:
多了一个CRecordset的派生类,对应前面选择的数据库表;视图类的基类是CRecordView,负责显示数据;工具栏上多了遍历记录集的4个按钮。
使用CDatabase类方法打开数据源
通过CDatabase类的Open函数来打开数据源,该函数原型如下:
virtualBOOLOpen(
LPCTSTRlpszDSN,//一个数据源名,此数据源名是通过ODBC管理器注册的。
如果DSN被设定在lpszConnect里,那么lpszDSN不应在被重新设定,lpszDSN应设为NULL。
如果没有设定lpszConnect,而且又把lpszDSN设定为NULL,那么将出现一个对话框,让用户选择数据源。
BOOLbExclusive=FALSE,//默认为FALSE,表示以共享方式打开数据源。
当前版本的类库不支持独占方式,如果设定为TRUE,将失败
BOOLbReadOnly=FALSE,//如果希望连接以只读方式打开,不想对数据源进行更新,那么设定为TRUE,所有依靠此连接打开的记录集全部继承此属性。
默认值为FALSE
LPCTSTRlpszConnect=_T(“ODBC;”),//连接串。
连接串可能包含数据源名、数据源中用户的ID、密码和其他信息。
整个连接串必须以”ODBC;”开头。
”ODBC;”表示连接是一个ODBC数据源。
BOOLbUseCursorLib=TRUE//如果希望加载ODBC光标动态连接库,设定为TRUE
);
下面的例子表示如何打开数据源:
//在文档类中加入
//CDatabase类对象
CDatabasem_pdatabase;
//连接对象到一个数据源(没有密码),ODBC连接对话框将是中隐藏
m_pdatabase.Open(_T(“students”),FALSE,FALSE,_T(“ODBC;UID=Admin”));
//或者也可以显示ODBC对话框,请用户提供连接信息
m_pdatabase.Open(NULL);
像程序Sample一样,通过向导生成数据库工程,不用添加代码就能实现对数据源的打开。
在CRecordset类中有一个名为GetDefaultConnect()的虚函数值得注意,通过调用它可以返回默认的数据源连接(也就是在生成工程的时候所选择的数据源)来打开数据源。
该函数如下:
CStringCSampleSet:
:
GetDefaultConnect()
{
return_T(“ODBC;DSN=students”);
}
使用CRecordste类打开记录集
通过声明CRecordset记录集类的对象,再利用记录集类的Open()函数可打开记录集,从而获取数据库中表的数据。
也正是在调用Open()函数后,记录集当中的成员变量得到数据源中表的字段值。
Open()函数的形式如下:
virtualBOOLOpen(
UNITnOpenType=AFX_DB_USE_DEFAULT_TYPE,
LPCTSTRlpszSQL=NULL,
DWORDdwOptions=none
);
其中nOpenType为打开的类型,可取只有一下4种:
✧CRecordset:
:
dynaset:
双向滚动的记录集,在记录集打开时,记录的顺序和成员就被确定了。
其他用户对数据的修改在fetch操作之后才可访问,这也被叫做键集驱动的记录集。
✧CRecordset:
:
dynamic:
双向滚动的记录集,其他用户对数据的修改在fetch操作后才可访问。
许多ODBC驱动程序都不支持此种记录集。
✧CRecordset:
:
ForwardOnly:
只读记录集,只向前滚动。
第二个参数lpszSQL是一个CString的指针,指向以下内容之一:
✧一个NULL指针;
✧一个表名;
✧一个SQL查询语句
第三个参数dwOptions为一系列选项的组合,它的默认值为None。
可以像下面这样调用Open()函数来打开记录集:
CDatabasem_pdatabase;
m_pdatabase.Open(_T(“students”),FALSE,FALSE,_T(“ODBC;UID=Admin”));
CRecordsetSample(&m_pdatabase);
Sample.Open(CRecordset:
:
dynaset,_T(“Selectnamefromstudents”));
以上语句先用CDatabase对象打开一个数据源,之后构造记录及对象,最后记录及对象Sample以动态方式打开students表中的name字段。
下面的语句表示以全部默认方式执行记录记得打开操作:
CDatabasem_pdatabase;
m_pdatabase.Open(_T(“students”),FALSE,FALSE,_T(“ODBC;UID=Admin”));
CRecordsetSample(&m_pdatabase);
Sample.Open();
也可以像下面代码中那样打开一个表中的所有字段:
CDatabasem_pdatabase;
m_pdatabase.Open(_T(“students”),FALSE,FALSE,_T(“ODBC;UID=Admin”));
CRecordsetSample(&m_pdatabase);
Sample.Open(CRecordset:
:
dynaset,_T(“Select*fromstudents”));
经过上面的操作,记录集对象的字段变量就获得了数据库中特定表中指定字段的数据。
像程序Sample一样,在向导当中选择数据源和表名。
在CRecordset类中有一个名为GetDefaultSQL()的虚函数值得注意,通过调用它可以返回默认的SQL语句,用于形成记录集对象。
该函数如下:
CStringCSampleSet:
:
GetDefaultSQL()
{
return_T(“[students]”);
}
绑定记录集
通过向导创建工程后,程序的框架就生成出来。
如果打开CRecordset的派生类CSampleSet,会发现里面已经有了5个变量:
//Field/ParamData
//{{AFX_FIELD(CSampleSet,CRecordset)
longm_id;
CStringm_name;
Longm_department;
Longm_age;
CStringm_comment;
//}}AFX_FIELD
这5个变量正好与要访问的表中的字段同名,并且变量的类型也与字段类型一致。
这是MFC自动添加的变量,已绑定表中的字段。
如果表中的字段是中文的,那么MFC会创建m_column1、m_column2等与之对应。
RFX实现了这种绑定。
RFX(RecordFieldExchange),记录字段交换使记录集(CREcordset)和隐藏于后台的数据源(Datasource)之间建立其对应的关系。
用户只需要操作记录集,就可以实现对数据源的操作。
MFC中提供了一组RFX调用函数,利用这些函数,就可以使记录集中的变量与数据源中的字段对应起来。
使记录集和数据之间进行数据交换成为可能,并且,这种交换是双向的。
可以在CSampleSet类的DoFieldExchange函数中看到一组组的RFX函数调用,正是通过调用它们,使CSampleSet记录集中的变量与students表中的字段对应起来。
voidCSampleSet:
:
DoFieldExchange(CFieldExchange*pFx)
{//{{AFX_FIELD_MAP(CSampleSet)
pFX->SetFieldType(CFieldExchange:
:
outputColumn);
RFX_Long(pFX,_T(“[id]”),m_id);
RFX_Long(pFX,_T(“[name]”),m_name);
RFX_Long(pFX,_T(“[department]”),m_department);
RFX_Long(pFX,_T(“[age]”),m_age);
RFX_Long(pFX,_T(“[comment]”),m_comment);
//}}AFX_FIELD_MAP
}
RFX函数通常有3个参数(个别的会有4或5个)。
第一个参数为一个指向CFieldExchange类对象的指针,第二个参数为数据源中的一个字段名称,第三个参数是与字段相对应的记录集中的变量名。
常用的RFX函数如下表:
函数
数据类型
RFX_Bool
BOOL
RFX_Byte
BYTE
RFX_Binary
CByteArray
RFX_Double
Double
RFX_Sing
Float
RFX_Int
Int
RFX_Long
Long
RFX_LongBinary
CLongBinary
RFX_Text
CString
RFX_Date
CTime
参数化记录集和查询
CRecordset类对象中有两个成员变量,一个为m_strFilter(过滤字符串,负责对记录集进行过滤,返回过滤后的记录),另一个为m_strSort(排序字符串,对记录集进行排序)。
m_strFilter存放着SQL语句中WHERE子句的条件字符串,m_strSort中则存放着SQL语句中ORDERBY子句的字符串。
经过对它们的赋值,可以更加灵活的获得数据库中特定的数据,以及对记录进行排序。
下面的代码中向m_strFilter赋值“comment=good”,向m_strSort赋值“name”:
CRecordsetSample;
Sample.m_strFilter=“comment=good”;
Sample.m_strSort=“name”;
除了直接向m_strFilter赋值外,还可以使用参数化。
利用参数化可以更直观,更方便地完成条件查询任务。
使用参数化的步骤如下:
首先声明参变量:
CStringage1;
CStringcomment1;
在构造函数中初始化参变量
age1=_T(“”);
comment=_T(“”);
将参变量与对应列绑定
pFX->SetFieldType(CFieldExchange:
:
param);
pFX->Text(pFX,_T(“[age]”),age1);
pFX->Text(pFX,_T(“[comment]”),comment1);
最后利用参变量进行条件查询
m_pSet->m_strFilter=“age=?
ANDcomment=?
”;
m_pSet->age=“21”;
m_pSet->comment=“good”;
m_pSet->Requery();
参变量的值按绑定的顺序替换查询字符串中的“?
”适配符。
代码中的m_pSet是CRecordView类的一个记录集指针,指向当前文档类中的记录集变量。
它是在CRecordView类的OnInitialUpdate中被赋予文档类下记录集对象的指针的。
下面是程序中CSampleView类的OnInitialUpdate函数体:
voidCSampleView:
:
OnInitialUpdate()
{//为m_pSet赋予文档类下的记录集对象的指针
m_pSet=&GetDocument()->m_sampleSet;
CRecordView:
:
OnInitialUpdate();
ResizeParentToFit();
}
遍历记录集合
CRecordset类中有一组函数负责记录集指针的移动,例如使用记录集指针下移一个记录、使用记录集指针上移一
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- MFCODBC 访问 数据库