色尼玛亚洲综合影院,亚洲3atv精品一区二区三区,麻豆freexxxx性91精品,欧美在线91

Step by Step-構(gòu)建自己的ORM系列-數(shù)據(jù)訪問層

一、開篇

         距離上篇《Step by Step-構(gòu)建自己的ORM系列-開篇》的時間間隔的太久了,很對不住大家啊,主要是因為有幾個系列必須提前先寫完,才能繼續(xù)這個系列,當(dāng)然我也在

寫這幾個系列的過程中,對ORM這個系列中的原來的實現(xiàn)的想法有了新的認(rèn)識和改進,當(dāng)然這些都不是說是很先進的思想或者認(rèn)識,也可能是大家見過的思路吧,希望后面我能在

寫設(shè)計模式系列的過程中,穿插講解ORM系列,當(dāng)然我的這個構(gòu)建的系列,也只能說是很簡易的,自己平時開發(fā)個小應(yīng)用工具或者什么的,可能用他,因為是自己開發(fā)的嘛,畢竟

使用起來還是比較順手的!符合自己的操作習(xí)慣嘛。

        當(dāng)然我寫這個系列的過程中,也會有自己認(rèn)識偏激的地方,或者思路不正確的地方,還請大伙多多指出和批評。我也是在我目前的項目中學(xué)習(xí)到了很多的寶貴的經(jīng)驗,其實

我們應(yīng)該能看到ORM給我們提供的方便和不便之處,我們?nèi)∑渚A,剔除糟粕,不過這真的很難。我其實對一些流行的ORM的底層實現(xiàn),研究的不多也不深,像Nhibernate,我

只是了解Hibernate,是當(dāng)時從Java中了解過來的,不深入,Castle框架倒是用過一段時間,EntityFreamWork,我也沒有用過,只是象征性的下載最新版本,體驗了下AOP的

方式,我感覺其實有很多的時候,我們使用AOP的方式,能夠改進我們程序的靈活性。這塊可能還需要大牛們多多指點。

        我理想的ORM是實現(xiàn)持久化的透明,這個怎么理解呢?就是說我在程序的開發(fā)中,我不想在業(yè)務(wù)代碼中書寫相應(yīng)的持久化操作,也不關(guān)心業(yè)務(wù)層中的去如何調(diào)用你的

ORM,去完成CRUD的操作。我只關(guān)心我的業(yè)務(wù)邏輯,這個有點像DDD(領(lǐng)域驅(qū)動開發(fā))里面的領(lǐng)域?qū)恿耍魂P(guān)心領(lǐng)域內(nèi)部的業(yè)務(wù)邏輯,而不關(guān)心其他的東西,這樣方便我們快速

的抓住關(guān)注的東西,而盡量讓與領(lǐng)域無關(guān)的東西不要影響業(yè)務(wù)領(lǐng)域邏輯的實現(xiàn)。

二、摘要

        本篇主要開始講述《Step by Step-構(gòu)建自己的ORM系列-數(shù)據(jù)訪問層》關(guān)于數(shù)據(jù)訪問層的部分,其實前面也對這塊的內(nèi)容有了一定的介紹了,其實本篇就是教你如何完成

ORM中的數(shù)據(jù)訪問層的操作,這里是提供統(tǒng)一的數(shù)據(jù)訪問方法的實現(xiàn)。當(dāng)然這里的操作還是主要集中在數(shù)據(jù)庫的操作,包括如何根據(jù)實體對象返回實體的列表,包括生成SQL語

句的幾類實現(xiàn),還包括一些實現(xiàn)后續(xù)的ORM的配置管理的維護,這里就是提供可視化的XML文件的配置,這個具體怎么來做呢?因為我們平時針對ORM的使用,都是直接修改

XML文件,我們可以提供一個可視化的界面,讓那個用戶配置這些相應(yīng)的設(shè)置。通過這些配置,我們可以實現(xiàn)數(shù)據(jù)庫的平滑的遷移,緩存應(yīng)用的配置,包括其他的一些相關(guān)設(shè)置信

息。總體來說這些操作都可以依托于,我們這里的數(shù)據(jù)訪問層來完成。

        我們來看看ORM中數(shù)據(jù)訪問層的重要作用和地位吧:

image

上圖我們知道,我們所有的相關(guān)功能的基礎(chǔ),都是基于數(shù)據(jù)訪問層來做的,所以我們處理好這個層的相關(guān)邏輯

后,后續(xù)的問題就會比較容易開展。下面我們就會針對這些疑問開始

一個個的解決我們的數(shù)據(jù)訪問層應(yīng)該提供的相關(guān)功能!大體的功能應(yīng)該有如下功能:

1、持久化的操作方法CUD。可以擴展提供創(chuàng)建表+其他的修改表等相關(guān)的自動腳本工具。提供持久化透明的方式。

2、提供緩存服務(wù),將對象的相應(yīng)映射信息緩存起來,這樣后續(xù)執(zhí)行生成語句等操作,效率上會是很大的提升。

3、我們在處理對象對于Update語句,應(yīng)該能處理好只能更變化的信息,如果沒有發(fā)生變化,那么我們是不是不用執(zhí)行更新操作了呢?減少數(shù)據(jù)庫的操作次數(shù)。

4、提供基礎(chǔ)的查詢方法,以后所有的基于ORM上的查詢基于這個查詢進行擴展。提供持久化透明的查詢方式。

5、并發(fā)和事務(wù)的控制。我們這里可能提供一個內(nèi)部的版本號的方式來做,一旦修改過這個對象或者發(fā)生改變,任何時候的操作,我們都是針對這個版本號的記錄來做的,版本號

通過內(nèi)部提供的方法來進行。

三、本文大綱

       1、開篇。

       2、摘要。

       3、本文大綱。

       4、ORM之?dāng)?shù)據(jù)訪問層分析。

       5、ORM相關(guān)代碼實現(xiàn)。

       6、本章總結(jié)。

       7、系列進度。

       8、下篇預(yù)告。

四、ORM之?dāng)?shù)據(jù)訪問層分析

        我們先來針對上面的幾個問題,我們給出實現(xiàn)思路,來分析下給出的思路的可行性和如何實現(xiàn)的解析。具體的代碼下節(jié)給出核心實現(xiàn)方案。

       4.1、提供通用的持久化的操作

        這個具體的解析在上篇中已經(jīng)給出了相應(yīng)的思路了,我們通過在底層提供相應(yīng)的方法來做。一般來說,對應(yīng)數(shù)據(jù)庫的四種操作,我們在數(shù)據(jù)訪問層,也提供了相應(yīng)的語句的

自動構(gòu)造的過程,具體的構(gòu)造,我們前面給出的實現(xiàn)方案是通過特性來實現(xiàn),特性中定義具體的數(shù)據(jù)庫字段,類型,長度等一些列的參數(shù)。我這里就不復(fù)述了,我這里分析下我們

這樣實現(xiàn)的好處。我們知道繼承的方式是挺好的,我為什么這么說,通過提供一個基類,基類中定義通用的CUD的操作方法,這樣只要是繼承這個類的子類,都會有CUD的操作

方法了,但是我們?yōu)榱颂峁┏志没该鞯姆桨福敲礋o疑,對于持久化的操作,我們就不希望由業(yè)務(wù)邏輯層中的業(yè)務(wù)邏輯對象來完成,那么如何來做呢?我們通過數(shù)據(jù)訪問層,提

供統(tǒng)一的操作方法,讓服務(wù)層來完成業(yè)務(wù)對象的持久化操作。這樣就能實現(xiàn),持久化透明的方案。

       所以我們可以這樣來做,在數(shù)據(jù)訪問層中,我們提供一個接口,接口中定義持久化操作的幾類方案,通過不同的實現(xiàn)配置,我們可以在XML配置文件中進行指定,我們采用

重量級的ORM還是輕量級的ORM,這樣我們也理想的實現(xiàn)了低耦合的特性。

       同時,對于不同的文件的操作,我們可以支持多文件類型的寫入,當(dāng)然對于不同的數(shù)據(jù)庫存儲,如果我們利用關(guān)系型數(shù)據(jù)庫我們需要ORM,對于對象數(shù)據(jù)庫的操作,或者

XML文件的操作,我們這時候的ORM就變了。

       4.2、提供緩存服務(wù)

         我們知道,我們第一篇中主要是通過自定義特性+反射的形式來處理:我們并沒有提供完整的特性操作,其實還有很多的情況,比如說,我們還可以提供對視圖的映射,提

供一個視圖的特性等。還有其他的特性有很多,后續(xù)會給出完整的代碼結(jié)構(gòu),我們知道自定義特性+反射,如果每次在將對象映射成數(shù)據(jù)庫表的時候,那么效率上是多么的低下

啊,那么這個時候,我們可以考慮使用緩存的方式,將數(shù)據(jù)庫表中的數(shù)據(jù)庫列與對象中的屬性列進行映射,我們可以把這些對應(yīng)關(guān)系放在緩存中,那么如果我們在后續(xù)的處理中遇

到與數(shù)據(jù)庫相關(guān)操作,需要進行對象映射的時候,我們都先會去緩存中查找有沒有指定鍵值的映射數(shù)據(jù)庫表列存在,存在取出生成SQL語句,否則通過反射取出對應(yīng)的數(shù)據(jù)庫表

列,放在緩存中。下面給出示意圖。將這個過程進行描述:

image

當(dāng)然我這里給出的肯定是反向的根據(jù)對象生成操作數(shù)據(jù)的SQL語句的方式。這里沒有考慮,當(dāng)數(shù)

據(jù)庫表發(fā)生變化的時候,我應(yīng)該自動同步緩存中的映射集合信息,當(dāng)然我們可以通過一定的策略,來實現(xiàn)這樣的雙向同步問題。例如如下的方式可能就是可行的方案。

image

通過上述的方式,我們通過同步組件,在每次進行數(shù)據(jù)操作之前,我們可以應(yīng)用更好的策略,比如記錄或者遍歷文件的修改狀態(tài),對比文件的最后修改日期,是不是發(fā)生修改,或者當(dāng)某個文件發(fā)生修

改之后,我們記錄在某個配置文件中,這樣我們可以提高同步的效率,因為通過這樣的方式,我們不需要每次檢查對象是不是發(fā)生變化了,這樣我們?nèi)绻l(fā)現(xiàn)對象沒有發(fā)生變化,

那么我們就不要讓同步組件去檢測對象是否發(fā)生變化,這樣就能提高效率,同時支持當(dāng)映射對象發(fā)生變化的時候,我們不用修改我們的關(guān)系數(shù)據(jù)庫。大家都知道,面向?qū)ο笤O(shè)計建

模與關(guān)系數(shù)據(jù)庫的最大難題就是雙方的變化的同步性的方案是很難定的,我這里只是給出一個簡單的思路和方式,可能還有更好的方案,也請大家多多告訴我。

      4.3、Update語句的操作

       我不知道,你們在面試的時候,如果你經(jīng)常開發(fā)底層的面向?qū)ο蟮腛RM的時候,應(yīng)該會遇到這樣的問題,我們在查詢一個映射對象的時候,我們可能只需要取出這個對象的

部分列,而不是全部的數(shù)據(jù)列,這個時候,我們?nèi)绾沃付兀烤褪翘畛鋵ο蟮臅r候,我們只需要填充指定的列?或者我們需要在在保存編輯的時候,我們不更新未發(fā)生變化的數(shù)據(jù)

庫,其實主要是要求,我們在生成SQL語句的時候,我們希望我們的更新語句中不要出現(xiàn),沒有發(fā)生變化的數(shù)據(jù)列的設(shè)置,這個如何做到呢?我想我們可以通過如下的2種方式來

做。

        1、通過對象的序列化,來復(fù)制一個對象,并且系統(tǒng)中緩存這個對象,在編輯之前,緩存,等到提交后,釋放這個對象。這個由系統(tǒng)默認(rèn)的提供方法。前提是標(biāo)記對象是編

輯狀態(tài),這樣在修改對象之前進行復(fù)制,不然如果修改完了,再復(fù)制就沒有什么意義了

        2、通過字典來保存更新數(shù)值的數(shù)據(jù)列,通過數(shù)據(jù)字典來存放。我們在字典中存放映射的數(shù)據(jù)列,將發(fā)生變化的數(shù)據(jù)列和數(shù)據(jù)列的值進行標(biāo)記發(fā)生改變,我們在生成更新語

句的時候。直接遍歷這個集合,將列狀態(tài)發(fā)生改變的列生成相應(yīng)的操作語句即可。這些都是可行的方式,我們在前面的架構(gòu)設(shè)計中也提到過的。都是給過思路的,這里我也不多復(fù)

述了。

        3、…。可能還有其他的更好的方式,還請大家多提出好的思路,我備注在這個位置!

       4.4、提供基礎(chǔ)的查詢方法。

        這里說的提供基礎(chǔ)的查詢方法,指的是基于數(shù)據(jù)庫操作之上,我們提供幾個常用的查詢方法,包括自動生成版本號的方法等,我們的版本號可以通過日期+流水號的形式來

生成,或者是其他的情況。GUID也是可行的辦法。不過維護起來可能不是很方便。所以底層提供相應(yīng)的操作方法更容易來做。

        我們這里考慮提供如下的基礎(chǔ)查詢方法,復(fù)雜的查詢方法,我們可以提供一個入口來做。例如我們提供如下幾類方法:

        1、底層生成版本號的方法,自增ID流水號,根據(jù)不同的生成規(guī)則自定義設(shè)置ID生成規(guī)則,來組織生成ID的通用方法。

        2、提供實體與數(shù)據(jù)庫行集之間的轉(zhuǎn)換,我們需要將數(shù)據(jù)庫記錄轉(zhuǎn)換為實體集合。通過查詢方法返回對象集合。這里提供返回指定主鍵的對象集合。

        3、返回一個數(shù)據(jù)表或者視圖中的所有記錄。

        4、返回傳入分頁個數(shù),和分頁排序字段,分頁條件的分頁集合。

        5、返回指定列的查詢方法。(這里沒有想到好的辦法,怎么樣的形式比較靈活能夠動態(tài)的指定返回的列,比如說1列,10列,5列等),希望大家提出好的意見和建議!

        6、提供統(tǒng)一的入口,編寫SQL語句傳入到數(shù)據(jù)訪問層中進行查詢和檢索,根據(jù)指定的返回類型來返回泛型對象。

        4.5、并發(fā)和事務(wù)控制

         我想一個系統(tǒng)中必須考慮的就是事務(wù)處理了,我們進行批量操作的時候,如果數(shù)據(jù)不同步,那就太痛苦了,也是不能使用的系統(tǒng)的,我們希望我們的ORM能夠自動的集成

事務(wù)和并發(fā),當(dāng)然這里說的并發(fā)是當(dāng)用戶數(shù)上升到一定量的時候,就會產(chǎn)生這樣的問題,理論上來說只要有2個以上的用戶,就必須考慮并發(fā)操作!并發(fā)我們有幾個控制的思路,

總體來說應(yīng)該說說我們前面的設(shè)計的內(nèi)部的一個自動生成的版本號,是最好的選擇。具體怎么個意思呢?我們來解釋下:

         對于并發(fā)控制,我們知道,并發(fā)控制的問題:寫丟失,讀出來的數(shù)據(jù)是臟數(shù)據(jù),無疑就是這么2個比較常見的問題,那么我們?nèi)绾蝸韺憗G失進行限制呢?目前通用的方案

都是通過樂觀鎖來處理,二個人可以同時對某個信息進行讀取,但是只能有一個人在進行編輯,但是最后修改的內(nèi)容會把前面修改的信息覆蓋掉,這是樂觀鎖的處理方式。

        悲觀鎖,則是只要有人在修改,那么可能你不能進行修改,也不能讀取,這種方式,當(dāng)然可以保證信息的修改的同步性和一致性,但是用戶的易用性和友好性方面不夠人性

化,相比來說,有人修改,就不能被其他人修改,但是可以讀取的方式體驗方面要差一些,不過各有使用的場景,一般來說,悲觀鎖是樂觀鎖的一個補充。

        我們這里既不是樂觀鎖,也不是悲觀鎖的形式,通過版本來對某個記錄的版本進行記錄,一旦發(fā)生改變,那么記錄的版本就要發(fā)生變化,我們這里對這個行集的版本的更新

可以通過ORM提供的版本的生成規(guī)則來生成一個版本號,或者是通過觸發(fā)器來實現(xiàn),當(dāng)然性能也是我們需要考慮的部分。

        對于事務(wù),我想一般的不是分布式操作的應(yīng)用,我們通過數(shù)據(jù)庫提供的本身的事務(wù)服務(wù)來完成,基本上就可以滿足日常的需求,也沒有什么特別難的地方,我想這里我也就

不詳細(xì)的說了,我們來簡單的說下,分布式事務(wù)的一致性,對于這種分布式的事務(wù)操作,我們可以采用離線并發(fā)模式來處理。這個怎么理解呢?就是通過工作單元來實現(xiàn)。我們把

每一個操作看著一個工作單元,如果我們在執(zhí)行某個事務(wù)操作的過程中,如果返回是0或者是其他的不是我們期望的結(jié)果時,我們不會進行任何的提交操作,如果全部執(zhí)行通過,

我們循環(huán)所有的工作單元進行提交,否則我們回滾所有的系統(tǒng)事務(wù)。我們把這樣的分布式事務(wù),看作一個業(yè)務(wù)事務(wù),由一些列的工作單元組成,這些工作單元看作是系統(tǒng)事務(wù)。

五、ORM相關(guān)代碼實現(xiàn)

         5.1、CUD的基本實現(xiàn)代碼:

           1,Create語句的實現(xiàn):

        private Dictionary<string, Column> _autoIncrementColumns = new Dictionary<string, Column>();
        private Dictionary<string, Column> _updateColumns = new Dictionary<string, Column>();

        public string TableName
        {
            get
            {
                return string.Empty;
            }
        }

        public Dictionary<string, Column> UpdateColumns
        {
            get
            {
                return this._updateColumns;
            }
            set
            {
                this._updateColumns = value;
            }
        }

        public Dictionary<string, Column> AutoIncrementColumns
        {
            get
            {
                return this._autoIncrementColumns;
            }
            set
            {
                this._autoIncrementColumns = value;
            }
        }

        public virtual IDbCommand GetDbCommand()
        {
            // 如果column的值沒有被更新過,則返回null
            if (this.UpdateColumns.Count == 0)
            {
                return null;
            }

            ArrayList fieldList = new ArrayList();
            ArrayList valueList = new ArrayList();
            SqlCommand cmd = new SqlCommand();

            foreach (Column column in this.UpdateColumns.Values)
            {
                fieldList.Add("[" + column.Key + "]");
                valueList.Add("@" + column.Value);
            }

            string fieldString = string.Join(" , ", (string[])fieldList.ToArray(typeof(string)));
            string valueString = string.Join(" , ", (string[])valueList.ToArray(typeof(string)));
            string cmdText = string.Format("INSERT INTO [{0}]({1}) VALUES({2})",
                this.TableName,
                fieldString,
                valueString);

            string sqlGetIndentityID = null;

            if (this.AutoIncrementColumns.Count == 1)
            {
                sqlGetIndentityID = string.Format("SELECT [{0}] = SCOPE_IDENTITY()");
            }

            if (sqlGetIndentityID != null)
            {
                cmdText = cmdText + " ; " + sqlGetIndentityID;
            }

            cmd.CommandText = cmdText;

            return cmd;

        }
    }

下面給出Update語句,是從上面的更新集合中編輯,將列的狀態(tài)發(fā)生改變的列添加生成到語句中-示例代碼如下:

        public virtual IDbCommand GetDbCommand()
        {
            // 如果column的值沒有被更新過,則返回null
            if (this.UpdateColumns.Count == 0)
            {
                return null;
            }

            ArrayList fieldList = new ArrayList();
            ArrayList valueList = new ArrayList();
            SqlCommand cmd = new SqlCommand();

            string updateSQL=string.Empty;
            foreach (Column column in this.UpdateColumns.Values)
            {
                if (column.State)
                    updateSQL += "[" + column.Key + "]=" + "@" + column.Value;
            }

           string cmdText=  string.Format("UPDATE {0} SET {1}={2}", updateSQL);

            cmd.CommandText = cmdText;

            return cmd;
        }

至于刪除的代碼比較簡單,我這里就不給出刪除的代碼了,總體來說形式是相同的。

             5.2、緩存服務(wù)代碼

        我有2篇關(guān)于緩存的介紹,緩存中最難搞的問題就是緩存的過期的問題,對應(yīng)反射的性能問題也是存在過期的問題,比如說我們的數(shù)據(jù)庫表發(fā)生變化,或者對象中的屬性發(fā)

生變化后,那么我們的緩存中的內(nèi)容也需要進行更新,不然我們生成的數(shù)據(jù)庫操作語句將會不正確。我們這里的策略就是將映射出來的對象,放在服務(wù)器中的緩存中,當(dāng)然對于

B/S和C/S系統(tǒng)中可能采取的緩存方式和策略還是有區(qū)別的。B/S我們的緩存可以采用緩存到服務(wù)器中,或者是通過緩存服務(wù)器來完成,一般是通過Remoting來將服務(wù)器與緩存

服務(wù)器完成通信。我們看看簡單的示例代碼吧:

   public class Cache
   {
       private static System.Web.Caching.Cache cache = HttpRuntime.Cache;//這里是默認(rèn)取當(dāng)前應(yīng)用程序的服務(wù)緩存。

       public static object Get(string key)
       {
           return cache[key];
       }

       public static bool Remove(string key)
       {
           return !(null == cache.Remove(key));
       }

       public static void Set(string key, object value)
       {
           cache.Insert(key, value, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(3));
       }
   }

上面給出的緩存類的示例代碼,具體的操作,使用反射后,將反射后對象元數(shù)據(jù)信息緩存起來,通過對象名來緩存:

具體代碼如下:

           PropertyInfo[] property = null;
            if (Cache.Get("") != null)
            {
                property = (PropertyInfo[])Cache.Get("");
            }
            else
            {
                Type t = Type.GetType("");

                property = t.GetProperties();
            }

通過上面的幾行簡單的代碼就能表達出我們上面講述的思路,具體如何過期,這個上面也給出了一些思路,可能大伙有更好的思路,我這里就不班門弄斧了。

      5.3,提供基礎(chǔ)的查詢服務(wù)

        我想大伙對于查詢語句的操作,應(yīng)該說是司空見慣了吧,我們?nèi)绾文芨玫耐瓿山y(tǒng)一的查詢服務(wù)可能是我們關(guān)心的問題,我這里不會給出多數(shù)據(jù)庫的實現(xiàn),但是可以給大伙

一個思路,我們這里定義返回的查詢命令的時候,如果說支持多數(shù)據(jù)的話,可以定義一個統(tǒng)一的接口,不同的數(shù)據(jù)庫提供不同的實現(xiàn)接口,然后根據(jù)統(tǒng)一的ORM配置來調(diào)用不同的

組件來生成SQL語句,完成調(diào)用操作。

        相關(guān)的查詢服務(wù)代碼如下:

       /// <summary>
       /// 系統(tǒng)自動生成的版本號
       /// </summary>
       /// <returns></returns>
       public string GetVersion()
       {
           return DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString() + DateTime.Now.Day.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString();
       }

       public int GetMax<T>()
       {
           //根據(jù)T的類型獲取T的最大列,完成查詢操作。
           string sqlText = " Select MAX(ISNULL(列名,0))+1 FROM TableName";

           return 0;
       }

       public List<T> GetAll<T>()
       {
           //根據(jù)T的類型獲取T的最大列,完成查詢操作。
           string sqlText = " Select *  FROM TableName";

           return new List<T>();
       }

       public List<T> GetList<T>(string condition,int pagesize,string orderField)
       {
           //根據(jù)T的類型獲取T的最大列,完成查詢操作。
           string sqlText = " Select *  FROM TableName where " + condition + " order by " + orderField;

           return new List<T>();
       }

      上面給出的不是全部的代碼,部分代碼還是大家自己去完成吧,我這里想的是,一些客戶比較復(fù)雜的自定義代碼通過一個接口傳入的形式,來完成基礎(chǔ)查詢服務(wù)的調(diào)用。

      我們這里給出通用的接口定義:

       CommandType CommandType
        {
            get;
            set;
        }

        string whereCondition
        {
            get;
            set;
        }

        string orderCondition
        {
            get;
            set;
        }

        string TableName
        {
            get;
            set;
        }

        Column[] ColumnList
        {
            get;
            set;
        }

        string SQL
        {
            get;
            set;
        }

                給出默認(rèn)幾類示例的實現(xiàn):

    public class BaseSQL : ISelect
    {
        public System.Data.CommandType CommandType
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public string whereCondition
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public string orderCondition
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public string TableName
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public Column[] ColumnList
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public string SQL
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        具體調(diào)用的代碼如下:

   public class SpecialSQL : BaseSQL
    {
        public void Test()
        {
            this.TableName = "";
            this.SQL = " SELECT * FROM TEST ";
            this.whereCondition = " ID=4 ";
            this.orderCondition = " ORDER BY ID DESC ";
        }
    }

      當(dāng)然這里的繼承的方式不是很推薦,可以采用抽象工廠的模式,來創(chuàng)建這個查詢對象,然后我們在調(diào)用這個查詢對象的地方,我們可以自定義這個SQL查詢對象,后臺的

ORM自動解析,完成自定義SQL語句的統(tǒng)一查詢服務(wù)入口。

      當(dāng)然如果您有更好的方案,可以提出來,非常感謝!

六、本章總結(jié)

        本文主要是講述ORM中的數(shù)據(jù)訪問層,我這里由于一些特殊的原因,代碼給出的不是特別的詳細(xì),一方面是由于之前的那部分的代碼丟了,現(xiàn)在一時難以還原,所以造成有

些代碼給出的不是特別完整的情況,請大家見諒,文章中的有些部分的內(nèi)容,我在實現(xiàn)的過程中也是遇到了不少的問題,我現(xiàn)在的具體問題列出來,也請大家?guī)臀医鉀Q一下,我的

疑問,我目前在架構(gòu)設(shè)計的過程中遇到如下的問題:

               1、我在實現(xiàn)服務(wù)層持久化透明服務(wù)的時候,我也想把查詢服務(wù)透明,意思就是業(yè)務(wù)對象與服務(wù)層只通過DTO來完成,業(yè)務(wù)對象的所有數(shù)據(jù)都通過服務(wù)層的訪問來完成。

               2、如果現(xiàn)在有比較復(fù)雜的業(yè)務(wù)邏輯的操作語句的時候,我的這個SQL語句放在數(shù)據(jù)訪問層好呢?還是放在哪里?應(yīng)該具體的職責(zé)劃分要明確。

               3、我只是希望業(yè)務(wù)邏輯層處理業(yè)務(wù)數(shù)據(jù),具體的業(yè)務(wù)數(shù)據(jù)怎么來的,我想讓業(yè)務(wù)邏輯只關(guān)心DTO。

               4、對于這樣的服務(wù)層提供的統(tǒng)一查詢方式的話,我在表現(xiàn)層調(diào)用的時候,如何傳參,能夠很好的組織參數(shù)的傳遞和調(diào)用,傳統(tǒng)的方式不再目前的考慮當(dāng)中。

           

it知識庫Step by Step-構(gòu)建自己的ORM系列-數(shù)據(jù)訪問層,轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 收藏| 南宫市| 明水县| 德惠市| 通海县| 大足县| 遂昌县| 邳州市| 胶州市| 洪雅县| 蕉岭县| 太湖县| 乐平市| 大丰市| 肇东市| 县级市| 裕民县| 来宾市| 游戏| 鄢陵县| 虎林市| 中阳县| 绩溪县| 桐乡市| 宝清县| 张家口市| 平泉县| 寿阳县| 棋牌| 双流县| 北流市| 鄱阳县| 宁乡县| 龙南县| 阜宁县| 资源县| 南丰县| 巴彦县| 肥城市| 南澳县| 永善县|