📄 封装ado访问数据库的两个类 .htm
字号:
<B>给贴子投票 </B>
<BR><a href='http://www.csdn.net/develop/addscore.asp?id=
7607
'>投票</a>
</TD></TR>
<TR>
<TD >
seesi
原作
</TD>
<TD colSpan=3 vAlign=top>
<B>出处: </B><A href='
'>
</A></TD></TR>
<TR><TD colSpan=5 bgcolor=#cccc99> </TD></TR>
</TD></TR></TBODY></TABLE>
<div align=center><div class=fst align=left><div class=fstdiv3 id=print2>
<br><br><P> </P>
<P> </P>
<P> </P>
<P> 对于初学者,使用ADO访问数据库的时候,涉及到各种数据类型转换,可能有一些难度,我试图封装了ADO访问数据库,使其更方便的用现有的VC的数据类型,更加方便的使用ADO操作数据库。<BR>下面分别提供两个封装ADO数据库访问的类,一个是数据库的连接类,一个是数据库字段访问的类。</P>
<P> 在连接类中,大家可以看到,连接类中并没有Recordset的成员变量,因为这样的,在整个数据库应用程序中,数据库的连接一般一个就够了,而同时打开的Reocordset则可能不只一个,所以,如果两个在同一个类里,那么,如果要同时打开两个记录集,需要建立类的两个实例,就是需要同时打开两个数据库连接,如果对于连接的是同一个数据库,同时打开两个连接的话,意味着资源的不必要的浪费。</P>
<P> 数据库字段访问类,简化了,获取数据库字段内容的操作,避免了数据类型转换的麻烦。</P>
<P> 两个类都对错误处理进行了较多的考虑,在访问数据库中,如果没有错误处理,其害处是显而易见的。</P>
<P> </P>
<P><BR>#ifndef _BBADOCONNECT_H<BR>#define _BBADOCONNECT_H</P>
<P><FONT color=#6600ff>//<BR>// ADO访问数据库类<BR>// 软件环境:需要MSADO15.DLL<BR>// 作者:邓振波<BR>// 2001.4.20<BR>// Email:<A href="mailto:seesi@china.com">seesi@china.com</A></FONT><BR><FONT color=#6600ff>// 说明:封装了ADO使用的操作函数和ADO访问数据库错误处理<BR>// 使在VC上方便的使用ADO访问数据库<BR>// 包括:ADO连接数据库、打开记录集、执行SQL、以及<BR>// 事务处理、ADO记录集内容转换成C++的常用数据类型(</FONT><FONT color=#6600ff>CString、char,long,float等)<BR>//<BR>// 使用:1。定义一个CBBAdoConnection实例:CBBAdoConnection </FONT><FONT color=#6600ff>m_adoConn;<BR>// 2。建立连接:m_adoConn.Open(strConnstring);<BR>// 如果需要无条件重新连接的可</FONT><FONT color=#6600ff>以,参数bRepen设成TREU<BR>// 3。打开记录集:<BR>//<BR>// _RecordsetPtr* prsThis=NULL;<BR>// prsThis=new _RecordsetPtr;<BR>// CString strSQL;<BR>// strSQL="select * from Table_Name";// <BR>// 如果记录集打开失败<BR>// </FONT></P>
<P><FONT color=#6600ff>if(!(m_adoConn.OpenRecordset(strSQL,prsThis)))<BR>// return FALSE;<BR>// 4。建立记录集值对象<BR>// 注意需要用参数构造<BR>// CBBRstValues rsv(m_adoConn,prsThis);<BR>// <BR>// 5。获得的字段的值<BR>// rsv.GetValueLong(&m_nDeptID,1L);//获得第一</FONT><FONT color=#6600ff>个字段的值<BR>// rsv.GetValueStr(m_strName,"ID");//获得第一</FONT><FONT color=#6600ff>个字段名为ID的值<BR>// 其它的同理.如果需要获得SQL Server中</FONT><FONT color=#6600ff>nText类型的字段值请用<BR>// GetValText(CString &strText, CString </FONT><FONT color=#6600ff>&strFieldName)函数<BR>// 6。记录集的记录移动 (*prsThis)->MoveNext()等类</FONT><FONT color=#6600ff>似函数<BR>// 7。记录集不用时候需要释放其资源<BR>// 1)关闭记录集<BR>// 2)删除记录集指针<BR>// e.g. (*prsThis)->Close();<BR>// delete prsThis;<BR>// prsThis=NULL;<BR>// 否则会造成内存泄漏<BR>// <BR>// 注:<BR>// 1。程序必须要初始化COM环境,请在应用类中加</FONT><FONT color=#6600ff>入AfxOleInit函数初始化环境,否则ADO的调用将失败<BR>// 2。如果需要调用存储过程SQL语句改为“Exec ” </FONT><FONT color=#6600ff>+ 存储过程名即可,与执行SQL同样<BR>//<BR>// CopyRight seesi,2001<BR>//<BR>// 说明:你可以随便在的程序中任意使用、修改本代码,但请你不要删</FONT><FONT color=#6600ff>除文件头的<FONT color=#6600ff></FONT>部分说明。如果需要转载,请注明出处。<BR>// msado15.dll必须放在本文件所在目录,或者自己指定下面的msado15.dll</FONT><FONT color=#6600ff>全路径<BR>// </FONT></P>
<P>#if !defined(__AFXADO_H)<BR>#import "msado15.dll" no_namespace rename ("EOF", "adoEOF") \<BR> rename ("LockTypeEnum", "adoLockTypeEnum") \<BR> rename ("DataTypeEnum", "adoDataTypeEnum") \<BR> rename ("FieldAttributeEnum", </P>
<P>"adoFieldAttributeEnum") \<BR> rename ("EditModeEnum", "adoEditModeEnum") \<BR> rename ("RecordStatusEnum", "adoRecordStatusEnum") </P>
<P>\<BR> rename ("ParameterDirectionEnum", </P>
<P>"adoParameterDirectionEnum")<BR>#endif // !defined(__AFXADO_H)</P>
<P><BR>class CBBAdoConnection <BR>{<BR>public:<BR> CBBAdoConnection();<BR> virtual ~CBBAdoConnection();<BR>public:<BR> int SetConnTimeOut(long lTimeOut); <FONT color=#9900ff>// 设置连接超时<BR> </FONT>int SetCommTimeOut(long lTimeOut); <FONT color=#9900ff>// 设置命令执行超时<BR></FONT> BOOL IsConnectClose(); <FONT color=#9900ff>// 判断连接是否已经打开<BR></FONT><FONT color=#9900ff> </FONT>int ExecuteSQL(LPCSTR szSQL); <FONT color=#9900ff>// 简单执行SQL语句,不返回记录</FONT><FONT color=#9900ff>集</FONT><BR><FONT color=#9900ff> // 打开数据库记录集<BR> // 参数:<BR> // strSQL 记录集的SQL语句<BR> // rs 返回的记录集_RecordsetPtr对象 <BR> // sConnString 数据库的连接字符串<BR> // 如果使用数据库连接已经打开,参数没用<BR> // 如果数据库的连接没有打开,当给予一个连接字符串,将先打开数据库连接<BR></FONT> BOOL OpenRecordset(CString strSQL, _RecordsetPtr *rs,CString sConnString="");<FONT color=#9709f7>//打开数据库记录集 <BR></FONT> BOOL OpenRecordset(const char *sSQL,_RecordsetPtr* rs,char* sConnString=NULL);</P>
<P> <FONT color=#9709f7>// 打开数据库连接<BR> // 参数:<BR> // strConnString 连接字符串<BR> // sConnString 连接字符串<BR> // bReOpen 是否重新打开,如果</FONT><FONT color=#9709f7>为FALSE,,<BR> // 将先判断数</FONT><FONT color=#9709f7>据库是否打开如果没有打开则打开,<BR> // 如果已经打</FONT><FONT color=#9709f7>开,将不执行任何操作<BR> // 如果为TRUE</FONT><FONT color=#9709f7>,则无条件重新打开。<BR> </FONT>BOOL OpenConnection(CString strConnString ,BOOL bReOpen=FALSE); <BR> BOOL OpenConnection(char* sConnString,BOOL bReOpen=FALSE); void CloseConnect();<FONT color=#9709f7>// 关闭数据库连接 </FONT></P>
<P> BOOL ExecuteTrans(CStringArray arrStrSQL); <FONT color=#9709f7>// 事务处理,</FONT><FONT color=#9709f7>不返回任何记录集,参数为事务SQL数组</FONT></P>
<P><BR><FONT color=#9709f7> </FONT>_ConnectionPtr* GetConnection(); <FONT color=#9709f7>// 得到_ConnectionPtr指针<BR></FONT> CString GetConnString(); <FONT color=#9709f7>// 得到连接字符串 <BR></FONT>private:<BR> enum ERRORFrom { <BR> ErrFormOpenConnsction,<BR> ErrFromOpenRecordset,<BR> ErrFormCloseConnection,<BR> ErrFormTanslation<BR> };<BR> _ConnectionPtr* m_pConn;<BR> char m_szConnString[512];<BR> <FONT color=#9709f7>///<BR></FONT>protected:<BR> void ReportError(int nERRORfrom);<BR>};</P>
<P><BR>class CBBRstValues <BR>{ <BR>public:<BR><FONT color=#9709f7> // 三种构造类的方法<BR> // 如果无参数构造,请构造后调用InitConnectAndRst方法<BR> // 其他的两种构造则不需调用InitConnectAndRst方法 <BR> </FONT>CBBRstValues();<BR> CBBRstValues(_ConnectionPtr* pConn,_RecordsetPtr* pRs);<BR> CBBRstValues(CBBAdoConnection* pBBadoConn,_RecordsetPtr* </P>
<P>pRs);</P>
<P> virtual ~CBBRstValues();<BR>public:<BR> <FONT color=#9709f7>// 初始化连接队象和记录集对象<BR></FONT> void InitConnectAndRst(_ConnectionPtr* pConn,_RecordsetPtr* pRs);<BR> void InitConnectAndRst(CBBAdoConnection* pBBAdoConn, _RecordsetPtr * Rs);</P>
<P><FONT color=#9709f7> // GetValText函数<BR> // 得到数据库nText字段的值<BR> // 参数:<BR> // strText 用来接收返回值(字段值)<BR> // strFieldName 字段名,该字段数据类型必须是nText类型<BR></FONT> BOOL GetValText(CString& strText,CString& strFieldName); <FONT color=#9709f7>//得到数据库nText</FONT><FONT color=#9709f7>字段的值</FONT><BR><FONT color=#9709f7> <BR> // GetValueStr函数<BR> // 得到数字型,日期型和字符型字段值函数<BR> // 参数:<BR> // cVal 用来接收返回值(字段值)的字符串指针,要求要开辟足够的内存单元<BR> // 或者足够容纳字段内容的字符数组。<BR> // vIndex 数据库字段的名字或者索引,变体型,一般不直接用这个参数,<BR> // 应该用同形式的多态函数的参数调用<BR> // 数据库字段的数据类型可以是数字型,日期型和字符型<BR> // nFieldLen 需要返回的数据的字符串的长度,如果为-1,则返回整个字段值<BR> // lpszFieldName 字段名,数据库字段的数据类型可以是数字型,日期型和字符型<BR> // nFieldIndex 在SQL语句中字段的索引序号数据库字段的数据类型可以是数字型,日期型和字符型</FONT></P>
<P><FONT color=#9709f7> // GetValueLong函数<BR> // 得到数字型,日期型和字符型字段值函数<BR> // 参数:<BR> // lVal 用来接收返回值(字段值)<BR> // vIndex 数据库字段的名字或者索引,变体型,一般不直接用这个参数,<BR> // 应该用同形式的多态函数的参数调用<BR> // 数据库字段的数据类型要求是数字型(int,long) <BR> // lpszFieldName 字段名,数据库字段的数据类型可以是数字型,日期型和字符型<BR> // nFieldIndex 在SQL语句中字段的索引序号数据库字段的数据类型可以是数字型,日期型和字符型</FONT></P>
<P><FONT color=#9709f7> // GetValueFlaot函数<BR> // 得到数字型,日期型和字符型字段值函数<BR> // 参数:<BR> // fVal 用来接收返回值(字段值)<BR> // vIndex 数据库字段的名字或者索引,变体型,一般不直接用这个参数,<BR> // 应该用同形式的多态函数的参数调用<BR> // 数据库字段的数据类型要求是字型(int,long,float,货币型等) <BR> // lpszFieldName 字段名,数据库字段的数据类型可以是数字型,日期型和字符型<BR> // nFieldIndex 在SQL语句中字段的索引序号数据库字段的数据类型可以是数字型,日期型和字符型</FONT></P>
<P> BOOL GetValueStr(char* cVal,_variant_t &vIndex,int </P>
<P>nFieldLen=-1);<BR> BOOL GetValueLong(long* lVal,_variant_t &vIndex);<BR> BOOL GetValueFloat(float* fVal,_variant_t &vIndex);</P>
<P> BOOL GetValueStr(char* cVal,long lIndex,int nFieldLen=-1);<BR> BOOL GetValueLong(long* lVal,long lIndex);<BR> BOOL GetValueFloat(float* fVal,long lIndex);</P>
<P> BOOL GetValueStr(char* cVal,CString strIndex,int nFieldLen=-1);<BR> GetValueLong(long *lVal, LPCSTR lpszIndex);<BR> BOOL GetValueFloat(float* fVal,CString strIndex);</P>
<P> BOOL GetValueStr(CString& str,LPCSTR lpszFieldName,int nFieldLen=-1);<BR> BOOL GetValueStr(CString& str,UINT nFieldIndex,int nFieldLen=-1);<BR> BOOL GetValueStr(CString& str,_variant_t &vIndex,int nFieldLen=-1);</P>
<P><FONT color=#9709f7> // 判断值是否有效,是否为NULL<BR></FONT> BOOL VerifyVTData(_variant_t& value);<BR> BOOL VerifyVTData(char* pData); <BR>protected: <BR> _RecordsetPtr* m_prsThis;<BR> _ConnectionPtr* m_pConn;<BR> void ReportError();</P>
<P>};</P>
<P>#endif // _BBADOCONNECT_H</P>
<P> </P>
<P> </P>
<P> </P>
<P><FONT color=#9709f7>////CPP文件</FONT></P>
<P><FONT color=#9709f7>//////////////////////////////////////////////////////////////////////<BR>// Construction/Destruction<BR>//////////////////////////////////////////////////////////////////////</FONT></P>
<P>CBBAdoConnection::CBBAdoConnection()<BR>{ <BR> m_pConn=NULL;<BR>}</P>
<P>_ConnectionPtr* CBBAdoConnection::GetConnection()<BR>{<BR> return m_pConn;<BR>}</P>
<P>CString CBBAdoConnection::GetConnString()<BR>{<BR> return m_szConnString;<BR>}</P>
<P>CBBAdoConnection::~CBBAdoConnection()<BR>{<BR><FONT color=#9709f7> // 关比连接<BR></FONT> CloseConnect();<BR>}</P>
<P>BOOL CBBAdoConnection::OpenConnection(char *sConnString,BOOL bReOpen /*=FALSE*/)<BR>{<BR> <BR> // 不需重新打开<BR> if(!bReOpen)<BR> {<BR> if(m_pConn !=NULL && ((*m_pConn)->State!=adStateClosed))<BR> return TRUE; <BR> }</P>
<P> VERIFY(sConnString); <BR> strcpy(m_szConnString,sConnString); </P>
<P> try<BR> {<BR> m_pConn =new _ConnectionPtr;<BR> m_pConn->CreateInstance(__uuidof(Connection));<BR> if(m_pConn==NULL)<BR> return FALSE;<BR> HRESULT hr=(*m_pConn)->Open((char*)sConnString,"","",-1); <BR> if(FAILED(hr))<BR> return FALSE; <BR> return TRUE;<BR> }<BR> catch(_com_error)<BR> {<BR> ReportError(ErrFormOpenConnsction);<BR> return FALSE;<BR> }<BR> catch(...)<BR> {<BR> #ifdef _DEBUG <FONT color=#9709f7>// 调试时显示相应的错误信息<BR></FONT> MessageBox(NULL,"数据库连接未处理的异常!","连接失败",MB_OK|MB_ICONINFORMATION);<BR> #else <BR> MessageBox(NULL,"连接数据失败,请检查网络和数据库设置是否正确","连接失败",MB_OK|MB_ICONINFORMATION);<BR> #endif<BR> return FALSE;<BR> } <BR> SetConnTimeOut(5);<BR>}</P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -