用Delphi的思想初步构建C++的ADO对象
其实名字起的太大了,哈哈,大家有没有在写数据库的时候老是需要try,catch,觉得很麻烦呢?我可受不了啊。但是没怎么写下去,一是对VC的ADO不了解,二是没时间。我把写的一些代码贴上来,有兴趣的人自己看下去。我懒得多解释了。贴上来等以后自己也可以看看。
看我的几个类吧。
#define READ_ONLY 1
#define WRITE_ONLY 2
#define READ_WRITE 3
template<typename Container, typename ValueType, int nPropType>
class CProperty
{
public:
CProperty()
{
m_cObject = NULL;
Set = NULL;
Get = NULL;
}
//设置属性所在的对象指针
void setContainer(Container* cObject)
{
m_cObject = cObject;
}
//设置set指针,用来修改属性用
void setter(void (Container::*pSet)(ValueType value))
{
if((nPropType == WRITE_ONLY) || (nPropType == READ_WRITE))
Set = pSet;
else
Set = NULL;
}
//设置get指针,用来读取属性用
void getter(ValueType (Container::*pGet)())
{
if((nPropType == READ_ONLY) || (nPropType == READ_WRITE))
Get = pGet;
else
Get = NULL;
}
//重载=操作符,用于实现这样的操作 CAdoConnection.Connected = TRUE;
//注意CAdoConnection.Connected其实是一个CProperty的对象
//属性的实现关键在于重载=操作符和隐式转换操作符
//重载后调用CProperty的拥有者的get、set函数来达到目的
ValueType operator =(const ValueType& value)
{
assert(m_cObject != NULL);
assert(Set != NULL);
(m_cObject->*Set)(value);
return value;
}
//重载隐式转换操作符
operator ValueType()
{
assert(m_cObject != NULL);
assert(Get != NULL);
return (m_cObject->*Get)();
}
private:
Container* m_cObject; //属性的拥有者
void (Container::*Set)(ValueType value); //set函数指针
ValueType (Container::*Get)(); //get函数指针
};
class CAdoConnection
{
public:
CAdoConnection();
~CAdoConnection();
//隐式的转换操作,不推荐使用,只是暂时类没有封装好,给客户一个方便
//使用时请确保指针在类的生命期内使用
operator _ConnectionPtr();
public:
CProperty<CAdoConnection, BOOL, READ_WRITE> Connected;
string ConnectingString;
string UserName, PassWord;
private:
void SetConnected(BOOL ConnectFlag);
BOOL GetConnected();
private:
_ConnectionPtr m_ptrConn;
friend class CAdoCommand;
friend class CAdoQuery;
};
class CAdoCommand
{
public:
CAdoCommand();
~CAdoCommand();
void Execute();
operator _CommandPtr();
public:
CommandTypeEnum CommandType;
string CommandText;
CAdoConnection * m_AdoConnection;
private:
_CommandPtr m_ptrComm;
};
//CAdoConnection
CAdoConnection::CAdoConnection()
{
Connected.setContainer(this);
Connected.setter(&CAdoConnection::SetConnected);
Connected.getter(&CAdoConnection::GetConnected);
// 创建一个连接实例
try {
HRESULT hr = m_ptrConn.CreateInstance(__uuidof(Connection));
if (FAILED(hr)) {
CString errormessage("创建实例失败!");
AfxMessageBox(errormessage);
}
}
catch(_com_error & error) {
CString errormessage;
errormessage.Format("创建实例失败!\r\n错误信息:%s", error.ErrorMessage());
AfxMessageBox(errormessage);
}
// 设定连接等待的最大秒数,默认是15秒
m_ptrConn->ConnectionTimeout=15;
UserName = "";
PassWord = "";
}
CAdoConnection::~CAdoConnection()
{
if (GetConnected())
SetConnected(FALSE);
m_ptrConn=NULL;
}
CAdoConnection::operator _ConnectionPtr()
{
return m_ptrConn;
}
void CAdoConnection::SetConnected(BOOL ConnectFlag)
{
if (TRUE == ConnectFlag) {
try {
// 打开连接
m_ptrConn->Open(ConnectingString.c_str(), UserName.c_str(), PassWord.c_str(), adModeUnknown);
}
catch(_com_error & error) {
CString errormessage;
errormessage.Format("连接数据库失败!\r\n错误信息:%s", error.ErrorMessage());
AfxMessageBox(errormessage);
}
}
else {
m_ptrConn->Close();
}
}
BOOL CAdoConnection::GetConnected()
{
if (m_ptrConn->State == adStateOpen)
return TRUE;
else
return FALSE;
}
//CAdoCommand
CAdoCommand::CAdoCommand()
{
m_AdoConnection = NULL;
CommandText = adCmdText;
// 创建一个命令对象实例
try {
HRESULT hr = m_ptrComm.CreateInstance(__uuidof(Command));
if (FAILED(hr)) {
CString errormessage("创建实例失败!");
AfxMessageBox(errormessage);
}
}
catch(_com_error & error) {
CString errormessage;
errormessage.Format("创建实例失败!\r\n错误信息:%s", error.ErrorMessage());
AfxMessageBox(errormessage);
}
}
CAdoCommand::~CAdoCommand()
{
m_ptrComm = NULL;
}
void CAdoCommand::Execute()
{
if ((m_AdoConnection == NULL) || (m_AdoConnection->Connected == FALSE))
return;
m_ptrComm->ActiveConnection = m_AdoConnection->m_ptrConn;
m_ptrComm->CommandType = CommandType;
m_ptrComm->CommandText = CommandText.c_str();
try {
m_ptrComm->Execute(NULL,NULL,adCmdUnknown);
}
catch(_com_error & error) {
CString errormessage;
errormessage.Format("查询数据库失败!\r\n错误信息:%s", error.ErrorMessage());
AfxMessageBox(errormessage);
}
}
CAdoCommand::operator _CommandPtr()
{
return m_ptrComm;
}
再来看一下我的简单的界面以及客户代码吧:
void CTestDataAccessDlg::Open()
{
// TODO: Add your control notification handler code here
m_AdoConnection.ConnectingString = "Provider=SQLOLEDB;Network Address=127.0.0.1;Initial Catalog=ere";
m_AdoConnection.UserName = "sa";
m_AdoConnection.PassWord = "S2k";
if (m_AdoConnection.Connected == FALSE)
m_AdoConnection.Connected = TRUE;
}
void CTestDataAccessDlg::Query()
{
// TODO: Add your control notification handler code here
m_AdoCommand.CommandType = adCmdText;
m_AdoCommand.CommandText = "select count(*) from Form_common";
m_AdoCommand.m_AdoConnection = &m_AdoConnection;
m_AdoCommand.Execute();
}
void CTestDataAccessDlg::Close()
{
// TODO: Add your control notification handler code here
if (m_AdoConnection.Connected == TRUE)
m_AdoConnection.Connected = FALSE;
}
好了,代码就是这些,能看明白吧?看不懂我也没办法 J
温柔的毒药 3/24/2005