功能背景
你用經典的ASP.NET+SqlServer做了一個新功能給Boss看,希望得到他的贊賞,誰知道,惡毒的Boss說,我們要考慮周全,你把他修改成也可以用Oracle數據庫,程序猿只好苦逼的回去,修改了一番再拿給Boss,一看還不錯,但是如果兼顧到Access數據庫就更好了。程序員徹底瘋狂了!
最普通的做法
我們都知道,如果使用SqlServer數據庫,則會使用using System.Data.SqlClient下相關的類,如:SqlConnection;
如果使用Oracle作為數據庫,則會使用到System.Data.OracleClient命名空間下相關類,如:OracleCommand;等等……
普通的做法是:判斷使用的是哪種類型的數據庫,然后new相關的數據庫連接類Connection,然后new出相關的數據庫操作類Command這樣子;當你做完這一步之后,你會發現,其實大部分的代碼都是一樣的,不同的只是SqlConnection,OracleConnection,OleDbConnection……等等這些與數據庫類型相關的類。所以你可能會寫出下面這樣的代碼:
string type = Console.ReadLine(); if (type == "SQLServer") { using (SqlConnection conn = new SqlConnection("數據庫連接字符串")) { conn.Open(); using (SqlCommand cmd = conn.CreateCommand()) { //相關數據庫操作 } } } else if (type == "Oracle") { using (OracleConnection conn = new OracleConnection("數據庫連接字符串")) { conn.Open(); using (SqlCommand cmd = conn.CreateCommand()) { //相關數據庫操作 } } } else { throw new Exception("沒有相關的數據庫源"); }
基於IDbConnection接口編程
為了避免更換數據庫大量修改代碼和重復判斷數據庫類型,我們決定使用基於接口編程的方法來實現:
首先介紹:IDbConnection這個接口,使用查看定義你就會發現,SqlConnection,OracleConnection,OleDbConnection等類都繼承自DbConnection類,而DbConnection類實現了IDbConnection這個接口,接口定義了很多通用的方法如:Open(),Close()等抽象方法讓實現該接口的類去重寫。
第一步:配置文件
利用providerName這個屬性標注是哪種類型的數據庫,代碼里通過他來判斷
<?xml version="1.0" encoding="utf-8" ?> <configuration> <connectionStrings> <add name="connstr" connectionString="" providerName="Access"/> </connectionStrings> </configuration>
第二步:接口編程
IDbConnection按繼承輩分來說,應該是各個數據庫操作類的祖父,當然,我們可以用父類對象變量指向子類對象的方法使用,
private void button1_Click(object sender, EventArgs e) { string connstr = ConfigurationManager.ConnectionStrings["connstr"].ConnectionString; //多種數據庫切換 IDbConnection conn; string provideName = ConfigurationManager.ConnectionStrings["connstr"].ProviderName; if (provideName == "Access") { conn = new OleDbConnection(connstr); } else if (provideName == "SQLServer") { conn = new SqlConnection(connstr); } else { throw new Exception("未知的ProvideName"); } using (conn) { conn.Open(); using (IDbCommand cmd= conn.CreateCommand()) { cmd.CommandText = "Insert into XXXXX"; cmd.ExecuteNonQuery(); } } MessageBox.Show("Success"); }
因為很多種數據庫連接類,比如OleDbConnection,SqlConnection都繼承自DbConnection,而DbConnection則實現了IDbConnection 接口,使用接口變量來指向各自的數據庫連接對象,更使得通用,但是,使用接口變量則無法調用各自私有的東西,比如OleDbConnection類下有某個屬於自己的方法A(),使用接口變量則無法調用A(),但是,可以類型轉換為OleDbConnection對象再來使用。