【前言】
作为一款成熟的面向对象高级编程语言,C#在ADO.Net的支持上已然是做的很成熟,我们可以方便地调用ADO.Net操作各类关系型数据库,在使用了多年的Sql_Helper_DG后,由于项目需要,于是乎,就准备写一个Mysql_Helper在实现过程中,发现ADO.Net封装之完善,以及面向对象的封装、继承、多态,有了这些特性,何不把数据库操作封装成为一个通用的类呢,此文由此铺展而来...
【实现功能】
这篇文章将要介绍的主要内容如下:
1、ADO.NET之SqlServer
2、ADO.NET之Oracle
3、ADO.NET之MySql
4、充分利用面向对象的特征,实现通用的操作类
【环境准备】
1、MySql连接器的DLL引用
使用Nuget搜索 MySql.Data 引用即可:
2、Oracle连接器的DLL引用
使用Nuget搜索 Oracle.ManagedDataAccess 进行引用:
【实现思路】
在ADO.NET对SqlServer,Oracle,Mysql的操作熟练的基础上,我们逐渐发现所有的操作都是使用的同一套的东西,不同的是:
SqlServer的操作使用的是SqlConnection、SqlCommand,SqlDataAdapter;
MySql使用的是MySqlConnection、MySqlCommand、MySqlDataAdapter;
Oracle使用的是OracleSqlConnection、OracleCommand、OracleDataAdapter;
该连接类,操作类都分别继承自基础类:DbConnection、DbCommand、DbDataAdapter;
其类间关系如图所示:
1.DbConnection家族
2.DbCommand家族
3.DBDataAdapter家族
了解如上的几个特点后,我们里面能联系到了“多态”这个概念,我们可以使用同一套相同的代码,用“多态”的特性实例化出不同的实例,进而可以进一步封装我们的操作,达到代码精炼可重用的目的。
【实现过程】
1.定义枚举类 Opt_DataBaseType 用于参数选择具体要实例的数据库
1 public enum Opt_DataBaseType 2 { 3 SqlServer, 4 MySql, 5 Oracle 6 }
2.自定义内部类SqlConnection_WR_Safe(多态提供DbConnection的对象、读写分离的支持)
1.在该内部类中,我们定义类属性DbConnection用于承接根据不同的数据库参数多态实例化后的对应Connection
2.实现IDisposable接口,提供释放DbConnection的方法
3.在读数据库连接失败时,及时切换到读写主数据库,提升系统的可用性
1 internal class SqlConnection_WR_Safe : IDisposable 2 { 3 /// <summary> 4 /// SqlConnection 5 /// </summary> 6 public DbConnection DbConnection { get; set; } 7 8 public SqlConnection_WR_Safe(Opt_DataBaseType dataBaseType, string ConnString_RW) 9 { 10 this.DbConnection = GetDbConnection(dataBaseType, ConnString_RW); 11 } 12 /** 13 * if read db disabled,switchover to read write db immediately 14 * */ 15 public SqlConnection_WR_Safe(Opt_DataBaseType dataBaseType, string ConnString_R, string ConnString_RW) 16 { 17 try 18 { 19 this.DbConnection = GetDbConnection(dataBaseType, ConnString_R); 20 } 21 catch (Exception) 22 { 23 this.DbConnection = GetDbConnection(dataBaseType, ConnString_RW); 24 } 25 } 26 27 /// <summary> 28 /// GetDataBase ConnectionString by database type and connection string -- private use 29 /// </summary> 30 /// <param name="dataBaseType"></param> 31 /// <param name="ConnString"></param> 32 /// <returns></returns> 33 private DbConnection GetDbConnection(Opt_DataBaseType dataBaseType, string ConnString) 34 { 35 switch (dataBaseType) 36 { 37 case Opt_DataBaseType.SqlServer: 38 return new SqlConnection(ConnString); 39 case Opt_DataBaseType.MySql: 40 return new MySqlConnection(ConnString); 41 case Opt_DataBaseType.Oracle: 42 return new OracleConnection(ConnString); 43 default: 44 return new SqlConnection(ConnString); 45 } 46 } 47 /// <summary> 48 /// Must Close Connection after use 49 /// </summary> 50 public void Dispose() 51 { 52 if (this.DbConnection != null) 53 { 54 this.DbConnection.Dispose(); 55 } 56 } 57 }
3.自定义内部类 DbCommandCommon 用于提供DbCommand对象
1 internal class DbCommandCommon : IDisposable 2 { 3 /// <summary> 4 /// common dbcommand 5 /// </summary> 6 public DbCommand DbCommand { get; set; } 7 public DbCommandCommon(Opt_DataBaseType dataBaseType) 8 { 9 this.DbCommand = GetDbCommand(dataBaseType); 10 } 11 12 /// <summary> 13 /// Get DbCommand select database type 14 /// </summary> 15 /// <param name="dataBaseType"></param> 16 /// <returns></returns> 17 private DbCommand GetDbCommand(Opt_DataBaseType dataBaseType) 18 { 19 switch (dataBaseType) 20 { 21 case Opt_DataBaseType.SqlServer: 22 return new SqlCommand(); 23 case Opt_DataBaseType.MySql: 24 return new MySqlCommand(); 25 case Opt_DataBaseType.Oracle: 26 return new OracleCommand(); 27 default: 28 return new SqlCommand(); 29 } 30 } 31 /// <summary> 32 /// must dispose after use 33 /// </summary> 34 public void Dispose() 35 { 36 if (this.DbCommand != null) 37 { 38 this.DbCommand.Dispose(); 39 } 40 } 41 }
4.自定义内部类 DbDataAdapterCommon 用于提供DbDataAdapter
该类继承自DbDataAdapter,以实现DataAdapter的Fill方法,可以将结果集填充到DataSet中去。
1 /// <summary> 2 /// DbDataAdapterCommon 3 /// </summary> 4 internal class DbDataAdapterCommon : DbDataAdapter, IDisposable 5 { 6 public DbDataAdapter DbDataAdapter { get; set; } 7 public DbDataAdapterCommon(Opt_DataBaseType dataBaseType, DbCommand dbCommand) 8 { 9 //get dbAdapter 10 this.DbDataAdapter = GetDbAdapter(dataBaseType, dbCommand); 11 //provid select command 12 this.SelectCommand = dbCommand; 13 } 14 private DbDataAdapter GetDbAdapter(Opt_DataBaseType dataBaseType, DbCommand dbCommand) 15 { 16 switch (dataBaseType) 17 { 18 case Opt_DataBaseType.SqlServer: 19 return new SqlDataAdapter(); 20 case Opt_DataBaseType.MySql: 21 return new MySqlDataAdapter(); 22 case Opt_DataBaseType.Oracle: 23 return new OracleDataAdapter(); 24 default: 25 return new SqlDataAdapter(); 26 } 27 } 28 /// <summary> 29 /// must dispose after use 30 /// </summary> 31 public new void Dispose() 32 { 33 if (this.DbDataAdapter != null) 34 { 35 this.DbDataAdapter.Dispose(); 36 } 37 } 38 }
5.在执行Sql查询的时候,我们便使用我们自定义的内部类进行操作
>1 这里以ExecuteNonQuery为例:
1 public static int ExecuteNonQuery(string commandTextOrSpName, CommandType commandType = CommandType.Text) 2 { 3 using (SqlConnection_WR_Safe conn = new SqlConnection_WR_Safe(dataBaseType, ConnString_RW)) 4 { 5 using (DbCommandCommon cmd = new DbCommandCommon(dataBaseType)) 6 { 7 PreparCommand(conn.DbConnection, cmd.DbCommand, commandTextOrSpName, commandType); 8 return cmd.DbCommand.ExecuteNonQuery(); 9 } 10 } 11 }
该代码通过参数DataBaseType确定要实例化的数据库类型,ConnString_RW传入写数据库的连接字符串进行实例化,DbCommand也是使用dataBaseType实例我们需要实际操作的数据库对象。
>2 查询ExecuteDataSet方法:
该方法通过参数dataBaseType确定要实例化的具体DbConnection,通过读写分离的连接字符串进行选择读库和写库。
1 public static DataSet ExecuteDataSet(string commandTextOrSpName, CommandType commandType = CommandType.Text) 2 { 3 using (SqlConnection_WR_Safe conn = new SqlConnection_WR_Safe(dataBaseType, ConnString_R, ConnString_RW)) 4 { 5 using (DbCommandCommon cmd = new DbCommandCommon(dataBaseType)) 6 { 7 PreparCommand(conn.DbConnection, cmd.DbCommand, commandTextOrSpName, commandType); 8 using (DbDataAdapterCommon da = new DbDataAdapterCommon(dataBaseType, cmd.DbCommand)) 9 { 10 DataSet ds = new DataSet(); 11 da.Fill(ds); 12 return ds; 13 } 14 } 15 } 16 }
全部代码见此:
1、数据库选择器枚举类:Opt_DataBaseType->
1 /********************************************************* 2 * CopyRight: QIXIAO CODE BUILDER. 3 * Version:4.2.0 4 * Author:qixiao(柒小) 5 * Create:2017-09-26 17:54:28 6 * Update:2017-09-26 17:54:28 7 * E-mail: dong@qixiao.me | wd8622088@foxmail.com 8 * GitHub: https://github.com/dong666 9 * Personal web site: http://qixiao.me 10 * Technical WebSit: http://www.cnblogs.com/qixiaoyizhan/ 11 * Description: 12 * Thx , Best Regards ~ 13 *********************************************************/ 14 namespace QX_Frame.Bantina.Options 15 { 16 public enum Opt_DataBaseType 17 { 18 SqlServer, 19 MySql, 20 Oracle 21 } 22 }