1. 程式人生 > >簡單的 C++ 操作資料庫類

簡單的 C++ 操作資料庫類

         網上看到的一個 C++ 操作資料庫的類,記錄下來。

AdoConnection.h

#ifndef __AdoConnection_h__
#define __AdoConnection_h__

class CAdoRecordset;

class CAdoConnection
{
public:
	static CAdoConnection* GetAdoConnection();
	static void DestroyAdoConnection();

	~CAdoConnection();
	BOOL InitInstance();

	BOOL Open() const;
	void Close() const;

	BOOL IsOpened() const;
	BOOL GetConnectionIDispatch( _variant_t& vActiveConn );
	BOOL OpenRecordset( TCHAR* sqlCmd, CAdoRecordset& recordset );

	BOOL ExecuteNonQuery( const TCHAR *sqlcmd ) const;
	BOOL Execute( const TCHAR *sqlcmd, CAdoRecordset& rst );

private:
	_ConnectionPtr	_ConnPtr;
	static CAdoConnection*	_AdoConnPtr;

	CAdoConnection();
	CAdoConnection( const CAdoConnection& );
	CAdoConnection& operator = ( const CAdoConnection& );
};

#endif // __CAdoConnection_h__


AdoConnection.cpp

#include "AdoConnection.h"
#include "AdoRecordset.h"

CAdoConnection*	CAdoConnection::_AdoConnPtr = NULL;

CAdoConnection* CAdoConnection::GetAdoConnection()
{
	if( NULL == _AdoConnPtr ) {
		_AdoConnPtr = new CAdoConnection();
		if( !_AdoConnPtr->InitInstance() )
			return NULL;
		if( !_AdoConnPtr->Open() )
			return NULL;
	}
	return _AdoConnPtr;
}

void CAdoConnection::DestroyAdoConnection()
{
	if( NULL != _AdoConnPtr ) {
		_AdoConnPtr->Close();
		delete _AdoConnPtr;
		_AdoConnPtr = NULL;
	}
}

CAdoConnection::CAdoConnection()
{
	_ConnPtr	= NULL;
}

CAdoConnection::~CAdoConnection()
{
	try {
		if( IsOpened() )
			Close();
	}
	catch( _com_error e ) {
		CString strErrorMsg;
		strErrorMsg.Format( _T("AdoConnection析構失敗!\n錯誤資訊: %s"), e.ErrorMessage() );
		AfxMessageBox( strErrorMsg );
	}	
}

BOOL CAdoConnection::InitInstance()
{
	try {
		_ConnPtr.CreateInstance( __uuidof(Connection) );
		return TRUE;
	}
	catch( _com_error e ) {
		CString strErrorMsg;
		strErrorMsg.Format( _T("AdoConnection初始化失敗!\n錯誤資訊: %s"), e.ErrorMessage() );
		AfxMessageBox( strErrorMsg );
	}
	return FALSE;
}

BOOL CAdoConnection::Open() const
{
	try {
		if( IsOpened() )
			Close();
		if( SUCCEEDED(_ConnPtr->Open( g_DatabaseConnectionString, _T(""), _T(""), adModeUnknown)) )
			return TRUE;
	}
	catch( _com_error e ) {
		CString strErrorMsg;
		strErrorMsg.Format( _T("連線資料庫失敗!\n錯誤資訊: %s"), e.ErrorMessage() );
		AfxMessageBox( strErrorMsg );
	}
	return FALSE;
}

void CAdoConnection::Close() const
{
	try {
		if( IsOpened() )
			_ConnPtr->Close();
	}
	catch( _com_error e ) {
		CString strErrorMsg;
		strErrorMsg.Format( _T("斷開資料庫失敗!\n錯誤資訊: %s"), e.ErrorMessage() );
		AfxMessageBox( strErrorMsg );
	}
}

BOOL CAdoConnection::IsOpened() const
{
	if( NULL == _ConnPtr )
		return FALSE;
	if( _ConnPtr->State )
		return TRUE;
	return FALSE;
}

BOOL CAdoConnection::GetConnectionIDispatch( _variant_t& vActiveConn )
{
	vActiveConn = (IDispatch*)_ConnPtr;
	//vActiveConn = _ConnPtr.GetInterfacePtr();
	return TRUE;
}

BOOL CAdoConnection::ExecuteNonQuery( const TCHAR *sqlcmd ) const
{
	try {
		VARIANT vRecordAffected;
		VariantInit( &vRecordAffected );
		if( IsOpened() ) {
			_ConnPtr->Execute( (_bstr_t)sqlcmd, &vRecordAffected, adCmdText/*adExecuteNoRecords*/ );
			return TRUE;
		}
	}
	catch( _com_error e ) {
		CString strErrorMsg;
		strErrorMsg.Format( _T("ExecuteNonQuery失敗!\n錯誤資訊: %s"), e.ErrorMessage() );
		AfxMessageBox( strErrorMsg );
	}
	return FALSE;
}

BOOL CAdoConnection::Execute( const TCHAR *sqlcmd, CAdoRecordset& rst )
{
	try {
		const _variant_t strSql = sqlcmd;
		rst.Close();
		rst.Open( sqlcmd, *this );
		return TRUE;
	}
	catch( _com_error e ) {
		CString strErrorMsg;
		strErrorMsg.Format( _T("Execute失敗!\n錯誤資訊: %s"), e.ErrorMessage() );
		AfxMessageBox( strErrorMsg );
	}
	return FALSE;
}

BOOL CAdoConnection::OpenRecordset( TCHAR* sqlCmd, CAdoRecordset& recordset )
{
	return recordset.Open( sqlCmd, *this );
}


AdoRecordset.h

#ifndef __AdoRecordset_h__
#define __AdoRecordset_h__

class CAdoConnection;

class CAdoRecordset
{
public:
	CAdoRecordset();
	CAdoRecordset( _RecordsetPtr *ptr );
	~CAdoRecordset();

	void	MoveFirst	();
	void	MoveNext	();
	void	MovePrev	();
	void	MoveLast	();
	void	Move		( int offset );

	BOOL	Open		( const TCHAR *sql, CAdoConnection& adoConn );
	void	Close		();

	BOOL	IsOpened	();
	BOOL	IsBOF		();
	BOOL	IsEOF		();

	int		GetFieldCount		();
	int		GetFieldOrder		( const TCHAR *fieldname );
	TCHAR*	GetFieldName		( const int fieldorder );
	TCHAR*	GetFieldValueStr	( const int fieldorder );
	TCHAR*	GetFieldValueStr	( const TCHAR *fieldname );
	int		GetFieldValueInt	( const int fieldorder );
	int		GetFieldValueInt	( const TCHAR *fieldname );
	float	GetFieldValueFlt	( const int fieldorder );
	float	GetFieldValueFlt	( const TCHAR *fieldname );
	BOOL	GetFieldValueBool	( const int fieldoerder );
	BOOL	GetFieldValueBool	( const TCHAR *fieldname );

	int		GetRecordCount		();

private:
	_RecordsetPtr	_Recordset;
	CAdoRecordset( const CAdoRecordset& );
	CAdoRecordset& operator = ( const CAdoRecordset& );
};

#endif // __AdoRecordset_h__


AdoRecordset.cpp

#include "stdafx.h"
#include "AdoRecordset.h"
#include "AdoConnection.h"

CAdoRecordset::CAdoRecordset()
{
	try {
		_Recordset.CreateInstance( __uuidof(Recordset) );
	}
	catch( _com_error e ) {
		CString strErrorMsg;
		strErrorMsg.Format( _T("CAdoRecordset初始化失敗!\n錯誤資訊: %s"), e.ErrorMessage() );
		AfxMessageBox( strErrorMsg );
	}
}

CAdoRecordset::CAdoRecordset( _RecordsetPtr *ptr )
{
	try {
		(*ptr).CreateInstance( __uuidof(Recordset) );
		_Recordset = *ptr;
	}
	catch( _com_error e ) {
		CString strErrorMsg;
		strErrorMsg.Format( _T("CAdoRecordset初始化失敗!\n錯誤資訊: %s"), e.ErrorMessage() );
		AfxMessageBox( strErrorMsg );
	}
}

CAdoRecordset::~CAdoRecordset()
{
	if( IsOpened() )
		Close();
}

BOOL CAdoRecordset::Open( const TCHAR *sql, CAdoConnection& adoConn )
{
	if( NULL == sql || 0 == _ftcsclen(sql) ) {
		AfxMessageBox( _T("Empty Sql statement !") );
		return FALSE;
	}

	if( !adoConn.IsOpened() ) {
		AfxMessageBox( _T("CAdoRecordset::Open: adoConn is not opened !") );
		return FALSE;
	}

	if( _Recordset->State != adStateClosed )
		_Recordset->Close();

	_variant_t vActiveConn;
	if( !adoConn.GetConnectionIDispatch(vActiveConn) ) {
		AfxMessageBox( _T("CAdoRecordset::Open: adoConn.GetConnectionIDispatch failed !") );
		return FALSE;
	}

	try {
		HRESULT hr = _Recordset->Open( _variant_t(sql), vActiveConn, adOpenStatic/*adOpenKeyset*/,
			adLockOptimistic/*adLockReadOnly*/, adCmdUnknown/*adOptionUnspecified*/ );
		return SUCCEEDED(hr);
	}
	catch( _com_error e ) {
		CString strErrorMsg;
		strErrorMsg.Format( _T("CAdoRecordset::Open()失敗!\n錯誤資訊: %s"), e.ErrorMessage() );
		AfxMessageBox( strErrorMsg );
		TCHAR *p = (TCHAR*)(e.Description());
		AfxMessageBox( p );
	}

	return FALSE;
}

void CAdoRecordset::Close()
{
	if( IsOpened() )
		_Recordset->Close();
}

BOOL CAdoRecordset::IsOpened()
{
	if( _Recordset->State )
		return TRUE;
	return FALSE;
}

BOOL CAdoRecordset::IsEOF()
{
	BOOL rst = TRUE;
	if( IsOpened() )
		rst = (BOOL)(_Recordset->GetadoEOF());
	return rst;
}

BOOL CAdoRecordset::IsBOF()
{
	BOOL rst = TRUE;
	if( IsOpened() )
		rst = (BOOL)(_Recordset->GetBOF());
	return rst;
}

int CAdoRecordset::GetRecordCount()
{
	int count = -1;
	if( IsOpened() )
		count = (int)_Recordset->GetRecordCount();
	return count;
}

void CAdoRecordset::MoveFirst()
{
	if( IsOpened() )
		_Recordset->MoveFirst();
}

void CAdoRecordset::MoveNext()
{
	if( IsOpened() )
		_Recordset->MoveNext();
}

void CAdoRecordset::MovePrev()
{
	if( IsOpened() )
		_Recordset->MovePrevious();
}

void CAdoRecordset::MoveLast()
{
	if( IsOpened() )
		_Recordset->MoveLast();
}

void CAdoRecordset::Move( int offset )
{
	if( IsOpened() )
		_Recordset->Move( (long)offset );
}

int CAdoRecordset::GetFieldCount()
{
	int fieldCount = -1;
	if( IsOpened() )
		fieldCount = _Recordset->GetFields()->GetCount();
	return fieldCount;
}

int CAdoRecordset::GetFieldOrder( const TCHAR* fieldname )
{
	int fieldOrder = -1;
	if( IsOpened() ) {
		int fieldCount = GetFieldCount();
		for( int i = 0; i < fieldCount; i++ ) {
			if(_Recordset->GetFields()->Item[i]->Name == (_bstr_t)fieldname ) {
				fieldOrder = i;
				break;
			}
		}
	}
	return fieldOrder;
}

TCHAR* CAdoRecordset::GetFieldName( const int fieldorder )
{
	if( IsOpened() ) {
		if( NULL != _Recordset->GetFields() ) {
			int fieldCount = _Recordset->GetFields()->GetCount();
			if( fieldCount > 0 ) {
				if( fieldorder >= 0 && fieldorder < fieldCount )
					return (TCHAR*)(_Recordset->GetFields()->Item[fieldorder]->Name);
			}
		}
	}
	return NULL;
}

TCHAR* CAdoRecordset::GetFieldValueStr( const int fieldorder )
{
	if( IsOpened() ) {
		if( NULL != _Recordset->GetFields() ) {
			int fieldCount = _Recordset->GetFields()->GetCount();
			if( fieldCount > 0 ) {
				if( fieldorder >= 0 && fieldorder < fieldCount ) {
					return (TCHAR*)((_Recordset->GetFields()->Item[fieldorder]->Value).operator _bstr_t());
				}
			}
		}
	}
	return NULL;
}

TCHAR* CAdoRecordset::GetFieldValueStr( const TCHAR *fieldname )
{
	if( IsOpened() ) {
		try {
			if( NULL != _Recordset->GetFields() )
				return (TCHAR*)((_Recordset->Fields->Item[fieldname]->Value).operator _bstr_t());
		}
		catch( _com_error e ) {
			//CString strErrorMsg;
			//strErrorMsg.Format( _T("CAdoRecordset初始化失敗!\n錯誤資訊: %s"), e.ErrorMessage() );
			//AfxMessageBox( strErrorMsg );
		}
	}
	return NULL;
}

int CAdoRecordset::GetFieldValueInt( const int fieldorder )
{
	if( IsOpened() ) {
		if( NULL != _Recordset->GetFields() ) {
			int fieldCount = _Recordset->GetFields()->GetCount();
			if( fieldCount > 0 ) {
				if( fieldorder >= 0 && fieldorder < fieldCount ) {
					return (int)(_Recordset->GetFields()->GetItem(fieldorder)->Value).operator int();
				}
			}
		}
	}
	return -1;
}

int CAdoRecordset::GetFieldValueInt( const TCHAR *fieldname )
{
	if( IsOpened() ) {
		if( NULL != _Recordset->GetFields() ) {
			return (_Recordset->Fields->Item[fieldname]->Value).operator int();
		}
	}
	return -1;
}

float CAdoRecordset::GetFieldValueFlt( const int fieldorder )
{
	float ret = -1.0;
	if( IsOpened() ) {
		if( NULL != _Recordset->GetFields() ) {
			int fieldCount = _Recordset->GetFields()->GetCount();
			if( fieldCount > 0 ) {
				if( fieldorder >= 0 && fieldorder < fieldCount ) {
					ret = (float)((_Recordset->GetFields()->Item[fieldorder]->Value).operator float());
				}
			}
		}
	}
	return ret;
}

float CAdoRecordset::GetFieldValueFlt( const TCHAR *fieldname )
{
	float ret = -1.0;
	if( IsOpened() ) {
		if( NULL != _Recordset->GetFields() ) {
			return (_Recordset->Fields->Item[fieldname]->Value).operator float();
		}
	}
	return ret;
}

BOOL CAdoRecordset::GetFieldValueBool( const int fieldorder )
{
	BOOL ret = FALSE;
	if( IsOpened() ) {
		if( NULL != _Recordset->GetFields() ) {
			int fieldCount = _Recordset->GetFields()->GetCount();
			if( fieldCount > 0 ) {
				if( fieldorder >= 0 && fieldorder < fieldCount ) {
					ret = (BOOL)((_Recordset->GetFields()->Item[fieldorder]->Value).operator bool());
				}
			}
		}
	}
	return ret;
}

BOOL CAdoRecordset::GetFieldValueBool( const TCHAR *fieldname )
{
	BOOL ret = FALSE;
	if( IsOpened() ) {
		if( NULL != _Recordset->GetFields() ) {
			return (BOOL)((_Recordset->Fields->Item[fieldname]->Value).operator bool());
		}
	}
	return ret;
}


使用:

if (!AfxOleInit())
{
    AfxMessageBox(IDP_OLE_INIT_FAILED);
    return FALSE;
}

if( NULL == CAdoConnection::GetAdoConnection() ) {
    g_Log.Write( _T("連線資料庫失敗") );
    return -1;
}

// ......



 
CString strCmd;
strCmd.Format( _T("SELECT * FROM StdTable WHERE (Id='%d')"), m_Id );
try {
    CAdoConnection *pAdoConn = CAdoConnection::GetAdoConnection();
    CAdoRecordset recordset;
    pAdoConn->OpenRecordset( strCmd.GetBuffer(0), recordset );
    int count = recordset.GetRecordCount();
    if( count > 0 ) {
        _count = count;
        _list = new MyList[count];
   
        recordset.MoveFirst();
        for( int i = 0; i < count; i++ ) {
            _list[i].SetId( recordset.GetFieldValueInt(_T("Id")) );
            _list[i].SetName( recordset.GetFieldValueStr(_T("Name")) );
            recordset.MoveNext();
        }
    }
}
catch( _com_error e ) {
    CString strError;
    strError.Format( _T("Error: %s\r\n"), e.ErrorMessage() );
    AfxMessageBox( strError );
} 

 


// ......

CAdoConnection *pAdoConn = CAdoConnection::GetAdoConnection();
if( NULL == pAdoConn )
        return FALSE;
		
CString strSql;
strSql.Format( _T("INSERT INTO StdTable(Name, Id) VALUES('%s', '%d')"), m_Name, _Id );
if( !pAdoConn->ExecuteNonQuery(strSql.GetBuffer(0)) )
        return FALSE;

// ......

CAdoConnection::DestroyAdoConnection();
AfxOleTerm(FALSE);