MFC 使用 ADO技术连接Access数据库

这篇具有很好参考价值的文章主要介绍了MFC 使用 ADO技术连接Access数据库。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

学了很久的MFC,于是想着使用MFC的ADO技术连接Access数据库。
记录一下,以备后面复习。
1.首先需要了解MDB数据库文件,本次示例代码连接的是MDB数据库文件。*.MDB文件是(Microsoft Database) 文件的缩写,是Access数据库文件的一种格式。就像是Word文档的.doc文件一样。
2.下面开始讲一下连接的具体步骤:
(1)新建一个对话框工程,添加相对应的控件,如下图所示:
MFC 使用 ADO技术连接Access数据库
首先最关键的步骤如下:
在stdafx.h头文件中添加如下代码,注意工程运行的x86平台下才不会出错。如果运行在x64平台下,可能会报错。笔者使用VS2022时运行在x64平台下,报错无法打开文件。可以参考该说明:https://blog.csdn.net/hbspring007/article/details/107467823

#import "C:\\Program Files (x86)\\Common Files\\System\\ado\\msado15.dll" no_namespace rename("EOF","adoEOF"),rename("BOF","adoBOF")
#import "C:\\Program Files (x86)\\Common Files\\System\\ado\\msjro.dll" no_namespace rename("ReplicaTypeEnum","_ReplicaTypeEnum")  

msado15.dll:主要用于对数据库进行操作。
msjro.dll:主要用于对数据库进行压缩。

第二步:
1.首先需要将msado15.tlh文件和msado15.tli文件添加到工程中。如果找不到,可从笔者工程中查找。
2.在工程的*App.h头文件中添加:连接数据库的代码如下:

_ConnectionPtr m_pConnnect;

_ConnectionPtr :为指向Connect 类对象的指针,用于连接数据库。
在工程的*App.cpp的文件的InitInstance()函数中的创建对话框之前添加如下代码:

// 初始化COM库
if (!AfxOleInit())
{
	AfxMessageBox(_T("初始化OLE DLL失败"));
}
HRESULT hr;
try
{
	// 创建Connection对象 
     hr = m_pConnnect.CreateInstance(_T("ADODB.Connection"));
     if (SUCCEEDED(hr))
     {   // 下面的连接字符串中Provider是针对Access2000环境的,对于Access97环境,需要改为Microsoft.Jet.OLDDB.3.51.
     hr = m_pConnnect->Open(_T("Provider =   Microsoft.Jet.OLEDB.4.0;Data Source= AdoData.mdb"), "", "", adModeUnknown);  // 连接数据库
     }
}
catch (_com_error e) // 捕捉异常
{
     CString errormessage;
	 errormessage.Format(_T("连接数据库失败!\r\n错误信息:%s"), e.ErrorMessage());
	 AfxMessageBox(errormessage);///显示错误信息
}

注意:上面的m_pConnect及使用了 “.” 操作符,又指针的行为间接引用"->“,是因为_ConnectionPtr类重载了”->"操作符。
首先,我们需要先初始化COM库。
其中的Data Source = AdoData.mdb数据库是预先做好的数据库。使用_ConnectionPtr::Open()函数打开数据库。
第三步:在***Dlg.h 文件中添如下代码:
为对话框关联成员变量如下:

    _RecordsetPtr m_pRecordset;
    UINT m_nID;
	UINT m_nAge;
	CString m_strUserName;
	// DataTime 控件成员变量
	COleDateTime m_tBirthday;
	// CListCtrl 控件
	CListCtrl m_UserList;
	// 用于判断是否成功读取数据库数据
	BOOL m_bSuccess;
	// 获取CListCtrl 控件中当前选择的行
	int m_nCurSelect;
	// 判断在添加数据或者选择数据后是否保存数据
	BOOL m_bAutoSave;

	// 定义四个 _variant_t 类对象
	_variant_t m_vID, m_vUserName, m_vAge, m_vBirthday;

_RecordsetPtr: 用于访问数据库中的数据。具体的用法可以参考MSDN,网址如下:MSDN 关于ADO 的介绍
其中使用了_variant_t类,关于这个类的介绍,大家也可以参考前面的MSDN.
_variant_t类:封装和管理了Variant类型的数据。
另外再添加两个函数用于保存修改和删除原来的数据。
在工程对话框的***::OnInitialDialog()函数中添加如下代码:

// 为列表控件添加列
	m_UserList.SetExtendedStyle(m_UserList.GetExtendedStyle()|LVS_EX_FULLROWSELECT| LVS_EX_GRIDLINES);
	m_UserList.InsertColumn(0,_T("ID"),LVCFMT_LEFT,60);
	m_UserList.InsertColumn(1, _T("用户名"), LVCFMT_LEFT,100);
	m_UserList.InsertColumn(2, _T("年龄"), LVCFMT_LEFT,60);
	m_UserList.InsertColumn(3, _T("生日"), LVCFMT_LEFT,120);
    try
	{
		// 创建一个新的连接数据库实例
	m_pRecordset.CreateInstance(_T("ADODB.Recordset"));
		// 使用SQL语句,用来查询users这个表的内容
		m_pRecordset->Open("SELECT * FROM users",_variant_t((IDispatch*)theApp.m_pConnnect,TRUE),adOpenStatic,adLockOptimistic,adCmdText);
		m_bSuccess = TRUE;
		// EOF(End of File:指示当前位置位于Recordset对象的最后一个记录之后)
		// 使用BOF(Before of File):bof表示rs当前的指针是指在了数据集的前面;使用BOF和EOF可用于判断Recordset对象是否包含记录
		// 或者从一个记录移到另一个记录时是否超出Recordset对象的限制。
		while(!m_pRecordset->adoEOF)  
		{
			// GetCollect()函数的作用:用来获取收集的字符串,例如就是用来获取_T("")字符串的
			vID = m_pRecordset->GetCollect(_T("id"));
			vUserName = m_pRecordset->GetCollect(_T("username"));
			vAge = m_pRecordset->GetCollect(_T("age"));
			vBirthdayr = m_pRecordset->GetCollect(_T("birthday"));
			// 在控件中插入新行
			nItem = m_UserList.InsertItem(0xffff,(_bstr_t)vID);
			// 在已经存在的行中设置信息
			m_UserList.SetItem(nItem, 1, 1, (_bstr_t)vUserName,NULL,0,0,0);
			m_UserList.SetItem(nItem, 2, 1, (_bstr_t)vAge, NULL, 0, 0, 0);
			m_UserList.SetItem(nItem, 3, 1, (_bstr_t)vBirthdayr, NULL, 0, 0, 0);
			m_pRecordset->MoveNext(); 
		}
	}
	catch (_com_error e)
	{
		AfxMessageBox(_T("读取数据库失败!"));
	}

上面对话框中,添加行按钮的实现代码如下:

    UpdateData();
	if (m_strUserName.GetLength() > 0)
	{
		// 创建可更新Recordset对象的新纪录
		m_pRecordset->AddNew();
		// 在65535行中插入_T("")
		m_nCurSelect = m_UserList.InsertItem(0xffff,_T(""));
		SaveData();
		m_UserList.SetItemState(m_nCurSelect,LVIS_SELECTED| LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
		m_UserList.SetHotItem(m_nCurSelect);
		m_UserList.SetFocus();
	}
	else
	{
		AfxMessageBox(_T("请输入用户名"));
	}

调用的SaveData()函数的代码如下:

if (!m_pRecordset->adoEOF && m_nCurSelect >= 0 && m_bAutoSave)
	{
		m_vID = (long)m_nID;
		m_vUserName = m_strUserName;
		m_vAge = (long)m_nAge;
		m_vBirthday = m_tBirthday;
		// PutCollect(A,B)函数的作用是将B中的数据添加到数据库A中
		m_pRecordset->PutCollect(_T("id"),m_vID);
		m_pRecordset->PutCollect(_T("username"), m_vUserName);
		m_pRecordset->PutCollect(_T("age"), m_vAge);
		m_pRecordset->PutCollect(_T("birthday"), m_vBirthday);
		// 将当前修改的值插入到当前选择行中
		m_UserList.SetItem(m_nCurSelect,0,LVIF_TEXT,(_bstr_t)m_vID,NULL,0,0,0);
		m_UserList.SetItem(m_nCurSelect, 1, LVIF_TEXT, (_bstr_t)m_vUserName, NULL, 0, 0, 0);
		m_UserList.SetItem(m_nCurSelect, 2, LVIF_TEXT, (_bstr_t)m_vAge, NULL, 0, 0, 0);
		m_UserList.SetItem(m_nCurSelect, 3, LVIF_TEXT, (_bstr_t)m_vBirthday, NULL, 0, 0, 0);
	}

与之相对的LoadData()函数的代码如下:

m_pRecordset->Move(m_nCurSelect, _variant_t((long)adBookmarkFirst));

	m_vID = m_pRecordset->GetCollect(_T("id"));
	m_vUserName = m_pRecordset->GetCollect(_T("username"));
	m_vAge = m_pRecordset->GetCollect(_T("age"));
	m_vBirthday = m_pRecordset->GetCollect(_T("birthday"));

	m_nID = m_vID.lVal;
	m_strUserName = (LPCTSTR)(_bstr_t)m_vUserName;
	m_nAge = m_vAge.lVal;
	m_tBirthday = m_vBirthday;
	UpdateData(FALSE);

前面对话框中删除按钮的实现代码如下:

    m_bAutoSave = FALSE;
	if (m_nCurSelect >= 0)
	{
		// 删除当前选中行
		m_UserList.DeleteItem(m_nCurSelect);
		int nCount = m_UserList.GetItemCount();
		if (nCount <= m_nCurSelect)
			m_nCurSelect = nCount - 1; // 删除之后重新设置选中行
		// 设置当前指针指向的记录会被删除
		m_pRecordset->Delete(adAffectCurrent);
		// 将当前记录集指针移到下一个记录
		m_pRecordset->MoveNext();
		if (nCount > 0)
			LoadData();
		// 设置当前选中行,为选中状态
		m_UserList.SetItemState(m_nCurSelect, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
		m_UserList.SetFocus();
	}
	m_bAutoSave = TRUE;

点击ListCtrl列表控件通知消息的代码如下:

void CMFCTESTADODlg::OnLvnItemchangedUserList(NMHDR* pNMHDR, LRESULT* pResult)
{
	// NMHDR:包含有关此通知消息的信息结构体
	// LPNMLISTVIEW:专属于ListView类型的通知消息结构体,包含了NMHDR,换一个控件会有不同的形式
	LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
	// TODO: 在此添加控件通知处理程序代码
	// 判断是否选择当前控件的行
	if (pNMLV->uNewState & LVIS_SELECTED)
	{
		UpdateData();
		SaveData();
		// 设置当前行为选中行
		m_nCurSelect = pNMLV->iItem;
		LoadData();
	}
	*pResult = 0;
}

最后确定按钮的实现代码如下:

if (m_bSuccess)
{
	// Update:保存对于对于当前记录集对象,即m_pRecordset数据的修改
	m_pRecordset->Update();
	// 关闭一个对象
	m_pRecordset->Close();
}

该Demo中用到的主要技术有:
_ConnectPtr类和_RecordsetPtr类。
Connect::CreateInstance;
Connect::Open;
Recordset::CreateInstance;
Recordset::Open;
Recordset的adoEOF和adoBOF成员变量;
Recordset::GetCollect();
Recordset::MoveNext();
Recordset::AddNew();
Recordset::Delete();
Recordset::Update();
Recordset::Close();
Recordset::Move();
这些函数的具体用法可以参考微软的官方文档:
Recordset Methods
本Demo的源码下载如下:Gitee文章来源地址https://www.toymoban.com/news/detail-448227.html

到了这里,关于MFC 使用 ADO技术连接Access数据库的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • VBA 连接ACCESS数据库

    在外部进行变量声明 如果报错:用户定义类型未定义,可能是未引用所虚的外部库,在工具-引用中添加 连接数据库 ,本例通过按钮的click事件连接,并将数据库内容填到单元格中 rs.Open SQL, con, adOpenKeyset, adLockOptimistic 中第三和第四个参数是限制记录是否可读写和锁定的,具

    2024年02月12日
    浏览(47)
  • Access数据库连接查询(C++篇)

    Microsoft Office Access是微软发布的一款关系型数据库; 起初是以\\\".mdb\\\"为后缀的文件,支撑其操作的数据库引擎是Microsoft.Jet.OLEDB;随着时间的发展,后面以\\\".access\\\"为后缀的文件,数据库引擎也升级成了Microsoft.ACE.OLEDB; 可创建任意项目,此处直接上截图 步骤一:导入动态链接库

    2024年02月07日
    浏览(61)
  • 实例讲解C++连接各种数据库,包含SQL Server、MySQL、Oracle、ACCESS、SQLite 和 PostgreSQL、MongoDB 数据库

      C++ 是一种通用的编程语言,可以使用不同的库和驱动程序来连接各种数据库。以下是一些示例代码,演示如何使用 C++ 连接 SQL Server、MySQL、Oracle、ACCESS、SQLite 和 PostgreSQL、MongoDB 数据库。 连接 SQL Server 数据库 要使用 C++ 连接 SQL Server 数据库,可以使用 Microsoft 的 ADODB 库。以

    2024年02月05日
    浏览(60)
  • 五、C#与数据库交互( ADO.NET基础)

    在C#中与数据库进行交互,通常使用ADO.NET(ActiveX Data Objects .NET)框架。ADO.NET是.NET Framework中用于数据访问的一组类库,它提供了多种用于连接和操作数据库的方法。 以下是使用ADO.NET与数据库交互的一些基本步骤: 1. 引入命名空间 在C#程序中,你需要引入 System.Data.SqlClient 命

    2024年02月02日
    浏览(57)
  • GBASE南大通用数据库通过 GBase ADO.NET 接口读取数据

    通过 GBase ADO.NET 接口读取 GBase Server 数据需要下面的步骤:  1) 使用 GBaseConnection 创建数据库连接对象   2) 使用 GBaseCommand 创建命令对象   3) 使用连接对象打开连接  4) 设置命令对象的 CommandText 属性,指明查询语句,并关联连接对象  5) 执行命令对象的 ExecuteReader 方法后返

    2024年01月24日
    浏览(49)
  • 【IDEA】数据库连接失败Access denied for user ‘xxx‘@‘localhost‘ (using password: YES)

    今天在配置数据库连接时报了个错,在网上搜了好久,直到后来知道原因后被自己蠢笑了。。。 Access denied for user \\\'xxx\\\'@\\\'localhost\\\' (using password: YES)  意思就是: 无权限使用root账号本地登录MySQL  在数据库中测试的连接是正确的,密码也测试过无误 错误原因: 手误将datasource下的

    2024年02月04日
    浏览(41)
  • .net----数据库的访问ADO.NET、DataAdapter和DataSet

    ADO.NET的概述 使用ADO.NET连接和操作数据库 使用DataAdapter和DataSet访问数据库 .NET Framework提供的数据访问服务的类库 提供对关系数据、XML和应用程序数据各种数据源的一致访问 应用程序使用ADO.NET连接到数据源,检索、处理和更新数据 SQL Server数据源:System.Data.SqlClient命名空间

    2024年02月07日
    浏览(37)
  • 【fly-iot飞凡物联】(15):IOT项目使用TDengine数据库,进行技术调研,本地使用docker启动成功,可以使用python进行连接数据插入。

    本文的原文连接是: https://blog.csdn.net/freewebsys/article/details/108971807 fly-iot飞凡物联专栏: https://blog.csdn.net/freewebsys/category_12219758.html 产品简介 TDengine 是一款专为物联网、工业互联网等场景设计并优化的大数据平台,它能安全高效地将大量设备、数据采集器每天产生的高达 TB 甚至

    2024年02月03日
    浏览(60)
  • VC++中通过ADO中的_RecordsetPtr操作数据库:增删改查

    VC++ 中通过ADO中的_RecordsetPtr操作数据库:增删改查 _RecordsetPtr 智能指针,它是专门为通过记录集操作数据库而设立的指针,通过该接口可以对数据库的表内的记录、字段等进行各种操作。 要搞清楚:数据库和ADO的记录集是两个不同的概念,是存在于不同物理位置的两个存储空间

    2024年01月17日
    浏览(46)
  • mysql连接数据库报错:1045 - Access denied for user ‘root‘@‘localhost‘ (using password:YES)

    连接数据库或者在Navicat连接数据库,报错信息为:1045 - Access denied for user \\\'root\\\'@\\\'localhost\\\' (using password:YES) 连接数据库报错问题 一、报错问题提示信息 1.终端连接报错 Navicat连接报错 二、解决方法: 以管理员身份运行cmd; 2.cd到mysql下的bin目录; 3.停止mysql服务 4.mysql权限屏蔽

    2024年02月12日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包