数据库访问是软件开发过程中经常用到的,ADO方法访问数据库是现在Windows平台开发软件经常用到的方法,但是在ADO组件中,使用COM调用的时候,经常会出现各种异常,异常处理在开发过程中如果处理不当,经常会导致程序无法正常工作甚至崩溃。本人在开发软件过程中,对ADO方法进行了封装,把COM异常吸收在类的内部,这样引用的时候就不必考虑异常处理,使开发过程简单化。本次封装,没有支持全部的方法,只是把最基本的数据库访问方法进行了封装,能够满足一般的开发应用。使用封装类的一个好处是,如果系统需要扩展数据库,比如支持其他的数据库访问方法,只需要修改实现就可以了,不需要调整接口,也增强了软件的可扩展性。
1. DBConnectionImpl.h
#pragma once
typedef _ConnectionPtr CADOConnectionPtr;
class CDBConnectionImpl
{
//构造函数和析构函数
public:
CDBConnectionImpl(void);
virtual ~CDBConnectionImpl(void);
//copy 采用复制的方式,复制后两个连接是相同,复制后的任何一个副本关闭连接后,
//所有副本的连接都会关闭,需要注意
//copy constructor
CDBConnectionImpl(const CDBConnectionImpl& rConnectionImpl) ;
//operator =
CDBConnectionImpl& operator= (const CDBConnectionImpl& rConnectionImpl) ;
//接口函数
public:
//返回数据库连接
CADOConnectionPtr& GetConnection(void);
/*
* 判断当前连接是否已经创建对象
*/
BOOL isValid(void) ;
void SetErrorMessage(LPCTSTR szErrMsg,const char* szSourceFile=NULL,int nLine=0) ;
const CString& GetErrorMessage(void) ;
//是否自动关闭连接
BOOL GetAutoClose(void) ;
protected:
//数据库连接
CADOConnectionPtr m_pConnectionPtr;
//error message
CString m_strErrMsg ;
//是否自动关闭连接
BOOL m_bAutoClose ;
};
inline CADOConnectionPtr& CDBConnectionImpl::GetConnection(void)
{
return m_pConnectionPtr ;
};
inline BOOL CDBConnectionImpl::isValid(void)
{
return (m_pConnectionPtr != NULL) ;
};
inline const CString& CDBConnectionImpl::GetErrorMessage(void)
{
return m_strErrMsg;
}
inline BOOL CDBConnectionImpl::GetAutoClose(void)
{
return m_bAutoClose ;
}
2. DBConnectionImpl.cpp
#include "StdAfx.h"
#include ".\dbconnectionimpl.h"
#include "DBErrorMsgDefs.h"
#include "ErrorHandler\Win32ErrorMsg.h"
CDBConnectionImpl::CDBConnectionImpl(void):
m_bAutoClose(TRUE)
{
HRESULT hr = S_OK ;
try
{
hr = m_pConnectionPtr.CreateInstance(__uuidof(Connection));
if (FAILED(hr))
{
CString strErrMsg = CWin32ErrorMsg::GetHResultErrorDescription(hr) ;
SetErrorMessage((LPCTSTR)strErrMsg,__FILE__,__LINE__) ;
}
}
catch (_com_error &e)
{
SetErrorMessage((LPCTSTR)e.Description(),__FILE__,__LINE__) ;
}
catch (...)
{
SetErrorMessage(EXCEPTION_UNKNOWN,__FILE__,__LINE__) ;
}
}
//copy constructor
CDBConnectionImpl::CDBConnectionImpl(const CDBConnectionImpl& rConnectionImpl):
m_pConnectionPtr(NULL),
m_bAutoClose(FALSE)
{
*this = rConnectionImpl ;
}
//operator =
CDBConnectionImpl& CDBConnectionImpl::operator= (const CDBConnectionImpl& rConnectionImpl)
{
if(this == &rConnectionImpl)
{
return *this ;
}
//错误信息不复制
try
{
m_strErrMsg = _T("");
//关闭连接,并释放对象
if (m_pConnectionPtr != NULL)
{
if((m_pConnectionPtr->GetState() != adStateClosed) && (m_bAutoClose) )
{
m_pConnectionPtr->Close() ;
m_pConnectionPtr = NULL ;
}
}
//clone it from destination
if(rConnectionImpl.m_pConnectionPtr != NULL)
{
m_pConnectionPtr = rConnectionImpl.m_pConnectionPtr ;
}
m_bAutoClose = FALSE ;
}
catch (_com_error &e)
{
SetErrorMessage((LPCTSTR)e.Description(),__FILE__,__LINE__) ;
}
catch (...)
{
SetErrorMessage(EXCEPTION_UNKNOWN,__FILE__,__LINE__) ;
}
return *this ;
}
CDBConnectionImpl::~CDBConnectionImpl(void)
{
try
{
//关闭连接,并释放对象
if (m_pConnectionPtr != NULL)
{
if( (m_pConnectionPtr->GetState() != adStateClosed) && (m_bAutoClose) )
{
m_pConnectionPtr->Close() ;
}
m_pConnectionPtr = NULL ;
}
}
catch (_com_error &e)
{
SetErrorMessage((LPCTSTR)e.Description(),__FILE__,__LINE__) ;
}
catch (...)
{
SetErrorMessage(EXCEPTION_UNKNOWN,__FILE__,__LINE__) ;
}
}
void CDBConnectionImpl::SetErrorMessage(LPCTSTR szErrMsg,const char* szSourceFile,int nLine)
{
m_strErrMsg = szErrMsg ;
}
//end of this file DBConnectionImpl.cpp