做開發也有將近2年的時間了,但是經驗其實也不多。經歷過幾個小公司,資料處理層使用過基本的sql,也有nhibernate框架。框架確實好用,省去了不少**量,但是業務複雜的情況下,也就難以依託了,仍然需要自己手動書寫sql。業餘開發專案的時候資料層使用了框架,後來改回了基礎的sql底層,原因嘛,也想說自己在重複造輪子的情況下,能有其他的收穫。
原本使用泛型版本的底層基類,無法使用多型,因此也就無法使用工廠模式建立對應的sql介面了。
原資料庫基類:
1///2
///資料庫連線基類
3///
4///
資料庫連線池
5///
資料庫command
6///
資料引數
7///
資料庫讀取流
8///
資料庫adapter
9///
事務10
public
class basedb
11where dbconn : dbconnection, new()
12where dbcmd : dbcommand, new()
13where dbparam : dbparameter, new()
14where dbreader : dbdatareader
15where dbadapter : dbdataadapter, new()
16where dbtrans : dbtransaction
17
資料庫派生類:
1///2
///ms-sql資料庫連線
3///
4public
class mssqldb : basedb5 8
9///
10///
access資料庫
11///
12public
class oledb : basedb
13
這種情況下,除非使用4.0的新特性「協變」,否則無法通過基類來接收對應的派生類了。
其實資料層的基類無非就是dbconnection、dbcommand、dbparameter等,差異的地方無非就是在例項化dbconnection、dbcommand、dbdataadapter這些,因此我們只要讓派生類去重寫返回dbconnection、dbcommand、dbdataadapter對應的派生類就可以了。
抽象方法如下:
1///2
///新資料庫連線池
3///
4///
資料庫連線字串
5///
6protected
abstract dbconnection newconn(string connectionstr);78
///9
///新sql解析方式
10///
11///
12protected
abstract dbcommand newcommand();
1314
///15
///新dataadapter
16///
17///
18protected
abstract dbdataadapter newadapter();
資料庫基類就做好了,這時候我們使用了幾次之後,就會發現在獲取dbdatareader的時候,要自己重複的寫如下**:
1 abstractbasedb db = //相應的派生類;
2using(dbdatareader reader = db.executereader(引數))
6 }
於是乎,就有了想把dbdatareader直接轉換成對應實體類的想法,既然有了想法我們就動手開始寫吧。
要將dbdatareader內的資料庫輸出流轉化為對應的實體類泛型,其實就是將每一行值進行轉換而已,這時候我們可以用泛型去定義,因為實體類需要例項化,因此我們需要這個t必須是可以例項化的。
**如下:
1 ilistclasslist = new list();2 propertyinfo properties = typeof(t).getproperties();
3 predicatematch;
4while (this.datareader.read())
5 16 }
17 classlist.add(tobj);
18 }
做到這裡的時候,可能有些人已經想到了乙個問題,那就是如果實體類屬性名跟資料庫的列名不相同(**生成的時候對資料庫列名進行了處理)怎麼辦呢,那這個時候,我們就需要提供乙個可以將資料庫列名進行轉化的方法,該委託出場了。
修改後**如下:
1///2
///轉化為類泛型
3///
4///
引用型別
5///
格式化列名
6///
7ilisttolist(func format) where t : new()
8 22 match = p => p.name == filedname;
23if (!this.datareader.isdbnull(i) && array.exists(properties, match))
24
28 }
29 classlist.add(tobj);
30 }
31return classlist;
32 }
以上加入了引數func,並且在獲取列名的時候,判斷如果格式化方法存在,則對列名進行處理,到這裡將dbdatareader轉化為實體類泛型就完成了,然而完成到這裡我們就會有了新的想法了,既然實體類已經實現了,那麼如果t是基礎型別怎麼辦呢,於是乎我們要過載這個方法,讓他也可以適用於基礎型別泛型。
進一步改進以後,**如下:
1///2
///將datareader轉化為泛型
3///
4///
需要轉化的實體類型別
5///
格式化列名
6///
7public ilisttolist(func format) where t : new()
8 15
else
16
19return list;
20 }
2122
///23
///轉化為值型別泛型
24///
25///
值型別型別
26///
27ilisttovaluelist()
28 35
return valuelist;
36 }
3738
///39
///轉化為類泛型
40///
41///
引用型別
42///
格式化列名
43///
44ilisttoclasslist(func format) where t : new()
45 59 match = p => p.name == filedname;
60if (!this.datareader.isdbnull(i) && array.exists(properties, match))
61
65 }
66 classlist.add(tobj);
67 }
68return classlist;
69 }
這樣轉化為泛型的方法就比較ok了。於是又使用了一段時間,發覺業務邏輯複雜的時候,返回的資料可不止一張表,也可能是多張表的資料一起返回的,這個時候除了可以使用datatable以外,沒有其他的方法可以用了。想到了在nhibernate獲取資料的時候,可以返回ilist型別,接下來我們也可依葫蘆畫瓢也做乙個這樣的轉換。
轉換的方式其實跟轉換為類泛型是差不多的,在迴圈dbdatareader.fieldcount的時候,我們只要將迴圈的資料放入arraylist內就可以了。
具體**如下:
1 ilist sublist = new arraylist();2while (this.datareader.read())
3 10 sublist.add(list);
11 }
12return sublist;
海量資料處理之資料庫索引
一,什麼是索引 資料庫索引好比是一本書前面的目錄,能加快資料庫的查詢速度。例如這樣乙個查詢 select from table1 where id 44。如果沒有索引,必須遍歷整個表,直到id等於44的這一行被找到為止 有了索引之後 必須是在id這一列上建立的索引 直接在索引裡面找44 也就是在id...
資料庫資料處理故事多
每年評教都會遇到資料匯入的一系列問題。從中收穫頗豐。這兩天別人總在問我,你們基礎出了什麼問題,為什麼總在導資料。資料沒問題,為了做足準備,我們需要將8期版的最全的資料整理到10期資料庫中。背景介紹 問題在於從8期版基礎系統到10期版基礎系統在資料庫設計方面有了很大的變化,例如10期學生表中存放著班級...
ORACEL資料庫資料處理 增
給大家介紹乙個簡單oracel資料庫資料處理 增 資料操縱語言 dml data manipulation language 資料操縱語言 可以在下列條件下執行 向表中插入資料 修改現存資料 刪除現存資料 事務是由完成若干項工作的dml語句組成的 insert into插入資料 為每一列新增乙個新值...