• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            hdqqq

              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
              35 隨筆 :: 0 文章 :: 104 評論 :: 0 Trackbacks


            在前面的幾篇文章中,分別對ado操作接口,單條的記錄結構,variant數據轉換為c數據類型等做了說明,這些都是為最終實現一個方便的數據庫操作接口作準備,在這一篇里,將創建一個模板數據庫記錄集操作類,它需要實現的功能有, select, update, 和delete操作,當然,除了select sql是將在程序中給出外,其它的象update,delete等都應該是這個模板記錄集根據字段類型和名稱自動生成的,而不必再人工生成這些sql語句. 用過微軟的.net的dataset應該有類似的體驗,在vs2003中,通過wizzard生成和數據庫相關的dataset記錄集和datarow等,用戶只要在dataset中添加和刪除,最后update一下,dataset自動幫你生成sql并執行.這樣就方便了很多.同時,記錄集的某條記錄的成員都是強數據類型的,而不是可變的variant數據類型. 對于經常使用的跨表的數據查詢等,也可以使用,無需先定義數據結構的麻煩.


            template? < typename ?_tlist >
            class?data_op_recordset
            {
            public :

            ????typedef?data_op_record_row
            < _tlist > ?_DataRow;
            ????typedef?std::list
            < ?_DataRow * ? > ?_DataSet;
            ????typedef?std::vector
            < ?__tagFieldInfo? > ?_FieldNames;
            ????enum?{
            ????????en_field_count?
            = ?_DataRow::en_member_count,
            ????};

            public :
            ????virtual?BOOL?Load(
            const ?TCHAR * ?query,?CCom_Connection & ?conn)?{
            ????????CCom_Recordset?lreset(__uuidof(Recordset));
            ????????_bstr_t?sql?
            = ?query;
            ????????lreset
            -> Open(sql,?(IDispatch * )conn,?ADODB_L::adOpenStatic,?ADODB_L::adLockReadOnly,?ADODB_L::adCmdText);
            ????????
            if ?(m_DataSet.size())?{
            ????????????Clear();
            ????????}

            ????????GetFieldName(lreset);

            ????????
            if ?(!lreset -> ADO_EOF? && ?!lreset -> BOF)?{
            ????????????
            ????????????lreset
            -> MoveFirst();
            ????????????
            int ?i;
            ????????????
            for ?(i? = ? 0 ;?i? < ?lreset -> GetRecordCount();?i ++ )?{
            ????????????????_DataRow
            * ?prow? = ? new ?_DataRow;
            ????????????????_data_get
            < en_field_count > ::DoDataChange(prow,?m_FieldNames,?lreset);
            ????????????????m_DataSet.push_back(prow);
            ????????????????lreset
            -> MoveNext();
            ????????????}
            ????????}
            ????????return?
            0 ;
            ????}

            ????virtual?BOOL?Update(CCom_Connection
            & ?conn)?{

            ????????BeforeUpdate();

            ????????BOOL?ret?
            = ? FALSE ;
            ????????std::list
            < ?CString? > ?sql_list;
            ????????
            for (_DataSet::iterator?it? = ?m_DataSet.begin();?it?! = ?m_DataSet.end();?it ++ )?{
            ????????????CString?sql;
            ????????????
            if ?(( * it) -> m_en_State? == ?_DataRow::_en_Row_Add)?{
            ????????????????sql?
            = ?MakeInsertSql( * ( * it));
            ????????????}

            ????????????
            if ?(( * it) -> m_en_State? == ?_DataRow::_en_Row_Update)?{
            ????????????????sql?
            = ?MakeUpdateSql( * ( * it));
            ????????????}

            ????????????
            if ?(( * it) -> m_en_State? == ?_DataRow::_en_Row_Del)?{
            ????????????????sql?
            = ?MakeDeleteSql( * ( * it));
            ????????????}
            ????????????
            if ?(sql.GetLength())?{

            ????????????????sql_list.push_back(sql);
            ????????????????TRACE(
            " %s\n " ,?sql);
            ????????????}
            ????????}

            ????????
            if ?(sql_list.size())?{
            ????????????conn
            -> BeginTrans();
            ????????????try?{
            ????????????????std::list
            < CString > ::iterator?it;
            ????????????????
            for ?(it? = ?sql_list.begin();?it?! = ?sql_list.end();?it ++ )?{
            ????????????????????CString?cc;
            ????????????????????_bstr_t?temp;
            ????????????????????
            ????????????????????_variant_t?RecordsAffected;
            ????????????????????cc?
            = ? * it;
            ????????????????????cc.Replace(
            ' \'','\"');
            ????????????????????TRACE( " %s\n " ,?cc);
            ????????????????????temp?
            = ?cc;
            ????????????????????conn
            -> Execute (temp,? & RecordsAffected,?ADODB_L::adCmdText);
            ????????????????}
            ????????????}catch?(_com_error?
            & e)?{
            ????????????????CString?info;
            ????????????????_bstr_t?es,?ds;
            ????????????????es?
            = ?e.ErrorMessage();
            ????????????????ds?
            = ?e.Description();
            ????????????????CString?c1,?c2;
            ????????????????c1?
            = ?es.operator?char * ();
            ????????????????c2?
            = ?ds.operator?char * ();
            ????????????????info.Format(
            " 錯誤:?%s?%s " ,?c1,?c2);
            ????????????????AfxMessageBox(info);
            ????????????????conn
            -> RollbackTrans();
            ????????????????return?
            FALSE ;
            ????????????}
            ????????????conn
            -> CommitTrans();
            ????????}

            ????????AfterUpdate();

            ????????return?
            TRUE ;
            ????}

            ????
            int ?GetRecordCount()?{
            ????????return?m_DataSet.size();
            ????}

            ????size_t?AddRow(_DataRow
            * ?pnew)?{
            ????????m_DataSet.push_back(pnew);
            ????????return?m_DataSet.size();
            ????}

            ????void?DelLastRow(size_t?index)?{
            ????????assert(m_DataSet.size()?
            == ?index);

            ????????
            if ?(m_DataSet.size())?{
            ????????????_DataSet::iterator?it?
            = ?m_DataSet.end();
            ????????????m_DataSet.erase(
            -- it);
            ????????}

            ????????
            ????}

            ????_DataRow
            & ?Row( int ?index)?{
            ????????
            int ?i;
            ????????_DataSet::iterator?it?
            = ?m_DataSet.begin();
            ????????
            for ?(i? = ? 0 ;?i? < ?index;?i ++ )?{
            ????????????it
            ++ ;
            ????????}
            ????????return?
            * ( * it);
            ????}

            private :

            ????void?BeforeUpdate()?{

            ????}
            ????void?AfterUpdate()?{
            ????????
            if ?(m_DataSet.size())?{
            ????????????_DataSet::iterator?it;
            ????????????it?
            = ?m_DataSet.begin();
            ????????????
            while ?(it?! = ?m_DataSet.end())?{
            ????????????????
            if ?(( * it) -> m_en_State? == ?_DataRow::_en_Row_Add?||?( * it) -> m_en_State? == _DataRow::_en_Row_Update)?{
            ????????????????????(
            * it) -> m_en_State? = ?_DataRow::_en_Row_NoChange;
            ????????????????????it
            ++ ;
            ????????????????????continue;
            ????????????????}
            ????????????????
            // 更新成功,刪除條目
            ????????????????
            if ?(( * it) -> m_en_State? == ?_DataRow::_en_Row_Del)?{
            ????????????????????_DataSet::iterator?tt;
            ????????????????????tt?
            = ?it ++ ;
            ????????????????????m_DataSet.erase(tt);
            ????????????????????continue;
            ????????????????}
            ????????????????it
            ++ ;
            ????????????}
            ????????}
            ????}


            ????CString?MakeInsertSql(_DataRow
            & ?row)?{
            ????????CString?ret?
            = ?CString();
            ????????
            int ?i;
            ????????ret?
            = ? " INSERT?INTO? " ;
            ????????ret?
            += ?m_TableName.c_str();
            ????????ret?
            += ? " ?( " ;
            ????????
            for ?(i? = ? 0 ;?i? < ?en_field_count;?i ++ )?{
            ????????????
            if ?(i? > ? 0 )?{
            ????????????????ret?
            += ? " ,? " ;
            ????????????}
            ????????????ret?
            += ?m_FieldNames.at(i).m_FieldName.c_str();
            ????????}
            ????????ret?
            += ? " )?values?( " ;
            ????????ret?
            += ?_data_get < en_field_count > ::MakeFieldValue(row);
            ????????ret?
            += ? " ); " ;
            ????????return?ret;
            ????}
            ????BOOL?IsKeyField(
            int )?{
            ????????return?
            FALSE ;
            ????}

            ????CString?MakeUpdateSql(_DataRow
            & ?row)?{
            ????????CString?ret?
            = ?CString();
            ????????ret?
            = ? " UPDATE? " ;
            ????????ret?
            += ?m_TableName.c_str();
            ????????ret?
            += ? " ?SET? " ;
            ????????ret?
            += ?_data_get < en_field_count > ::MakeUpdateValue(row,?m_FieldNames,?m_TableName.c_str());
            ????????ret?
            += ? " ; " ;
            ????????return?ret;
            ????}

            ????CString?MakeDeleteSql(_DataRow
            & ?row)?{
            ????????CString?ret?
            = ?CString();
            ????????ret?
            = ? " Delete?*?from? " ;
            ????????ret?
            += ?m_TableName.c_str();
            ????????ret?
            += ? " ? " ;
            ????????ret?
            += ?_data_get < en_field_count > ::MakeDeleteValue(row,?m_FieldNames);
            ????????ret?
            += ? " ; " ;
            ????????return?ret;
            ????}
            public :
            ????void?Test()?{
            ????????_DataSet::iterator?it?
            = ?m_DataSet.begin();
            ????????MakeInsertSql(
            * ( * it));
            ????????MakeUpdateSql(
            * ( * it));
            ????????MakeDeleteSql(
            * ( * it));
            ????}

            private :

            ????BOOL?GetFieldName(CCom_Recordset
            & ?reset)?{
            ????????
            long ?fieldcount;
            ????????
            long ?i;
            ????????CComFields?lfields;
            ????????lfields?
            = ?reset -> GetFields();
            ????????fieldcount?
            = ?lfields -> GetCount();
            ????????m_FieldNames.clear();
            ????????
            for (i? = 0 ;?i? < ?fieldcount;?i ++ )?{
            ????????????CComField?lf;
            ????????????lf?
            = ?lfields -> GetItem(_variant_t(i));
            ????????????_bstr_t?fname?
            = ?lf -> Name;
            ????????????CString?fieldname??
            = ?fname.operator?char * ();
            ????????????m_FieldNames.push_back(__tagFieldInfo(std::
            string (LPCTSTR(fieldname)),?lf -> Type));
            ????????????TRACE(
            " fieldname?%s\n " ,?fieldname);
            ????????}
            ????????return?
            TRUE ;
            ????}

            ????virtual?BOOL?Save()?{
            ????????BOOL?ret?
            = ? FALSE ;
            ????????
            for (_DataSet::iterator?it? = ?m_DataSet.begin();?it?! = ?m_DataSet.end();?it ++ )?{
            ????????}
            ????????return?ret;
            ????}

            ????BOOL?InsertRow()?{
            ????????return?
            0 ;
            ????}

            ????BOOL?DeleteRow()?{
            ????????return?
            0 ;
            ????}

            ????BOOL?UpdateRow()?{
            ????????return?
            0 ;
            ????}

            public :
            ????void?SetTableName(LPCTSTR?table_name)?{
            ????????m_TableName?
            = ?table_name;
            ????}

            ????void?SetKey(
            int ?index)?{
            ????????m_FieldNames.at(index).m_KeyField?
            = ? TRUE ;
            ????}

            ????void?SetKey(
            int ?id1,? int ?id2)?{
            ????????m_FieldNames.at(id1).m_KeyField?
            = ? TRUE ;
            ????????m_FieldNames.at(id2).m_KeyField?
            = ? TRUE ;
            ????}

            ????void?Clear()?{
            ????????
            if ?(m_DataSet.size())?{
            ????????????_DataSet::iterator?it;
            ????????????
            for ?(it? = ?m_DataSet.begin();?it?! = ?m_DataSet.end();?it ++ )?{
            ????????????????delete?
            * it;
            ????????????}
            ????????????m_DataSet.clear();
            ????????}
            ????}

            ????void?SetModified()?{
            ????????m_Modified?
            = ? true ;
            ????}

            ????bool?GetModified()?{
            ????????return?m_Modified;
            ????}


            public :
            ????data_op_recordset()?:?m_Modified(
            false )?{}
            ????~data_op_recordset()?{
            ????????Clear();
            ????}
            protected:
            private :
            ????_DataSet?m_DataSet;
            ????_FieldNames?m_FieldNames;
            ????std::
            string ?m_TableName;
            ????bool?m_Modified;
            };


            例子代碼在:

            http://www.shnenglu.com/Files/hdqqq/ado_template.rar

            在其中實現了表格數據顯示,添加記錄和一個跨表數據查詢結果的顯示.

            vc 6 工程, 編譯需要loki 和boost 庫支持.

            過完春節以后,很多事情,一直沒有時間寫東西,這次把基于模板的數據操作類寫完,總算是對自己有個交待.


            ?

            posted on 2007-03-26 11:18 hdqqq 閱讀(1395) 評論(3)  編輯 收藏 引用 所屬分類: c/c++

            評論

            # re: 創建一個基于模板的數據庫記錄集操作類(四) 2007-08-02 10:52 bbp
            想說的是,你的代碼依賴于Windows平臺,不好!  回復  更多評論
              

            # re: 創建一個基于模板的數據庫記錄集操作類(四)[未登錄] 2007-08-28 09:16 hdqqq
            跨平臺的數據庫操作接口,比較難實現.  回復  更多評論
              

            # re: 創建一個基于模板的數據庫記錄集操作類(四) 2008-09-22 10:40 Arcol
            沒看你文章之前,我也寫了一份類似的用模板封裝數據庫ADO接口,同樣是基于TypeList思想實現的,感覺很有意思,親自寫過一次才知道難度有多大

            另外,要駁一下上面的回帖,跨平臺的不一定就是好東西,本來封裝的就是ado數據庫接口,是否跨平臺已經沒多大意義了  回復  更多評論
              

            国产高潮国产高潮久久久| 97久久国产综合精品女不卡| 久久99国产乱子伦精品免费| 2020最新久久久视精品爱| 久久不射电影网| 久久久高清免费视频| 91精品国产综合久久久久久| 久久亚洲色一区二区三区| 国产精品国色综合久久| 久久人妻AV中文字幕| 精品久久久久久无码国产| 国产精品一区二区久久不卡| 精品一久久香蕉国产线看播放 | 国产精品99久久久精品无码| 大伊人青草狠狠久久| 国内精品人妻无码久久久影院导航 | 国产精品一区二区久久精品无码| 狠狠色婷婷久久综合频道日韩| 久久久WWW成人免费精品| 欧美va久久久噜噜噜久久| 久久综合九色综合网站| 婷婷久久综合九色综合绿巨人| 久久精品九九亚洲精品天堂| 亚洲av伊人久久综合密臀性色| 精品国产VA久久久久久久冰| 中文字幕久久精品无码| 精品久久久无码21p发布| 精品蜜臀久久久久99网站| 国内精品久久久久久久影视麻豆| 久久久久久国产精品美女| 久久成人小视频| 国产精品美女久久久免费| 国产成人久久精品二区三区| 国产精品久久久香蕉| 久久免费小视频| 99久久精品午夜一区二区| 久久精品国产99久久久古代| 久久久久久狠狠丁香| 久久久一本精品99久久精品88| 午夜精品久久久久久影视777| 久久精品蜜芽亚洲国产AV|