`

使用ADO封装类的数据库程序开发实例(下)

    博客分类:
  • VC
阅读更多

使用ADO封装类的数据库程序开发实例(下)

原文地址:http://www.vckbase.com/document/viewdoc/?id=611

 

《使用ADO封装类的数据库程序开发实例(上)》 中详细介绍了ADO的一些基本的概念,接下来让我们在此基础上进行具体的编程。

五、开始编写ADO应用程序.

使用ADO之前,我们另外还需要添加下面的语句,如此把ADO的库引入到工程中.

#import "c:\program files\common files\system\ado\msado15.dll" 
        no_namespace rename("EOF","adoEOF") 
根据机器安装时候的设置不同具体的路径可能不一样。
另外编译的时候会出现如下的警告信息:
msado15.tlh(405) : warning C4146: unary minus operator applied to unsigned type, result still unsigned 
MSDN建议我们不要理会。如果你实在不想看到的话可以在stdafx.h中加入一行下面的代码:
#pragma warning(disable:4146) 
这样这个警告信息就不会再出现了。

 

ADO使用了COM,所以在使用ADO之前,必须对COM进行了初始化,否则无法使用.你可以使用AfxOleInit()来初始化,但只能初始一次,你不能多次调用此函数,建议你在应用程序的APP类的InitInstance方法中进行初始化.
上面这些一般相关的资料都有详细说明,因此我就不细说了,下面我们来看看如何我封装的两个类。

六、ADO封装类:CAdoConnection 和 CAdoRecordSet

首先当然是要连接到数据源了,连接到数据源的函数是_CAdoConnection的Connect方法,它封装了ADO连接对象的CreateInstance和Open方法:
我们来看看我是如何封装的:

BOOL CAdoConnection::Connect(LPCTSTR strConnect, long lOptions)
{
	m_strConnect = strConnect;
	try
	{
		///创建 Connection 对象---------------------------
		HRESULT	hr = m_pConnection.CreateInstance("ADODB.Connection");
		if (SUCCEEDED(hr))
		{
			// 连接数据库---------------------------------------------
			if (SUCCEEDED(m_pConnection->Open(strConnect, "", "", lOptions)))
			{	
				return TRUE;
			}
		}
	}
	catch (_com_error e)
	{
		TRACE(_T(":( 连接数据库发生错误: %s\n"), e.ErrorMessage());
		return FALSE;
	} 
	catch (...)
	{
		TRACE(_T(":( 连接数据库时发生未知错误:"));
	}
	return FALSE;
}
使用之前先定义一个CAdoConnection 类对象如m_adoConnection,例如:
CString strSrcName = "E:\\Access\\datebase.mdb";//假设在e盘有这样一个access的数据库文件
CString strConnect = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + strSrcName;
m_adoConnection.Connect(LPCSTR(strConnect));
这样就连接到数据源了.

接着就是要打开记录集了,下面我对它的open方法的封装:使用进你可以忽略后面的三个参数,直接把一个SQL语句传给它.

HRESULT CAdoRecordSet::Open(LPCTSTR strSQL, 
			long lOption, 
			CursorTypeEnum CursorType, 
			LockTypeEnum LockType)
{
	try
	{
		if (m_pConnection == NULL)
		{
			return -1;
		}
		else if (m_pRecordset == NULL)
		{
			m_pRecordset.CreateInstance("ADODB.Recordset");
		}
		
		m_pRecordset->Open(_bstr_t(strSQL),
			_variant_t((IDispatch*)m_pConnection->GetConnection(), true),
			CursorType, LockType, lOption);
		if (m_pRecordset == NULL) 
		{
			return -1;
		}
		return (m_pRecordset->adoEOF) ? 0 : 1;
	}
	catch (_com_error e)
	{
		TRACE(_T(":( 打开记录集发生错误: %s\n"), e.ErrorMessage());
		return -1;
	}
}
例如我们可以这样来用:
CAdoRecordSet rset;
rset.SetAdoConnection(&(GetDocument()->m_adoConnection));//记得要先指定相应的连接对象,否则会出错.
m_strSQL = "select * from city";//要执行的SQL语句.
rset.Open(m_strSQL);
七.写一个数据查询工具(我对实现过程只稍作了介绍,具体内容请参考源代码):

7.1 连接数据库

首先要编写连接到数据库的代码,为此,我写了一个对话框类(CLogoDig)用来选择不同的数据源,
然后在视图类(这个视图类是从CFromView类派生的)添加 CAdoConnection 类成员变量,并添加如下连接函数
void CAccessView::OnFileConnect() 
{
	CLogoDig dlg;
	if (dlg.DoModal() == IDOK)
	{
		if (dlg.m_nSrcType == 0)
		{
			CString strConnect = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + dlg.m_strSrcName;
			GetDocument()->m_adoConnection.Disconnect();
			if (!GetDocument()->m_adoConnection.Connect(LPCSTR(strConnect)))
			{
				AfxMessageBox("连接数据库失败!");
				return;
			}
		}
		else if (dlg.m_nSrcType == 1)
		{
			CString strConnect = "Provider=SQLOLEDB.1;Data Source=" + dlg.m_strSrcName + 
					";Initial Catalog=" + dlg.m_strDbName  +
					";User ID=" + dlg.m_strUserName + "; PWD=" + dlg.m_strPassWord;
			GetDocument()->m_adoConnection.Disconnect();
			if (!GetDocument()->m_adoConnection.Connect(LPCSTR(strConnect)))
			{
				AfxMessageBox("连接数据库失败!");
				return;
			}
		}
		((CMainFrame*)GetParentFrame())->m_wndLeftBar.InitTree();
	}
}

7.2 CCoolControlBar类和CMSFlexGrid类

在这个数据查询工具中我们使用了另外两个类:CCoolControlBar类和CMSFlexGrid类。.前者是我写的一个可以动态改变大小的控制条类,后者是系统自带一个网格控件,这个控件功能较少,但对于只用来显示一下查询结果已经够用了。
在编辑CFromView类对话框资源视图中,在正在编辑的对话框资源上点右键,选择插入ActiveX控件,然后选择"Microsoft FlexGrid control"控件。然后在类向导中在"Member Variables"页中为它添加变量,类向导会提示要引入向个头文件,确认,这时你的类视图中就会增加好几个类。
先介绍一个要用到的几个函数:
SetCols 设置总共拥有的列数
SetFixedCols 设置固定的列数,即背景为灰色的那种
SetRows 设置总共拥有的行数
SetCol 设置当前列
SetRow 设置当前行
SetText 设置当前格的文本。位置由上面两个函数决定。
SetColWidth 设置列宽

7.3 数据的显示与处理


另外我们还需要两个编辑控件,用来输入SQL语句和显示错误信息.并在OnSize消息处理函数中动态设置它们的位置:
void CAccessView::OnSize(UINT nType, int cx, int cy) 
{
	CFormView::OnSize(nType, cx, cy);
	
	if (m_wndGrid.GetSafeHwnd() != NULL) //控件是否已经创建
	{
		m_editError.MoveWindow(0, 10, cx, cy - 50);
		m_wndGrid.MoveWindow(0, 0, cx, cy - 40);
		m_editSQL.MoveWindow(0, cy - 40, cx, 40);
	}
}
添加一条菜单项并添加相应响应函数,用于开始执行输入的SQL语句:
void CAccessView::OnRun() 
{
	UpdateData();
	UpdateGrid();
}
根据查询情况显示查询结果:
void CAccessView::UpdateGrid()
{
	//连接对象是否打开------------------------------------------
	if (!GetDocument()->m_adoConnection.IsOpen()) 
	{
		AfxMessageBox("数据库没有打开或已经关闭!");
		return;
	}
	//先隐藏这两个控件------------------------------------------
	m_wndGrid.ShowWindow(SW_HIDE);
	m_editError.ShowWindow(SW_HIDE);

	CAdoRecordSet rset;
	rset.SetAdoConnection(&(GetDocument()->m_adoConnection));
	if (rset.Open(m_strSQL, adCmdText) != 1)
	{
		//查询出错,取得出错信息并显示在编辑控件里面------------------
		m_strError = GetDocument()->m_adoConnection.GetLastError();
		UpdateData(FALSE);
		m_editError.ShowWindow(SW_SHOW);
		return;
	}
	//下面我用到的有些函数在类中可能没有封装,所以还是使用了try块,以防万一,:(
	try
	{
		//取得记录集的字段数和行数----------------------------------
		int nrow = rset.GetRecordCount();
		int ncol = rset.GetFields()->Count;
		//设置网格控件的列数和行数----------------------------------
		m_wndGrid.SetCols(ncol);
		m_wndGrid.SetRows(nrow + 1); // 多留一行以显示字段名
		m_wndGrid.SetFixedCols(0);
		
		CString value;
		//填充字段名-----------------------------------------------
		m_wndGrid.SetRow(0);
		for (int i = 0; i < ncol; i++)
		{
			m_wndGrid.SetCol(i);
			m_wndGrid.SetText(LPCSTR(rset.GetFieldName(i)));
			//设置当前列的大致宽度-------------------------------
			int nwidth = rset.GetFieldDefineSize(i) * 200;
			nwidth = nwidth > 2000 ? 2000 : nwidth;
			m_wndGrid.SetColWidth(i, nwidth);
		}
		
		//读取记录集-----------------------------------------------
		int n = 1;
		while (!rset.IsEOF()) 
		{
			m_wndGrid.SetRow(n);
			n++;
			for (int i = 0; i < ncol; i++)
			{
				m_wndGrid.SetCol(i);
				rset.GetValueString(value, (long)(i));
				m_wndGrid.SetText(LPCTSTR(value));
			}
			rset.MoveNext();
		}
		m_wndGrid.ShowWindow(SW_SHOW);
	}
	catch (_com_error) 
	{
		return;
	}
}
记录集用完后,可以及时用Close()将它关闭,以释放相应的资源. CAdoRecordSet类折构函数,会自动关闭记录.

7.4 其它功能(获取数据库信息)


我们还可以加一点另外的功能:在右边的树控件中显示数据库所拥有的表单和它们各自所拥有所有字段.这段主要是用来演示如何获得数据库的一些信息.
主要实现函数如下:
void CLeftBar::InitTree()
{
	CAdoRecordSet rset;
	_bstr_t Value;
	CString strTablename = "";
	HTREEITEM item = TVI_ROOT;
	try
	{
		if (GetDocument()->m_adoConnection.GetConnection()->State != adStateOpen) return;
		m_ctrlTree.DeleteAllItems();
		//取得数据库字段信息---------------------------------------------
		rset = GetDocument()->m_adoConnection.OpenSchema (adSchemaColumns);
		while (!rset.IsEOF())
		{
			CString strValue;
			//取得表名-----------------------------------------------
			rset.GetValueString(strValue, "TABLE_NAME");
			if (strValue != strTablename)
			{
				strTablename = strValue;
				item = m_ctrlTree.InsertItem((LPCTSTR)strTablename, 1, 1);
			}
			//取得字段名--------------------------------------------
			Value = rset.GetFields()->Item[L"COLUMN_NAME"]->Value;
			m_ctrlTree.InsertItem((LPCTSTR)Value, 2, 2, item);
			
			rset.MoveNext();
		}
	}
	catch(_com_error e)
	{
		
	}
}
当然,你一样可以查询看数据库还拥有哪些视图,索引等信息. 这里还用到了CCoolControlBar类,但如何使用这里就不细说了,毕竟现在主要谈的是ADO,如果你对它有什么兴趣可以真接找我.:) 

一个小查询器就差不多完成了。

八、其他参考信息(有很多我在源代码里面已有详细注释,就不一一重复了)
_Connection、_Recordset、_Field参考
分享到:
评论

相关推荐

    使用ADO封装类的数据库程序开发实例[第二版] 源码

    本文将深入探讨如何使用ADO(ActiveX Data Objects)封装类进行数据库程序的开发,以【标题】"使用ADO封装类的数据库程序开发实例[第二版] 源码"为例,结合【描述】中的关键点,如SQL Server、Access、图片存取和XML...

    使用ADO封装类的数据库程序开发实例

    在数据库程序开发中,ADO(ActiveX ...总之,通过使用ADO封装类进行数据库程序开发,可以降低开发难度,提高代码质量,并使项目更加易于维护。了解和熟练运用这些封装技巧,对于任何IT开发者来说都是一项重要的技能。

    使用ADO封装类的数据库程序开发实例[第二版

    "使用ADO封装类的数据库程序开发实例[第二版]"是一个教程或书籍,旨在教导开发者如何高效地利用ADO进行数据库操作,并通过封装类来提高代码的可复用性和可维护性。 首先,我们需要了解ADO的核心概念。ADO包括一系列...

    《使用ADO封装类的数据库程序开发实例》配套代码.zip

    本压缩包文件"《使用ADO封装类的数据库程序开发实例》配套代码.zip"包含了使用ADO进行数据库编程的实践案例,可以帮助开发者深入理解和应用ADO技术。 首先,让我们详细了解什么是ADO。ADO是.NET Framework的一部分...

    使用ADO封装类的数据库程序开发实例.zip

    在.NET编程环境中,ADO(ActiveX Data Objects)是微软提供的一种数据访问技术,它允许开发者与各种数据库进行交互。在实际开发中,为了提高代码的可重用性和可...这就是使用ADO封装类的数据库程序开发实例的基本思路。

    使用ADO封装类的数据库程序开发实例(DOC)

    总之,ADO封装类的使用可以帮助开发者更加专注于业务逻辑,而不是底层的数据访问细节,从而提升开发效率和代码质量。通过深入理解和熟练运用这些封装类,可以更高效地开发数据库驱动的软件应用。

    使用ADO封装类的数据库程序开发实例.doc

    在本篇文档中,作者分享了一个使用ADO封装类进行数据库程序开发的实例,旨在提供一个更完善的ADO类库,以简化数据库操作。这个类库主要封装了ADO组件的大部分方法,并扩展了一些实用功能。 首先,作者提到的...

    Ado_使用ADO封装类的数据库程序开发实例[参考].pdf

    本文将深入探讨如何使用ADO封装类进行数据库程序的开发,以提高开发效率和代码的可维护性。 首先,ADO是一个由微软提供的面向对象的API,它允许开发者以语言无关的方式访问各种数据源,包括但不限于关系型数据库。...

    ADO.zip_ado 封装类_ado封装类_数据库封装类

    总的来说,这个压缩包中的ADO封装类是软件开发中的重要工具,它简化了数据库访问的复杂性,使开发者能够更专注于业务逻辑,而不是数据库操作的细节。使用这样的封装类,可以保持代码的整洁,同时也便于团队协作和...

    ADO封装类文件 数据库访问

    在这个场景中,"ADO封装类文件 数据库访问"指的是在VC6.0环境下,已经编写完成的用于简化ADO操作的C++类库,包括两个文件:ADOConn.h和ADOConn.cpp。 **ADOConn.h** 文件通常会定义一个名为ADOConn的类,这个类是对...

    ado_class.rar_ ADO_class_ACCESS 封装类_ADO数据库_ado封装类_数据库封装类

    通过使用这样的封装类,开发人员能够更专注于业务逻辑,而不是数据库操作的细节,从而提高开发效率和代码质量。在实际项目中,根据需求,可能还需要对这个类进行进一步的定制和扩展,以满足特定的应用场景。

    小而强悍的C++ ADO封装类

    在实际项目中,使用这样的C++ ADO封装类可以显著提高开发效率,降低代码复杂性。MYADO这个文件可能是封装类的实现,包括头文件(.h)和源文件(.cpp),通过阅读和理解这些文件,我们可以了解具体如何使用和定制这个...

    MFC ADO访问数据库封装类

    在本案例中,“MFC ADO访问数据库封装类”指的是利用MFC对ADO接口进行封装,以简化数据库操作,提高开发效率。 首先,了解MFC ADO的基本概念是至关重要的。MFC通过提供CDatabase、CRecordset和CRecordView等类,...

    VC封装ADO访问数据库的代码实例

    在VC++开发环境中,MFC(Microsoft Foundation Classes)是一个强大的库,它为Windows应用程序提供了一套C++类,简化了Windows API的使用。ADO(ActiveX Data Objects)是微软提供的一个用于访问数据库的接口,它...

    VC++使用ADO开发ACCESS数据库

    **VC++使用ADO开发ACCESS数据库** 在Windows编程中,Visual C++(VC++)是一种强大的开发工具,尤其在处理数据库应用时。本教程将重点介绍如何利用ActiveX Data Objects(ADO)来连接和操作Microsoft Access数据库...

    ADO类连接数据库集成类

    总的来说,在"ADO类连接数据库集成类"中,开发者通过封装ADO类,实现了VC++应用程序与SQL Server 2008数据库的无缝连接,简化了数据库操作,提高了开发效率。在实际项目中,这样的集成类可以作为基础组件复用,降低...

    vs2008平台下ADO操作ACEESS数据库编程实例

    通过分析和学习这些代码,你可以更好地理解如何在VS2008环境下使用ADO与Access数据库交互。 通过以上步骤,你可以在VS2008中使用ADO高效地操作ACCESS数据库。记得在实际应用中,要确保数据安全性和事务一致性,遵循...

    vc++下可以使用的ADO封装类

    通过阅读和理解`AdoRecordSet.cpp`、`Ado.cpp`和`AdoCommand.cpp`中的源代码,开发者可以更好地掌握这些类的内部实现和使用方式,进一步优化自己的数据库应用程序。同时,`AdoRecordSet.h`、`Ado.h`和`AdoCommand.h`...

Global site tag (gtag.js) - Google Analytics