功能背景
你用经典的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对象再来使用。