MFC下使用ADO连接数据库

MFC下使用ADO连接数据库
MFC下使用ADO连接数据库

MFC下使用ADO读写Access数据库实例

一、原型系统描述 (2)

二、数据库表设计 (2)

三、数据库编程 (2)

1.新建MFC基于对话框项目 (2)

2.用#import指令引入ADO类型库 (2)

3.创建数据库操作类CADODatabase (3)

3.1为CADODatabase添加两个成员变量 (3)

3.2添加OpenDatabase函数 (3)

3.3添加CloseDatabase函数 (4)

3.4添加Select函数 (5)

3.5添加Execute函数 (6)

四、MFC界面编程 (6)

1.在对话框中添加控件 (6)

2.在程序启动时初始化列表框,并连接数据库 (7)

2.1初始化列表框 (7)

2.2连接数据库 (7)

3.添加查询功能 (8)

4.添加新增记录功能 (9)

五、使用Datagrid ActiveX控件 (10)

1.添加Datagrid控件 (10)

2.创建数据库 (11)

3.创建数据库操作类CADODatabase (12)

4.使用Datagrid (12)

4.1 绑定数据源 (12)

4.2 添加记录 (13)

说明:本文以“学生信息管理”系统雏形为例子,介绍在MFC下如何使用ADO连接数据库编程,并给出示例代码。下面内容第一至四节介绍如何采用ADO连接数据库、关闭数据、执行sql语句及如何用另一种方式执行常用的select语句。第五节介绍如何使用Datagrid控件:建立_RecordsetPtr对象与Datagrid控件之间的绑定,通过改变_RecordsetPtr 对象的内容更新数据库表的记录。第一至四节的内容请参考代码“CtrlListDatabase.rar”,第五节内容请参考“Datagrid.rar”请同学们结合https://www.360docs.net/doc/1c1334324.html,课程内容自主学习,将所学到的技术应用到项目实训中。

一、原型系统描述

本程序为一个学生信息管理系统雏形。程序界面如下图左图所示。用户在姓名栏输入查询字段,列表框中列出查询结果。如下图右图所示。

用户点击新增记录按钮新增学生信息记录。

二、数据库表设计

建立Access文件test.mdb,创建student表,表中字段名称、数据类型及各字段的说明设置如下

三、数据库编程

1.新建MFC基于对话框项目

新建MFC基于对话框项目。本例中对项目命名为CtrlListDatabase。

2.用#import指令引入ADO类型库

为了引入ADO类型库,需要在项目的stdafx.h文件中加入如下语句:

#import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF", "adoEOF")

注意添加的位置在#endif //_AFX_NO_AFXCMN_SUPPORT之后

3.创建数据库操作类CADODatabase

为CADODatabase添加两个成员变量

_ConnectionPtr m_pConnection;

_RecordsetPtr m_pRecordset;

其中m_pConnection是一个指向Connection对象的指针,通过它来连接数据库。

m_pRecordset是一个指向记录集合的指针,从数据库查询得到的结果放在m_pRecordset中。

添加OpenDatabase函数

功能:连接数据库

输入:数据库连接串strConnection(其含义见第四部分第二步中2.2的解释)

输出:TRUE,如果成功连接数据库,FALSE,如果连接数据库失败

BOOL CADODatabase::OpenDatabase(CString strConection)

{

HRESULT hr = ::CoInitialize(NULL); // 初始化COM

if (!SUCCEEDED(hr)) // 初始化失败

{

return FALSE;

}

_bstr_t strConnect(strConection);

try

{

// 创建Connection对象

hr = m_pConnection.CreateInstance("ADODB.Connection");

if (SUCCEEDED(hr))

{

// 连接数据库

if (SUCCEEDED(m_pConnection->Open(strConnect, "", "", adModeUnknown)))

{

return TRUE;

}

}

}

catch (_com_error e)

{

TRACE(_T("连接数据库发生错误%s\n"), e.ErrorMessage());

}

return FALSE;

}

上述代码中,通过Connection对象的Open方法来进行连接数据库的,下面是该方法的原型:

上述函数中参数ConnectionString为连接字串;参数UserID是用户名;参数Password 是登陆密码;在本例子中,数据库的用户名和密码均没创建,所以去空值””。参数Options 是连接选项,用于指定Connection对象对数据的更新许可权,一般情况下Options可以是如下几个常量:

adModeUnknown 缺省。当前的许可权未设置

adModeRead 只读

adModeWrite 只写

adModeReadWrite 可以读写

adModeShareDenyRead 阻止其它Connection对象以读权限打开连接adModeShareDenyWrite 阻止其它Connection对象以写权限打开连接adModeShareExclusive 阻止其它Connection对象以读写权限打开连接adModeShareDenyNone 阻止其它Connection对象以任何权限打开连接

添加CloseDatabase函数

功能:关闭数据库连接

返回:TRUE,如果成功关闭,否则FALSE。

BOOL CADODatabase::CloseDatabase()

{

if (m_pConnection == NULL)

{

// 如果连接已经为空

return TRUE;

}

try

{

m_pConnection->Close();

m_pConnection = NULL;

return TRUE;

}

catch (_com_error e)

{

TRACE(_T("关闭数据库发生错误:%s\n"), e.ErrorMessage());

}

return FALSE;

}

添加Select函数

功能:返回查询结果

输入:查询语句字符串sql

输出:查询结果集合

方法一:直接用Recordset对象进行查询取得记录集

_RecordsetPtr CADODatabase::Select(CString sql)

{

_bstr_t CommandText(sql); // 生成要执行的sql语句字符串

m_pRecordset.CreateInstance("ADODB.Recordset"); // 生成_RecordsetPtr实例

m_pRecordset->Open(CommandText, // 连接数据库查询

m_pConnection.GetInterfacePtr(),

adOpenDynamic,

adLockBatchOptimistic,

adCmdText);

return m_pRecordset;

}

其中Open方法原型如下:

HRESULT Recordset15::Open ( const _variant_t & Source, const _variant_t & ActiveConnection, enum CursorTypeEnum CursorType, enum LockTypeEnum LockType, long Options )

上述函数中参数Source是数据查询字符串;参数ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象);参数CursorType光标类型,它可以是以下值之一;请看这个枚举结构:

参数LockType表示数据库的锁定类型,它可以是以下值之一,请看如下枚举结构:

方法二:利用Command对象来执行SQL命令

_RecordsetPtr CADODatabase::Select(CString sql)

{

_CommandPtr m_pCommand;

m_pCommand.CreateInstance("https://www.360docs.net/doc/1c1334324.html,mand");

_variant_t vNULL;

vNULL.vt = VT_ERROR;

vNULL.scode = DISP_E_PARAMNOTFOUND; //定义为无参数

m_pCommand->ActiveConnection = m_pConnection; //非常关键的一句,将建立的连接赋值给它

m_pCommand->CommandText = "SELECT * FROM users"; //命令字串

m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText); return

m_pRecordset;

}

添加Execute函数

功能:执行sql语句(例如Insert、Update操作等)

输入:sql语句字符串

返回值:TRUE,如果成功执行。

BOOL CADODatabase::Execute(CString sql)

{

_bstr_t CommandText(sql);

_variant_t RecordsAffected;

m_pConnection->Execute(CommandText, &RecordsAffected, adCmdText);

return TRUE;

}

四、MFC界面编程

1.在对话框中添加控件

2.在程序启动时初始化列表框,并连接数据库

在CCtrlListDatabaseDlg::OnInitDialog()函数中添加两部分代码:

初始化列表框

m_ListCtrl.SetExtendedStyle(LVS_EX_HEADERDRAGDROP

| LVS_EX_FULLROWSELECT

| LVS_EX_TRACKSELECT); // 设置列表框的样式

CString header[4] = {"姓名", "性别", "出生日期", "已修学分" }; // 增加列表头部

for (int i = 0; i < 4; i++)

{

m_ListCtrl.InsertColumn(i, header[i], LVCFMT_CENTER, 80);

}

连接数据库

为CCtrlListDatabaseDlg类添加成员变量m_database,其类型为CADODatabase.数据库连接代码如下:

CString strConnection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=";

strConnection += "test.mdb";

m_database.OpenDatabase(strConnection);

strConnection是数据库连接字符串。本项目采用Jet引擎连接Access数据库,所以Provider=Microsoft.Jet.OLEDB.4.0; Data Source后面写的是数据库名称。我们在第一步中建立的数据库文件叫test.mdb,所以本项目中连接数据库的字符串是

Provider=Microsoft.Jet.OLEDB.4.0;Data Source= test.mdb

(注意:test.mdb应该放在项目所在文件下,否则需要把test.mdb所在路径也上。例如,如果test.mdb放在d盘根目录下,则该写d:\\test.mdb)

如果项目中采用SQLServer作为数据库,则需要修改数据库连接字符串。例如:

driver={SQL Server};Server=127.0.0.1;DATABASE=vckbase; UID=sa;PWD=139

其中driver={SQL Server}; 表示项目采用SQLServer作为数据库。Server 表示数据库所在机器,如果用本机数据库,则写127.0.0.1。DATABASE指数据库名称。UID是连接数据库时的用户名,PWD指密码。如果用户名/密码为空,则使用””。

3.添加查询功能

为查询按钮添加响应函数

void CCtrlListDatabaseDlg::OnButtonQuery()

{

// TODO: Add your control notification handler code here

m_ListCtrl.DeleteAllItems(); // 删除列表控件中已有记录

UpdateData();

CString sql = "select * from student where name like '%"; // 根据用户输入的查询名称生成sql语句。

sql += m_strQueryName;

sql += "%'";

_RecordsetPtr pRecordset = m_database.Select(sql); // 获得查询结果集合

CString record[4];

CString temp;

COleDateTime time;

int gender, credit;

int row = 0;

while (!pRecordset->adoEOF) // 遍历查询结果集合,将每条结果在列表框中显示 {

// pRecordset->GetCollect("name")取出当前记录的Name字段的值。因为Name字段的值是字符串类型,所以取bstrVal属性获得字段值。

CString temp = pRecordset->GetCollect("name").bstrVal;

// 往列表框新增一条记录

m_ListCtrl.InsertItem(row, temp);

// pRecordset->GetCollect("gender")取出当前记录的gender字段的值。因为gender 字段的值整数类型,所以取lVal属性获得字段值。

gender = pRecordset->GetCollect("gender").lVal;

if (gender == 0)

{

m_ListCtrl.SetItemText(row, 1, "男");

}

else

{

m_ListCtrl.SetItemText(row, 1, "女");

}

// pRecordset->GetCollect("birthday")取出当前记录的birthday字段的值。因为birthday字段的值为时间类型,所以取date属性获得字段值。

time = pRecordset->GetCollect("birthday").date;

temp = time.Format("%Y-%m-%d");

m_ListCtrl.SetItemText(row, 2, temp);

// pRecordset->GetCollect("credit")取出当前记录的credit字段的值。因为credit字段的值为整数类型,所以取lval属性获得字段值。

credit = pRecordset->GetCollect("credit").lVal;

temp.Format("%d", credit);

m_ListCtrl.SetItemText(row, 3, temp);

row++;

pRecordset->MoveNext();

}

}

4.添加新增记录功能

新增编辑框,控件摆放如下图所示。为该编辑框新建一个关联的类CEditInfoDlg

在CCtrlListDatabaseDlg中增加“新增按钮”响应函数

void CCtrlListDatabaseDlg::OnButtonAdd()

{

// TODO: Add your control notification handler code here

CEditInfoDlg dlg;

if (IDOK == dlg.DoModal())

{

// 根据用户在编辑框输入的信息生成sql语句

CString sql = "insert into student (name, gender, birthday, credit) values (";

sql += "'" + dlg.m_name + "'";

CString gender;

gender.Format("%d", dlg.m_gender);

sql += ", " + gender;

CString time = dlg.m_birthday.Format("%Y-%m-%d");

sql += ", '" + time + "'";

CString strCredit;

strCredit.Format("%d", dlg.m_credit);

sql += ", " + strCredit + ")";

m_database.Execute(sql);

}

}

五、使用Datagrid ActiveX控件

本节演示如何使用Datagrid控件显示数据。新建项目基于对话框MFC项目,命名为Datagrid。界面控件设置同上,区别是采用Datagrid控件代替List Control控件。

1.添加Datagrid控件

Datagrid控件的添加:菜单栏->项目(Project) ->添加至项目(Add to Project)->组件和控件(Components and Controls)

选择Registered ActiveX Controls,Microsoft DataGrid Control

点击插入(Insert),确定。此时弹出一个确认框

不作修改,点击确定。然后点击关闭(Close)关闭文件对话框。此时控件列表中会多了一个红色的控件---Datagrid控件。

将Datagrid控件拉到对话框界面。控件ID设为ID_DATAGRID_RESULT,Caption设为“查询结果”,关联变量类型为CDatagrid,变量名为m_datagrid。其余控件设置同上。如图所示。

2.创建数据库

新建数据库test.mdb,创建student表。

3.创建数据库操作类CADODatabase

具体操作同上。

在窗口创建时,建立数据库连接。即在CDatagridDlg::OnInitDialog()函数中添加代码:CString strConnection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=";

strConnection += "test.mdb";

m_database.OpenDatabase(strConnection);

4.使用Datagrid

4.1 绑定数据源

给查询按钮添加相应函数OnBUTTONQuery。

void CDatagridDlg::OnBUTTONQuery()

{

// TODO: Add your control notification handler code here

UpdateData();

// 根据查询条件生成sql语句

CString sql = "select * from student where name like '%";

sql += m_QueryName;

sql += "%'";

// 获得查询结果

_RecordsetPtr pRecordset = m_database.Select(sql);

m_QueryResult.SetRefDataSource(NULL);

// 绑定数据源

m_QueryResult.SetRefDataSource((LPUNKNOWN)pRecordset);

m_QueryResult.SetColumnHeaders(TRUE);

_variant_t vIndex;

CColumn col = NULL;

// 设置显示数据列

vIndex = long(0);

col = m_QueryResult.GetColumns().GetItem(vIndex);

col.SetWidth(50); // 设置列宽度

col.SetCaption("id");

col.SetVisible(FALSE); // 隐藏主键列不显示

vIndex = long(1);

col = m_QueryResult.GetColumns().GetItem(vIndex);

col.SetWidth(50); // 宽度

col.SetCaption("姓名");

vIndex = long(2);

col = m_QueryResult.GetColumns().GetItem(vIndex);

col.SetWidth(50); // 宽度

col.SetCaption("性别");

vIndex = long(3);

col = m_QueryResult.GetColumns().GetItem(vIndex);

col.SetWidth(80); // 宽度

col.SetCaption("出生日期");

vIndex = long(4);

col = m_QueryResult.GetColumns().GetItem(vIndex);

col.SetWidth(50); // 宽度

col.SetCaption("学分");

m_QueryResult.Refresh();

}

4.2 添加记录

添加记录代码如下:

CEditInfoDlg dlg;

if (IDOK == dlg.DoModal())

{

// 获得数据源记录集。

_RecordsetPtr pRecordset = m_database.m_pRecordset;

//注意:调用下述代码前,需确保pRecordset与某张数据库表内的数据绑定

// 新增一条记录

pRecordset->AddNew();

// 设置姓名字段

pRecordset->PutCollect("name", _variant_t(dlg.m_name));

// 设置性别字段

CString gender;

if (dlg.m_gender == 0)

{

gender = "男";

}

else

{

gender = "女";

}

pRecordset->PutCollect("gender", _variant_t(gender));

// 设置出生日期字段

CString time = dlg.m_birthday.Format("%Y-%m-%d");

pRecordset->PutCollect("birthday", _variant_t(time));

// 设置学分字段

CString credit;

credit.Format("%d", dlg.m_credit);

pRecordset->PutCollect("credit", _variant_t(credit));

// 添加记录

pRecordset->Update();

}

相关主题
相关文档
最新文档