国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

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

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://m.survivalescaperooms.com/jeffwongishandsome/


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 凯里市| 安塞县| 宁南县| 固阳县| 轮台县| 凤翔县| 颍上县| 麻江县| 洛浦县| 邻水| 富裕县| 温州市| 土默特左旗| 临夏市| 岢岚县| 二手房| 错那县| 新建县| 赞皇县| 洪雅县| 洮南市| 邻水| 昌都县| 吉木萨尔县| 徐州市| 临洮县| 子洲县| 汽车| 民和| 鹤庆县| 安乡县| 丹江口市| 威海市| 阿巴嘎旗| 鄂托克旗| 两当县| 江西省| 壤塘县| 清新县| 牟定县| 南乐县|