亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

ado.net快速上手疑問及解答(完結篇)

2019-11-17 03:48:04
字體:
來源:轉載
供稿:網友

樓豬上周周末偶而有感而發(也就是ado.net快速上手實踐篇(一)(二) ),想不到收到三位童鞋的郵件,提出了他們的疑問,并指出樓豬在源碼中存在的問題。非常感謝他們的細心和認真的態度,在這里抱住鳴謝一下。下面,樓豬就把童鞋們發現的問題和提出的疑問一并整理,統一回復一下,草草落筆,恐怕還有訛誤,請注意甄別。
一、代碼中的問題
1、偽SqlMapper的基類為什么用抽象類BaseSqlMapper而不用接口?
答:樓豬也知道在IBatis下的SqlMapper的基類就是一個接口ISqlMapper,但是樓豬寫代碼的時候,發現泛型約束在抽象基類里寫一次,在SqlMapper下就不要再寫了,而用接口就必須寫兩遍約束。呵呵,一時偷懶的后果,沒有深刻意識到“針對接口編程”這一條常識,提出這個問題的童鞋明顯可以看出技高樓豬一籌啊,,哈哈,樓豬吸取這個教訓了,本文最后的demo樓豬將BaseSqlMapper統一換成了ISqlMapper接口,請留意。
2、在前臺頁面里面寫SQL語句太多,是不是不太好?
這個問題也很好。在實際的項目中,SQL語句通常都寫在具體的Dao文件中,比如前文demo中提到的PersonDao類。我們在添加一個Person的時候,示例中是通過view plaincopy to clipboardPRint?
public int Insert(string sqlInsert) 

public int Insert(string sqlInsert)
這種形式的方法執行插入的,但是在實際項目中的時候,我們通常都會寫view plaincopy to clipboardprint?
public int Insert(Person model) 

public int Insert(Person model)
這種類型的方法執行數據庫插入操作。所以在前臺(表現層)寫SQL語句其實是不合理的。再次多多感謝指出代碼問題的童鞋們。如果已經對某些新手造成某些誤導,樓豬在這里要深刻反省和檢討(demo寫的明顯有點隨意和偷懶),在這里,樓豬鄭重提醒,SQL語句的位置請不要模仿demo中這種糟糕的寫法,樓豬也是過來人,因為使用Batis.net的時候都是放在Dal層xml下的,請務必重視起來。

二、疑問(直接摘錄郵件內容)
1、“數據庫切換貌似沒有是吧.怎樣切換MSSQL。ACC,XML等等呢”?
答:這個應該是說源碼對多種數據庫的支持問題。哦,樓豬還沒有實現??丛创a,Sql Server簡單的基本的CRUD功能已經支持了。如果要擴展支持其他數據庫,模仿SqlServer類里的具體實現即可。樓豬的機器環境上沒有安裝Oracle或者MySQL等數據庫,所以寫完了也不好測試。您如果條件具備,自己可以試著完成它。至于說數據庫的切換,理想狀態的實現莫過于最經典的抽象工廠模式,呵呵,配置文件配合反射就行了。但是樓豬建議您簡單使用偽SqlMapper進行數據庫類型切換。具體操作,其實只要在配置文件appsetting中加一個數據庫類型節點sqlType,配合類里的常用數據庫類型的枚舉即可。

  <appSettings>
    <add key="db_timeOut" value="5000"/>
    <!--數據庫類型 0 SqlServer 1 Orcale 2 MySql-->
    <add key="sqlType" value="0"/>
  </appSettings>
枚舉如下:

代碼
namespace AdoNetDataaccess.Mapper
{
        public enum SqlEnum
        {
            Default = 0,
            SQLServer = 0,
            Oracle = 1,
            MySql = 1
        }
}

然后,就是一些實例化SqlMapper的過程判斷了,將數據庫切換的問題完全轉移到實例化SqlMapper上來:

代碼
using System;
using System.Collections.Generic;
using System.Configuration;

namespace AdoNetDataAccess.Mapper
{
    using AdoNetDataAccess.Core.Contract;
    using AdoNetDataAccess.Core.Implement;

    #region enum

    public enum SqlEnum
    {
        Default = 0,
        SQLServer = 0,
        Oracle = 1,
        MySql = 1
    }

    #endregion

    public sealed class MapperUtill
    {

        #region fields

        public static string currentSqlKey = "sqlConn";

        public static int cmdTimeOut = 15;

        private static int sqlType = 0;//數據庫類型 0 SqlServer 1 Orcale 2 MySql

        private static readonly object objSync = new object();

        private static readonly IDictionary<string, ISqlMapper> dictMappers = new Dictionary<string, ISqlMapper>();

        #endregion

        #region constructor and methods

        private MapperUtill()
        {

        }

        static MapperUtill()
        {
            try
            {
                cmdTimeOut = int.Parse(ConfigurationManager.AppSettings["db_timeOut"]);
            }
            catch
            {
                cmdTimeOut = 15;
            }
            try
            {
                sqlType = int.Parse(ConfigurationManager.AppSettings["sqlType"]);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            //實例化SqlDbMapper
            for (int i = 0; i < ConfigurationManager.ConnectionStrings.Count; i++)
            {
                string key = ConfigurationManager.ConnectionStrings[i].Name;
                string value = ConfigurationManager.ConnectionStrings[i].ConnectionString;
                CreateMapper(key, value, cmdTimeOut);
            }
        }

        public static ISqlMapper GetSqlMapper(string key)
        {
            return MapperUtill.GetMapper(key);
        }

        public static ISqlMapper GetCurrentSqlMapper()
        {
            return MapperUtill.GetMapper(currentSqlKey);
        }

        public static void CreateMapper(string connKey, string sqlConStr, int connTimeOut)
        {
            IDbOperation operation = null;
            switch (sqlType)
            {
                default:
                case 0:
                    operation = new SqlServer(sqlConStr, connTimeOut);
                    break;
                case 1:
                    //operation = new Orcale(sqlConStr, connTimeOut);//Orcale 未實現
                    break;
                case 2:
                    //operation = new MySql(sqlConStr, connTimeOut);//MySql 也沒有實現呢
                    break;
            }
            if (operation == null)
            {
                throw new Exception("您配置的數據庫類型有可能那啥出問題了");
            }
            SqlMapper mapper = new SqlMapper(operation);
            dictMappers.Add(connKey.ToUpper().Trim(), mapper);//不區分大小寫
        }

        public static ISqlMapper GetMapper(string sqlConKey)
        {
            if (string.IsNullOrEmpty(sqlConKey))
            {
                throw new Exception("數據庫連接字符串主鍵為空!");
            }
            sqlConKey = sqlConKey.ToUpper();//不區分大小寫
            ISqlMapper mapper = null;
            if (dictMappers.ContainsKey(sqlConKey))
            {
                mapper = dictMappers[sqlConKey];
            }
            else
            {
                throw new Exception(string.Format("沒有{0}所對應的數據庫連接", sqlConKey));
            }
            return mapper;
        }

        /// <summary>
        /// 釋放所有
        /// </summary>
        public void Release()
        {
            foreach (KeyValuePair<string, ISqlMapper> kv in dictMappers)
            {
                SqlMapper mapper = kv.Value as SqlMapper;
                if (mapper == null)
                {
                    continue;
                }
                mapper.CurrentDbOperation.CloseConnection();
            }
            dictMappers.Clear();
        }

        #endregion

    }
}

必須要注意,這里的數據庫切換方式不是絕對的,您可以按照自己喜歡的習慣的其他方式編程完成切換,樓豬這里只是拋磚而已。
2、“我對ORM不熟悉,想問下您的這個ORM到底是節省了哪部分工作? 我看里面有大量的反射,這樣是不是非常影響效率?”
首先,樓豬對ORM也不太熟悉?,F在實現的這個嚴格來說也根本談不上算是ORM,但是有樓豬自己使用過的兩個ORM的影子。
其次,當前實現的東東不是為了節省哪部分工作而設計的,樓豬的初衷是重讀ado.net經典紅皮書而做的復習筆記。
第三,反射相對于沒有使用反射,當然非常影響效率。需要說明的是,要不要使用反射應該根據實際的項目需要。根據樓豬個人開發經驗,對于大多數程序員要實現的簡單的常見的前后臺mis系統,在保證基本需求的情況下,客戶如果對效率沒有意見,用用沒有太大關系,大部分工作就交給服務器完成去吧,程序員不用做太多工作。但是對于訪問頻繁的大型網站,實時系統或者應對大數據量操作的系統等等,建議不要使用反射,而且可能要重點花精力在數據“裝潢”上面。
最后,如果有童鞋對ORM感興趣,不妨在網上搜搜大牛們的作品,大名鼎鼎的NHibernate,iBatis.net,WebSharp,LINQ等等(這么多ORM,一個一個都要熟悉,源碼也研究不過來啊,建議新手熟練一兩種足矣),也許對您有更多的啟發。如果您自己實現了類似其他流行ORM的主流功能(如自動生成SQL語句或者通過XML配置,緩存,延遲加載等等),并且功能更加強大,用起來更加順手方便的新ORM,呵呵,真誠期待您的功德圓滿那一天早日到來,快點來造福萬千程序員吧。

稍作改進后的demo下載:demo

作者:Jeff Wong
出處:http://www.49028c.com/jeffwongishandsome/


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美性xxxx极品高清hd直播| 久久久久久久亚洲精品| 日本成人黄色片| 欧美在线视频观看免费网站| 91中文字幕一区| 国产精品网站视频| 久久亚洲精品小早川怜子66| 91色视频在线观看| 亚洲精品视频播放| 久久的精品视频| 日韩欧美在线观看视频| 日韩精品中文字幕视频在线| 亚洲视频综合网| 亚洲男人的天堂在线播放| 欧美日韩国产综合视频在线观看中文| 国内免费久久久久久久久久久| 欧美日韩中文字幕在线视频| 亚洲精品久久久久久久久| 欧美极品xxxx| 欧美亚洲在线观看| 国产69精品久久久久久| 91av视频在线观看| 久久久久久国产精品三级玉女聊斋| 日韩电影免费观看在线| 亚洲a∨日韩av高清在线观看| 国产精品mp4| 亚洲人成伊人成综合网久久久| 青青久久aⅴ北条麻妃| 九九久久精品一区| 久久成人精品视频| 亚洲二区在线播放视频| 国产精品久久久av| 欧美激情按摩在线| 欧美成人一区在线| 成人黄色短视频在线观看| 一个人看的www久久| 国产69精品久久久久久| 69视频在线播放| 日本中文字幕成人| 91精品久久久久久久久久久| 成人情趣片在线观看免费| 国产精品99久久久久久人| 亚洲欧美精品中文字幕在线| 久久久久久久色| 91精品中国老女人| 91精品久久久久久久久久| 日韩极品精品视频免费观看| 91丨九色丨国产在线| 国产精品久久久久久av| 国产一区二区三区丝袜| 国产精国产精品| 亚洲成人aaa| 欧美巨大黑人极品精男| 欧美激情一二三| 国产视频自拍一区| 亚洲xxx大片| 国产精品久久久久久久久久久不卡| 久久精彩免费视频| 欧美精品一区三区| 国产精品爽黄69| 久久在线精品视频| 国产精品aaa| 成人黄色网免费| 欧美另类极品videosbestfree| 欧美精品电影在线| 亚洲精品98久久久久久中文字幕| 久久久久久亚洲| 中文字幕亚洲二区| 欧美成人免费va影院高清| www.亚洲成人| 狠狠躁夜夜躁人人躁婷婷91| 国产精品人成电影在线观看| 亚洲国产成人久久综合| 色视频www在线播放国产成人| 亚洲精选一区二区| 日韩美女免费视频| 亚洲欧美日韩中文视频| 亚洲视频网站在线观看| 亚洲精选一区二区| 中文字幕在线精品| 欧美网站在线观看| 国产精品va在线| 欧美精品一本久久男人的天堂| 国产精品一区二区久久| 亚洲一区精品电影| www.日韩不卡电影av| 欧美日本在线视频中文字字幕| 国产免费亚洲高清| 亚洲毛片一区二区| 国产精品成av人在线视午夜片| 日韩精品亚洲视频| 日韩一区二区久久久| 欧美一级免费视频| 国产在线999| 国产精品久久久av久久久| 久久久久久久久久久网站| 欧美理论电影在线播放| 亚洲第一视频网站| 国产盗摄xxxx视频xxx69| 自拍偷拍亚洲区| 午夜精品理论片| 91久久久久久久久久| 91人人爽人人爽人人精88v| 美女视频黄免费的亚洲男人天堂| 国产精品扒开腿做爽爽爽的视频| 91亚洲精品一区| 国产精品网站大全| 日韩欧美视频一区二区三区| 亚洲精品美女在线观看| 亚洲伊人一本大道中文字幕| 国语自产偷拍精品视频偷| 永久免费毛片在线播放不卡| 91久久中文字幕| 精品国产999| 91在线观看免费观看| 亚洲欧美制服另类日韩| 亚洲精品成人久久| 91色在线视频| 成人在线免费观看视视频| 久久精品国产视频| 亚洲欧美日韩另类| 亚洲japanese制服美女| 日韩av大片在线| 久久影视电视剧免费网站| 国产精品亚洲美女av网站| 亚洲人成绝费网站色www| 岛国av一区二区三区| 97免费中文视频在线观看| 亚洲性无码av在线| 91精品国产免费久久久久久| 亚洲护士老师的毛茸茸最新章节| 69av在线播放| 亚洲新声在线观看| 色综合男人天堂| 爽爽爽爽爽爽爽成人免费观看| 亚洲国产精品成人av| 91国产在线精品| 国产精品福利无圣光在线一区| 欧美日韩国产一区中文午夜| 一区二区欧美久久| 欧美另类极品videosbest最新版本| 日韩欧美成人精品| 91黑丝在线观看| 亚洲香蕉成人av网站在线观看| 欧美大片第1页| 96国产粉嫩美女| 国产精品18久久久久久麻辣| 亚洲激情 国产| 亚洲成人性视频| 亚洲男人天堂手机在线| 欧美亚洲另类视频| 国产精品27p| 亚洲精品免费av| 国产精品一二区| 91久久精品国产91性色| 国产一区二区三区在线看| 欧美激情精品久久久久| 国内精品小视频| 91在线视频导航| 久久精品一偷一偷国产| 欧美一级淫片播放口| 日韩在线视频网站| 国内久久久精品| 黑人与娇小精品av专区|