標(biāo)題有點大。但是,我覺得99%的接近了。
好了,下面我們來說說一個SqlHelper為了適應(yīng)各種不同的業(yè)務(wù)需要,它應(yīng)該具備哪些基本要素。
第一點、可控的事務(wù)。
事務(wù)是數(shù)據(jù)庫操作的關(guān)鍵部分,在對數(shù)據(jù)庫進(jìn)行插入、修改、刪除時都會用到;事務(wù)是基于數(shù)據(jù)庫連接的。一個事務(wù)必須要運行在一個連接上,但一個連接上可以有多個事務(wù)。
可控的事務(wù)就是你在進(jìn)行數(shù)據(jù)的增刪改時需要一個事務(wù)來進(jìn)行輔助,當(dāng)操作出錯時將修改的數(shù)據(jù)還原。類似下面的過程
transaction.begin(); ... do something... transaction.commit(); or error transaction.rollback();
當(dāng)然,你會說,我有部分代碼不需要事務(wù)。對!向操作日志之類的東西,只要你的語句沒錯,不管其它的操作成功與否都需要寫入數(shù)據(jù)庫。這樣的操作就可以護(hù)理事務(wù)了。
可控的事務(wù)其它隱匿包含兩種操作。一種是普通的單表增刪改操作。一種是多表增刪改操作,多見于主從表。
那么,我們需要使用兩套(標(biāo)準(zhǔn)或)代碼來對以上兩種情況進(jìn)行處理嘛?
第二點,多樣的輸入方式。
何為輸入方式?哈哈,這個很簡單嘛!CommandText 與 Parameters。數(shù)據(jù)庫管理系統(tǒng)發(fā)展到今天早已經(jīng)超出使用sql命令的范圍,在NoSql數(shù)據(jù)庫越來越成熟的情況下,關(guān)系型數(shù)據(jù)庫卻依然是主流。所以,哈哈。我們還是談CommandText 與 Parameters。
向數(shù)據(jù)庫發(fā)現(xiàn)Sql命令的方法只有通過文本的形式,然后Parameters的使用卻可以為編程以及數(shù)據(jù)庫安全提供幫助。例如:
var sql = new StringBuilder(); sql.Append( " INSERT INTO xACCOUNT " ); sql.Append( " (USERID, " ); sql.Append( " ACCOUNT, " ); sql.Append( " EMAIL, " ); sql.Append( " STATE, " ); sql.Append( " PWD, " ); sql.Append( " CREATEOPTION, " ); sql.Append( " PROPERTY, " ); sql.Append( " JOINDATE, " ); sql.Append( " ATTENMODE) " ); sql.Append( " VALUES " ); sql.Append( " (:pUSERID, " ); sql.Append( " :pACCOUNT, " ); sql.Append( " :pEMAIL, " ); sql.Append( " :pSTATE, " ); sql.Append( " :pPWD, " ); sql.Append( " :pCREATEOPTION, " ); sql.Append( " :pPROPERTY, " ); sql.Append( " :pJOINDATE, " ); sql.Append( " :pATTENMODE) " ); return sql.ToString();
如果你需要向數(shù)據(jù)庫中連接插入1W條數(shù)據(jù),我想你第一想到的應(yīng)該是使用帶參數(shù)的insert語句。為什么?直白點說,數(shù)據(jù)庫對這條語句做出了優(yōu)化。如果你需要向數(shù)據(jù)庫插入10w以上的數(shù)據(jù),那么就不要用這個方法了。有個以datatable方式插入的方法,秒級。
數(shù)據(jù)安全方面,這個最普通的說法是防止惡意sql語句攻擊。百度一下應(yīng)該大把資料。
第三點,高復(fù)雜度與低耦合。
什么是高復(fù)雜度。即:所有對數(shù)據(jù)庫的操作高度封裝。再解釋:.net提供了數(shù)據(jù)操作的接口對象,如Connectin,Command,Transaction,DataReader,DataAdapter,DataSet,DataTable,Parameter等等對象。這些幾乎是數(shù)據(jù)庫操作時必不可少的元素。然后這些對象對于我們的開發(fā)來說還是過于分散,因為我們更多的是關(guān)心操作的結(jié)果。所以,將它們再次封裝后,只留下,DataSet,DataTable,DataReader,Execute(),ExecuteScalar()就足夠我們使用的了。
什么是低耦合。即:業(yè)務(wù)類只做業(yè)務(wù)邏輯相關(guān)的事,將數(shù)據(jù)處理交給數(shù)據(jù)處理層去做(純廢話,大家都知道的)。這個要怎么實現(xiàn)?
?
下面,我來展示兩個圖一個文件列表。通過這些來說明上述三點是如何實現(xiàn)的。
圖一,類模型
|
從這個圖,你能看到各對象之間的關(guān)聯(lián)。按照.net一個對象一個文件的作法。這也表示,我的文件列中有6個文件。 |
圖二,類結(jié)構(gòu)圖。哈哈,這是你最次要想知道的。你最想要知道的是我的代碼是什么?有沒有可以下載的地方?
最后是文件列表,
?
下面我將正向的介紹這6個文件(類)
1、ErrorObject 。業(yè)務(wù)基類(blo)的基類。 用于描述錯誤信息。它很簡單只有兩個屬性一個方法。
屬性: IsSucceed,用于判斷一個(系列)業(yè)務(wù)操作是否成功。
屬性:ErrorCode,表示出錯的代碼。這里只存儲出錯代碼。具體出錯信息需要另行存儲,以方便管理。
?
2、Blo 。業(yè)務(wù)類的基類 。所有的業(yè)務(wù)類需要從這里繼承。為什么?還記得“可控事務(wù)”最后的問題嘛!這個就是答案。
2.1 獨立業(yè)務(wù)操作
設(shè):
public class TestA : Blo { public bool Add( object obj) { Transaction.Begin(); try { ............ Transaction.Commit(); } catch (Exception ex) { Transaction.RollBack(); ErrorCode = - 1111 ; throw ; } } } ? |
這里業(yè)務(wù)類 TestA 的操作在自己的事務(wù)過程中 |
2.2 大事務(wù)業(yè)務(wù)操作。
public class TestB : Blo { public bool Add( object obj) { Transaction.Begin(); try { ? |
這里業(yè)務(wù)類 TestB 的操作在自己的事務(wù)過程中。而 TestA 的操作則在TestB的事務(wù)過程里。對,沒錯,它們共享了一個事務(wù)過程。 |
?共享事務(wù)過程的辦法就是 Transaction 要做的事了。這個過會再講。
?
3、Dao 數(shù)據(jù)訪問層。 說白了就是寫sql語句的地方。
在這里你可以直接寫sql語句,也可以使用參數(shù)的形式。不管使用哪種方法,最終的目的是通過制造sql命令,使用OracleHelper對數(shù)據(jù)庫進(jìn)行操作,并將得到的結(jié)果返回給blo層。
上一個直接sql的代碼片段
using ( var helper = new OracleHelper { ConnectionString = txtOracle.Text, CommandText = txtSql.Text }) { var dt = helper.GetDataTable(); if (dt != null && dt.Rows.Count > 0 ) { foreach (DataRow row in dt.Rows) { lbResult.Items.Add(row.Field < string >( " TABLE_NAME " ) + " \t " + row.Field< string >( " COMMENTS " )); } } }
?
4、ParameterList。 參數(shù)列表對象。
這個對象,在我的上一版本是沒有的。之所以現(xiàn)在增加,是因為我在最近寫一個導(dǎo)入工具時發(fā)現(xiàn),我原來寫的那個helper在對參數(shù)進(jìn)行操作時只能一次性操作。即AddParameter方法只會在調(diào)用時才能賦值,而不能在第二次以上的循環(huán)中對其賦值。且不能保存對參數(shù)列表的引用。
對象中加入了屬性操作
public OracleParameter this [ string parameterName]
?
以通過參數(shù)名稱來快速檢索參數(shù)對象。內(nèi)部存儲使用的是 Dictionary 對象。
同時對象增加了 CopyTo 方法,可以將參數(shù)對象全部導(dǎo)出。
5、Transaction 業(yè)務(wù)邏輯中的事務(wù)控制器。
此對象為事務(wù)共享時控制是否共用同一事務(wù)的關(guān)鍵。主要的方法為
public void AddBusiness(Blo business)
?
將多個需要共享事務(wù)的業(yè)務(wù)對象放到同一事務(wù)中。屬性?
public bool IsRelated { get ; private set ; }
?
用于判斷是否為共享事務(wù)。這個屬性為只讀的。當(dāng)業(yè)務(wù)類進(jìn)行事務(wù)操作時,判斷IsRelated是否為true。若為True則跳過事務(wù)處理(其實它沒有自己的事務(wù)處理過程,所以也就沒辦法提交,只能跳過)。
6、OracleHelper 數(shù)據(jù)庫處理類。
本文的重點,也是大家最熟悉的。每個人的處理方式不同。但接口只要差不多就行了。略過。
?
最后,你最關(guān)心的問題,代碼在哪里,哪里可以下載!哈哈。。。哈哈。。。
我在這只能說抱歉了。授人以魚,不如授人以漁。在我這個文的基本上,你動動手,活動活動腦子,我想也能搞個八 九 不 離 十 吧。
別太懶了。
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
