• <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++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
              35 隨筆 :: 0 文章 :: 104 評論 :: 0 Trackbacks
            ?????? 上一篇講到了根據(jù)一個(gè)typelist實(shí)現(xiàn)一個(gè)結(jié)構(gòu),這個(gè)結(jié)構(gòu)帶有typelist中所有類型的成員,同時(shí),可以通過Field0,Field1等接口訪問和賦值.在這個(gè)基礎(chǔ)上,我們可以構(gòu)建對應(yīng)一條記錄的結(jié)構(gòu)data_row,

            二.一條記錄

            #define?ROW_NO_CHANGE?0
            #define?ROW_ADD?
            1
            #define?ROW_UPDATE?
            2
            #define?ROW_DELETE?
            3

            template
            <typename?_tlist>
            class?data_op_record_row?:?
            public?struct_mem<_tlist>
            {
            public:
            ????enum?_enum_RowState?{
            ????????_en_Row_NoChange?
            =?ROW_NO_CHANGE,????//未修改
            ????????_en_Row_Add?
            =?ROW_ADD,????????????//新增記錄
            ????????_en_Row_Update?
            =?ROW_UPDATE,????????//更新
            ????????_en_Row_Del?
            =?ROW_DELETE,????????//刪除
            ????}?m_en_State;
            public:
            ????void?SetState(
            int?newstate)?{
            ????????
            if?(m_en_State?!=?newstate)?{
            ????????????
            if?(newstate?==?_en_Row_NoChange?||?
            ????????????????newstate?
            ==?_en_Row_Add?||?
            ????????????????newstate?
            ==?_en_Row_Update?||?
            ????????????????newstate?
            ==?_en_Row_Del)?
            ????????????{
            ????????????????m_en_State?
            =?(_enum_RowState)newstate;
            ????????????}
            ????????}
            ????}
            public:
            ????data_op_record_row?()?:?m_en_State(_en_Row_NoChange)?{}
            ????~data_op_record_row?(){}
            protected:
            private:
            };
            上面的類增加了一個(gè)枚舉,標(biāo)識這條記錄當(dāng)前的狀態(tài),在記錄集中,將根據(jù)記錄的狀態(tài)進(jìn)行相關(guān)的操作.這個(gè)其實(shí)類似與.net中的DataRow,不過.net中的DataRow可以用wizzard生成需要的類,而這里是用模板生成的.

            三.數(shù)據(jù)類型轉(zhuǎn)換
            ????? 數(shù)據(jù)庫中的表對應(yīng)的字段有不同的數(shù)據(jù)類型,ADO操作接口中用不同的數(shù)據(jù)類型與之對應(yīng),其中Field接口的GetType就是返回字段類型的,但是ADO的GetValue返回的是_variant_t類型,為了實(shí)際業(yè)務(wù)的需要,還需要轉(zhuǎn)換成不同的類型,因此,需要對_variant_t類型進(jìn)行轉(zhuǎn)換.為此需要提供模板轉(zhuǎn)換函數(shù)

            template?<typename?_type>
            void?DbData_Change(_type
            &?ret,?_variant_t&?field)
            {
            ???AfxMessageBox(
            "未定義的數(shù)據(jù)轉(zhuǎn)換");
            }


            template?
            <>
            void?DbData_Change
            <int>(int?&?ret,?_variant_t&?field)
            {
            ????ret?
            =?field.lVal;
            }

            template?
            <>
            void?DbData_Change
            <std::string>(std::string&?ret,?_variant_t&?field)
            {
            ????_bstr_t?temp;

            ????
            if?(field.vt?!=?VT_NULL)?{
            ????????temp?
            =?field.bstrVal;
            ????????ret?
            =?temp.operator?const?char*();
            ????}
            }

            template?
            <>
            void?DbData_Change
            <bool>(bool&?ret,?_variant_t&?field)
            {
            ????ret?
            =?(field.boolVal?==?(short)0xFFFF???TRUE?:?FALSE);
            }

            template?
            <>
            void?DbData_Change
            <double>(double&?ret,?_variant_t&?field)
            {
            ????
            if?(field.vt?!=?VT_NULL)?{
            ????????
            //ret?=?field.cyVal;
            ????????ret?
            =?field.dblVal;
            ????}
            else?{
            ????????ret?
            =?0;
            ????}
            }

            上面的模板函數(shù)的功能是從_variant_t轉(zhuǎn)換到某中數(shù)據(jù)類型,對于其它類型還可以進(jìn)行擴(kuò)充,對于沒有進(jìn)行特化的函數(shù),編譯器會(huì)使用缺省模板,在運(yùn)行時(shí)候就會(huì)出現(xiàn)提示.有了上面的函數(shù),現(xiàn)在我們需要一個(gè)數(shù)據(jù)類型的封裝類,使得被封裝的類型可以自動(dòng)進(jìn)行從_variant_t類型的需要類型的轉(zhuǎn)換,所以有了下面的封裝類.
            //數(shù)據(jù)庫數(shù)據(jù)類型封裝
            template?
            <typename?_type>
            class?_db_data_wrapper
            {
            public:
            ????_type
            &?Value()?{
            ????????return?m_Data;
            ????}

            ????
            const?_type&?operator?=(const?_type&?value)?{
            ????????m_Data?
            =?value;
            ????????return?value;
            ????}

            ????_db_data_wrapper
            &?operator?=?(const?_db_data_wrapper&?other)?{
            ????????
            if?(this?!=?&other)?{
            ????????????m_Data?
            =?other.m_Data;
            ????????}
            ????????return?
            *this;
            ????}

            public:
            ????virtual?void?GetDbValue(_variant_t
            &?field_value)?{
            ????????DbData_Change(m_Data,?field_value);
            ????}

            public:
            ????_db_data_wrapper(){}
            ????_db_data_wrapper(
            const?_type&?value)?:?m_Data(value)?{}
            ????~_db_data_wrapper(){}
            private:
            ????_type?m_Data;
            };

            typedef?_db_data_wrapper
            <?int?>?DB_INT;
            typedef?_db_data_wrapper
            <?std::string?>?DB_STRING;
            typedef?_db_data_wrapper
            <?bool?>?DB_BOOL;
            typedef?_db_data_wrapper
            <?double?>?DB_DOUBLE;



            上面的代碼預(yù)定義了幾種常用的數(shù)據(jù)類型,這個(gè)數(shù)據(jù)的封裝類支持 = 操作符,因此可以直接用被封裝的數(shù)據(jù)對其賦值.象下面
            int?i?=?4;
            DB_INT?di;
            di?
            =?i;
            i?
            =?di.Value();


            同時(shí)通過成員函數(shù)GetDbValue(_variant_t& field_value), 支持從_variant_t轉(zhuǎn)換為自身封裝的類型.

            現(xiàn)在,可以用上面的數(shù)據(jù)類型構(gòu)建記錄結(jié)構(gòu)了

            typedef data_op_record_row< TYPELIST_2(DB_INT,DB_STRING) > my_DataRow;

            在上面的my_DataRow類型中,有兩個(gè)成員Field0, Field1,類型分別為 DB_INT,DB_STRING, 支持_variant_t類型轉(zhuǎn)換.

            當(dāng)然,用wrapper對數(shù)據(jù)進(jìn)行封裝在實(shí)際的使用中畢竟有些麻煩, 如數(shù)據(jù)必須通過 Value() 函數(shù)來取得,如果直接使用象 int, std::string 等類型作為 記錄結(jié)構(gòu)的成員,也可以實(shí)現(xiàn)_variant自動(dòng)轉(zhuǎn)換,但是需要在上一層的記錄集類中加入相關(guān)的轉(zhuǎn)換操作,實(shí)現(xiàn)起來比較麻煩,所以我這里選擇了對數(shù)據(jù)進(jìn)行封裝.


            ?

            posted on 2007-01-22 17:33 hdqqq 閱讀(1243) 評論(1)  編輯 收藏 引用 所屬分類: c/c++

            評論

            # re: 創(chuàng)建一個(gè)基于模板的數(shù)據(jù)庫記錄集操作類(二) 2007-01-24 09:44 天下無雙
            看到模板,我就有些不明白了。  回復(fù)  更多評論
              

            久久99热这里只有精品66| 久久亚洲中文字幕精品有坂深雪| 国产精品无码久久综合网| 久久久久国产成人精品亚洲午夜| 亚洲伊人久久成综合人影院| 欧美噜噜久久久XXX| 国产精品久久久天天影视香蕉 | 久久青青草原精品国产软件| 亚洲精品国产第一综合99久久| 人妻精品久久无码区| 久久综合九色欧美综合狠狠| 国产精品美女久久久久 | 亚洲中文字幕久久精品无码喷水| 69久久精品无码一区二区| 国产精品久久久久久五月尺| 久久中文娱乐网| 国产成年无码久久久久毛片| 久久精品中文字幕大胸| 国内精品欧美久久精品| 国产精品久久久久AV福利动漫 | 国产91久久精品一区二区| 国产精品99久久久久久宅男小说 | 人妻无码αv中文字幕久久琪琪布| 久久夜色精品国产www| 香港aa三级久久三级| 久久99精品久久久久久hb无码| 狠狠色狠狠色综合久久| 欧美精品九九99久久在观看| 久久亚洲国产精品123区| 久久久艹| 亚洲AV伊人久久青青草原| 久久青青草原亚洲av无码| 久久精品亚洲乱码伦伦中文| 日日躁夜夜躁狠狠久久AV| 丁香五月综合久久激情| 精品久久久久久| 久久国产热精品波多野结衣AV| 99久久国产精品免费一区二区 | 久久综合九色综合网站| 婷婷综合久久中文字幕蜜桃三电影 | 精品国产一区二区三区久久|