前期在作一個裝配線系統自動化掃描打標應用時,系統要求操做實時性比較強,因此沒有用ORM之類的工具,但是開發組成員設計的數據庫操做類顯得有些複雜,調用代碼量大,可擴展性低下,更不用說靈活性了,換個數據庫類型,這個組件就廢掉了。sql
我自已嘗試封裝了個數據庫操做幫助類,自認爲還算簡單。數據庫
同時,考慮到未來可能涉及到其餘項目不一樣數據庫類型也有一樣的需求,在設計方面也提供了擴展的接口,總之,儘可能使之簡單化,可擴展,可複用,加強靈活性。app
原理很簡單,設計一個抽象類(Helper),具體的子類(SQLHelper,OracleHelper…)繼承此抽象類便可。ide
從方法使用者角度考慮,我把方法設計想像成一個加工廠,我只須要關注輸入源料和輸入產品,具體複雜的工藝加工過程不須要關心,以下圖所示:函數
using System.Collections.Generic; using System.Data; using System.Data.Common; namespace XiaoCai.DataAccess { public interface IDbParameter { void Add(string paramName, DbType sqlType, object paramValue, DbParameter dbParam); void Add(string paramName, object paramValue, DbParameter dbParam); void Add(string paramName, DbType sqlType, DbParameter dbParam); List<System.Data.Common.DbParameter> GetParameters(); void Clear(); } }
using System.Collections.Generic; using System.Data; using System.Data.Common; namespace XiaoCai.DataAccess { public class DBParameter:IDbParameter { private readonly List<System.Data.Common.DbParameter> _dbParams;//聲明一個SQL參數列表 /// <summary> /// 構造函數,實例化SQL參數列表 /// </summary> public DBParameter() { _dbParams = new List<System.Data.Common.DbParameter>(); } public void Add(string paramName, DbType dbType, object paramValue,DbParameter dbParam) { System.Data.Common.DbParameter addSqlParam = dbParam; addSqlParam.DbType = dbType; addSqlParam.ParameterName = paramName; addSqlParam.Value = paramValue; _dbParams.Add(addSqlParam); } public void Add(string paramName, object paramValue, DbParameter dbParam) { System.Data.Common.DbParameter addSqlParam = dbParam; addSqlParam.ParameterName = paramName; addSqlParam.Value = paramValue; _dbParams.Add(addSqlParam); } public void Add(string paramName, DbType dbType, DbParameter dbParam) { System.Data.Common.DbParameter addSqlParam = dbParam; addSqlParam.DbType = dbType; addSqlParam.ParameterName = paramName; addSqlParam.Direction = ParameterDirection.Output; addSqlParam.Size = 200; _dbParams.Add(addSqlParam); } public List<System.Data.Common.DbParameter> GetParameters() { return _dbParams; } public void Clear() { _dbParams.Clear(); } } }
執行結果類:執行一個方法結束後,無論執行成功或失敗,返回一個結果(執行狀態,返回數據,返回消息)工具
#region Copyright & License /****************************************************************************** * This document is the property of XiaoCai * No exploitation or transfer of any information contained herein is permitted * in the absence of an agreement with XiaoCai * and neither the document nor any such information * may be released without the written consent of XiaoCai * * All right reserved by XiaoCai ******************************************************************************* * Owner: Agan * Version: 1.0.0.0 * Component:* * Function Description:* * Revision / History *------------------------------------------------------------------------------ * Flag Date Who Changes Description * -------- -------- --------------- ------------------------------------------- * 1 20120815 Agan File created *------------------------------------------------------------------------------ */ #endregion using System; namespace XiaoCai.DataAccess.Messages { [Serializable] public class ExecutionResult { private bool _statusField; private string _messageField; private object _anythingField; /// <summary> /// Returns true or false /// </summary> public bool Status { get { return _statusField; } set { _statusField = value; } } /// <summary> /// Returns message of string type /// </summary> public string Message { get { return _messageField; } set { _messageField = value; } } /// <summary> /// Returns a object /// </summary> public object Anything { get { return _anythingField; } set { _anythingField = value; } } } }
目前只添加了增,刪,改,查幾個操做(暫不支持事務),以下:測試
using System; using System.Collections.Generic; using System.Data; using System.Data.Common; using XiaoCai.DataAccess.Messages; namespace XiaoCai.DataAccess { public abstract class Helper { private DbConnection _dbConnection; private readonly AppLog _appLog; public Helper(DbConnection dbConnection) { _dbConnection = dbConnection; _appLog=new AppLog(GetType().Name); } public abstract ExecutionResult ExecuteQueryDS(string sqlCommandText, List<System.Data.Common.DbParameter> dbParams); public abstract ExecutionResult ExecuteQueryDS(string sqlCommandText); public ExecutionResult ExecuteUpdate(string sqlCommandText, List<DbParameter> dbParams) { DbCommand dbCommand; ExecutionResult result; result = new ExecutionResult(); try { if (_dbConnection.State != ConnectionState.Open) { _dbConnection.Open(); } dbCommand = _dbConnection.CreateCommand(); dbCommand.CommandType = CommandType.Text; dbCommand.CommandText = sqlCommandText; foreach (DbParameter tmpSqlParam in dbParams) { dbCommand.Parameters.Add(tmpSqlParam); } dbCommand.ExecuteNonQuery(); result.Status = true; result.Message = "OK"; } catch (Exception ex) { result.Status = false; result.Message = ex.Message; //write exception log. if (_appLog.IsErrorEnabled) { _appLog.Error(ex.Message); _appLog.Error(ex.StackTrace); } } finally { if (_dbConnection != null && _dbConnection.State != ConnectionState.Closed) { _dbConnection.Close(); } } return result; } public ExecutionResult ExecuteUpdate(string sqlCommandText) { ExecutionResult result = new ExecutionResult(); try { if (_dbConnection.State != ConnectionState.Open) { _dbConnection.Open(); } DbCommand sqlCommand = _dbConnection.CreateCommand(); sqlCommand.CommandType = CommandType.Text; sqlCommand.CommandText = sqlCommandText; sqlCommand.ExecuteNonQuery(); result.Status = true; result.Message = "OK"; } catch (Exception ex) { result.Status = false; result.Message = ex.Message; //write exception log. if (_appLog.IsErrorEnabled) { _appLog.Error(ex.Message); _appLog.Error(ex.StackTrace); } } finally { if (_dbConnection != null && _dbConnection.State != ConnectionState.Closed) { _dbConnection.Close(); } } return result; } public ExecutionResult ExecuteSP(string spName, List<DbParameter> dbParams) { DbParameter outputParam = null; ExecutionResult result = new ExecutionResult(); try { if (_dbConnection.State != ConnectionState.Open) { _dbConnection.Open(); } DbCommand dbCommand = _dbConnection.CreateCommand(); dbCommand.CommandType = CommandType.StoredProcedure; dbCommand.CommandText = spName; foreach (DbParameter tmpSqlParam in dbParams) { dbCommand.Parameters.Add(tmpSqlParam); if (tmpSqlParam.Direction.Equals(ParameterDirection.Output)) { outputParam = tmpSqlParam; } } dbCommand.ExecuteNonQuery(); if (outputParam == null) { result.Message = "OK"; result.Anything = "OK"; } else { result.Message = "OK"; result.Anything = outputParam.Value.ToString(); } result.Status = true; } catch (Exception ex) { result.Message = "Helper:ExecuteSP," + ex.Message; result.Anything = "Helper:ExecuteSP," + ex.Message; result.Status = false; //write exception log. if (_appLog.IsErrorEnabled) { _appLog.Error(ex.Message); _appLog.Error(ex.StackTrace); } } finally { if (_dbConnection != null && _dbConnection.State != ConnectionState.Closed) { _dbConnection.Close(); } } return result; } } }
繼承父類Helper,重寫子類方法便可。以下我只須要重寫兩個方法ExecuteQueryDS及其重載方法,根據子類不一樣點須要和父類區分。this
以下是:SQLHelper.csspa
using System; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Data.SqlClient; using XiaoCai.DataAccess.Messages; namespace XiaoCai.DataAccess.SQLServer { public class SQLHelper:Helper { private readonly DbConnection _dbConnection; private readonly AppLog _appLog; public SQLHelper(DbConnection dbConnection) : base(dbConnection) { _dbConnection = dbConnection; _appLog = new AppLog(this.GetType().Name); } public override ExecutionResult ExecuteQueryDS(string sqlCommandText, List<DbParameter> dbParams) { ExecutionResult result = new ExecutionResult(); DataSet resultDS = new DataSet(); try { if (_dbConnection.State != ConnectionState.Open) { _dbConnection.Open(); } SqlCommand sqlCommand = ((SqlConnection)_dbConnection).CreateCommand(); sqlCommand.CommandType = CommandType.Text; sqlCommand.CommandText = sqlCommandText; foreach (DbParameter tmpSqlParam in dbParams) { sqlCommand.Parameters.Add(tmpSqlParam); } DataAdapter dataAdapter = new SqlDataAdapter(sqlCommand); dataAdapter.Fill(resultDS); result.Status = true; result.Message = "OK"; result.Anything = resultDS; } catch (Exception ex) { result.Status = false; result.Message = ex.Message; //write exception log. if (_appLog.IsErrorEnabled) { _appLog.Error(ex.Message); _appLog.Error(ex.StackTrace); } } finally { if (_appLog != null && _dbConnection.State != ConnectionState.Closed) { _dbConnection.Close(); } } return result; } public override ExecutionResult ExecuteQueryDS(string sqlCommandText) { ExecutionResult result = new ExecutionResult(); DataSet resultDS = new DataSet(); try { if (_dbConnection.State != ConnectionState.Open) { _dbConnection.Open(); } SqlCommand sqlCommand = ((SqlConnection)_dbConnection).CreateCommand(); sqlCommand.CommandType = CommandType.Text; sqlCommand.CommandText = sqlCommandText; DataAdapter dataAdapter = new SqlDataAdapter(sqlCommand); dataAdapter.Fill(resultDS); result.Status = true; result.Message = "OK"; result.Anything = resultDS; } catch (Exception ex) { result.Status = false; result.Message = ex.Message; //write exception log. if (_appLog.IsErrorEnabled) { _appLog.Error(ex.Message); _appLog.Error(ex.StackTrace); } } finally { if (_appLog != null && _dbConnection.State != ConnectionState.Closed) { _dbConnection.Close(); } } return result; } } }
其餘的具體操做子類,也同理,以下:設計
OracleHelper.cs:
using System; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Data.OracleClient; using XiaoCai.DataAccess.Messages; namespace XiaoCai.DataAccess.Ora { public class OracleHelper:Helper { private readonly DbConnection _dbConnection; private readonly AppLog _appLog; public OracleHelper(DbConnection dbConnection) : base(dbConnection) { _dbConnection = dbConnection; _appLog = new AppLog(this.GetType().Name); } public override ExecutionResult ExecuteQueryDS(string sqlCommandText, List<DbParameter> dbParams) { ExecutionResult result = new ExecutionResult(); DataSet resultDS = new DataSet(); try { if (_dbConnection.State != ConnectionState.Open) { _dbConnection.Open(); } OracleCommand oraCommand = ((OracleConnection)_dbConnection).CreateCommand(); oraCommand.CommandType = CommandType.Text; oraCommand.CommandText = sqlCommandText; foreach (DbParameter tmpSqlParam in dbParams) { oraCommand.Parameters.Add(tmpSqlParam); } DataAdapter dataAdapter = new OracleDataAdapter(oraCommand); dataAdapter.Fill(resultDS); result.Status = true; result.Message = "OK"; result.Anything = resultDS; } catch (Exception ex) { result.Status = false; result.Message = ex.Message; //write exception log. if (_appLog.IsErrorEnabled) { _appLog.Error(ex.Message); _appLog.Error(ex.StackTrace); } } finally { if (_appLog != null && _dbConnection.State != ConnectionState.Closed) { _dbConnection.Close(); } } return result; } public override ExecutionResult ExecuteQueryDS(string sqlCommandText) { ExecutionResult result = new ExecutionResult(); DataSet resultDS = new DataSet(); try { if (_dbConnection.State != ConnectionState.Open) { _dbConnection.Open(); } OracleCommand oraCommand = ((OracleConnection)_dbConnection).CreateCommand(); oraCommand.CommandType = CommandType.Text; oraCommand.CommandText = sqlCommandText; DataAdapter dataAdapter = new OracleDataAdapter(oraCommand); dataAdapter.Fill(resultDS); result.Status = true; result.Message = "OK"; result.Anything = resultDS; } catch (Exception ex) { result.Status = false; result.Message = ex.Message; //write exception log. if (_appLog.IsErrorEnabled) { _appLog.Error(ex.Message); _appLog.Error(ex.StackTrace); } } finally { if (_appLog != null && _dbConnection.State != ConnectionState.Closed) { _dbConnection.Close(); } } return result; } } }
MySQLHelper.cs:
using System; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Text; using XiaoCai.DataAccess.Messages; using MySql.Data.MySqlClient; namespace XiaoCai.DataAccess.MySQL { public class MySQLHelper : Helper { private DbConnection _dbConnection; private readonly AppLog _appLog; public MySQLHelper(DbConnection dbConnection) : base(dbConnection) { _dbConnection = dbConnection; _appLog = new AppLog(this.GetType().Name); } public override ExecutionResult ExecuteQueryDS(string sqlCommandText, List<DbParameter> dbParams) { ExecutionResult result = new ExecutionResult(); DataSet resultDS = new DataSet(); try { if (_dbConnection.State != ConnectionState.Open) { _dbConnection.Open(); } MySqlCommand sqlCommand = ((MySqlConnection)_dbConnection).CreateCommand(); sqlCommand.CommandType = CommandType.Text; sqlCommand.CommandText = sqlCommandText; foreach (DbParameter tmpSqlParam in dbParams) { sqlCommand.Parameters.Add(tmpSqlParam); } DataAdapter dataAdapter = new MySqlDataAdapter(sqlCommand); dataAdapter.Fill(resultDS); result.Status = true; result.Message = "OK"; result.Anything = resultDS; } catch (Exception ex) { result.Status = false; result.Message = ex.Message; //write exception log. if (_appLog.IsErrorEnabled) { _appLog.Error(ex.Message); _appLog.Error(ex.StackTrace); } } finally { if (_appLog != null && _dbConnection.State != ConnectionState.Closed) { _dbConnection.Close(); } } return result; } public override ExecutionResult ExecuteQueryDS(string sqlCommandText) { ExecutionResult result = new ExecutionResult(); DataSet resultDS = new DataSet(); try { if (_dbConnection.State != ConnectionState.Open) { _dbConnection.Open(); } MySqlCommand sqlCommand = ((MySqlConnection)_dbConnection).CreateCommand(); sqlCommand.CommandType = CommandType.Text; sqlCommand.CommandText = sqlCommandText; DataAdapter dataAdapter = new MySqlDataAdapter(sqlCommand); dataAdapter.Fill(resultDS); result.Status = true; result.Message = "OK"; result.Anything = resultDS; } catch (Exception ex) { result.Status = false; result.Message = ex.Message; //write exception log. if (_appLog.IsErrorEnabled) { _appLog.Error(ex.Message); _appLog.Error(ex.StackTrace); } } finally { if (_appLog != null && _dbConnection.State != ConnectionState.Closed) { _dbConnection.Close(); } } return result; } } }
如下是以SQL Server爲例,實例化一個幫助類(SQLHelper)對象,往方法裏傳SQL字符串和參數,輸入結果,就這麼簡單。
using System; using System.Configuration; using System.Data; using System.Data.SqlClient; using XiaoCai.DataAccess.Messages; namespace XiaoCai.DataAccess.SQLServer.Test { [NUnit.Framework.TestFixture] class TestSQLHelper { private Helper _helper = new SQLHelper(new SqlConnection(ConfigurationManager.AppSettings["Database.SqlServerConn"])); [NUnit.Framework.Test] //不帶參數的方法 public void ExecuteQueryDS() { string sqlText = @"select * from T_AUTH_USER"; ExecutionResult result=_helper.ExecuteQueryDS(sqlText); if (result.Status) { DataSet ds = (DataSet) result.Anything; if (ds.Tables[0].Rows.Count > 0) { for (int i = 0; i < ds.Tables[0].Rows.Count; i++) { Console.WriteLine("UserId:" + ds.Tables[0].Rows[i][0] + ",User_Name:" + ds.Tables[0].Rows[i][1] + ",PASSWORD:" + ds.Tables[0].Rows[i][2]); } } } else { Console.WriteLine(result.Message); } } [NUnit.Framework.Test] //帶參數的方法 public void ExecuteQueryDS2() { string sqlText = @"select * from T_AUTH_USER t where t.NAME=@UserName"; DBParameter dbParam=new DBParameter();//實例化一個參數對象 dbParam.Add("@UserName", "aganqin",new SqlParameter());//添加參數 ExecutionResult result = _helper.ExecuteQueryDS(sqlText,dbParam.GetParameters());//執行查詢方法 if (result.Status) { DataSet ds = (DataSet)result.Anything;//取得結果 if (ds.Tables[0].Rows.Count > 0) { //顯示結果 for (int i = 0; i < ds.Tables[0].Rows.Count; i++) { Console.WriteLine("UserId:" + ds.Tables[0].Rows[i][0] + ",User_Name:" + ds.Tables[0].Rows[i][1] + ",PASSWORD:" + ds.Tables[0].Rows[i][2]); } } } } [NUnit.Framework.Test] //參數的方法 public void ExecuteUpdate() { string sqlText = @"UPDATE T_AUTH_USER SET [PASSWORD]=@PASSWORD where [NAME]=@UserName"; DBParameter dbParam = new DBParameter(); dbParam.Add("@UserName", "aganqin",new SqlParameter()); dbParam.Add("@PASSWORD", "123456",new SqlParameter()); ExecutionResult result = _helper.ExecuteUpdate(sqlText, dbParam.GetParameters()); if (result.Status) { ExecuteQueryDS2(); } else { Console.WriteLine(result.Message); } } } }
using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.Data.OracleClient; using System.Data.SqlClient; using System.Linq; using System.Text; using XiaoCai.DataAccess.Messages; using XiaoCai.DataAccess.Ora; namespace XiaoCai.DataAccess.Ora.Test { [NUnit.Framework.TestFixture] class TestOracleHelper { private Helper _helper = new OracleHelper(new OracleConnection(ConfigurationManager.AppSettings["Database.SqlServerConn"])); [NUnit.Framework.Test] //不帶參數的方法 public void ExecuteQueryDS() { string sqlText = @"select * from T_AUTH_USER"; ExecutionResult result=_helper.ExecuteQueryDS(sqlText); if (result.Status) { DataSet ds = (DataSet) result.Anything; if (ds.Tables[0].Rows.Count > 0) { for (int i = 0; i < ds.Tables[0].Rows.Count; i++) { Console.WriteLine("UserId:" + ds.Tables[0].Rows[i][0] + ",User_Name:" + ds.Tables[0].Rows[i][1] + ",PASSWORD:" + ds.Tables[0].Rows[i][2]); } } } else { Console.WriteLine(result.Message); } } [NUnit.Framework.Test] //不帶參數的方法 public void ExecuteQueryDS2() { string sqlText = @"select * from T_AUTH_USER t where t.NAME=@UserName"; DBParameter dbParam=new DBParameter(); dbParam.Add("@UserName", "aganqin",new OracleParameter()); ExecutionResult result = _helper.ExecuteQueryDS(sqlText,dbParam.GetParameters()); if (result.Status) { DataSet ds = (DataSet)result.Anything; if (ds.Tables[0].Rows.Count > 0) { for (int i = 0; i < ds.Tables[0].Rows.Count; i++) { Console.WriteLine("UserId:" + ds.Tables[0].Rows[i][0] + ",User_Name:" + ds.Tables[0].Rows[i][1] + ",PASSWORD:" + ds.Tables[0].Rows[i][2]); } } } } [NUnit.Framework.Test] //不帶參數的方法 public void ExecuteUpdate() { string sqlText = @"UPDATE T_AUTH_USER SET [PASSWORD]=@PASSWORD where [NAME]=@UserName"; DBParameter dbParam = new DBParameter(); dbParam.Add("@UserName", "aganqin", new OracleParameter()); dbParam.Add("@PASSWORD", "123456", new OracleParameter()); ExecutionResult result = _helper.ExecuteUpdate(sqlText, dbParam.GetParameters()); if (result.Status) { ExecuteQueryDS2(); } else { Console.WriteLine(result.Message); } } } }
using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.Linq; using System.Text; using MySql.Data.MySqlClient; using XiaoCai.DataAccess.Messages; using XiaoCai.DataAccess.MySQL; namespace XiaoCai.DataAccess.TestMySQLHelper.Test { [NUnit.Framework.TestFixture] class TestOracleHelper { private Helper _helper = new MySQLHelper(new MySqlConnection(ConfigurationManager.AppSettings["Database.SqlServerConn"])); [NUnit.Framework.Test] //不帶參數的方法 public void ExecuteQueryDS() { string sqlText = @"select * from T_AUTH_USER"; ExecutionResult result=_helper.ExecuteQueryDS(sqlText); if (result.Status) { DataSet ds = (DataSet) result.Anything; if (ds.Tables[0].Rows.Count > 0) { for (int i = 0; i < ds.Tables[0].Rows.Count; i++) { Console.WriteLine("UserId:" + ds.Tables[0].Rows[i][0] + ",User_Name:" + ds.Tables[0].Rows[i][1] + ",PASSWORD:" + ds.Tables[0].Rows[i][2]); } } } else { Console.WriteLine(result.Message); } } [NUnit.Framework.Test] //不帶參數的方法 public void ExecuteQueryDS2() { string sqlText = @"select * from T_AUTH_USER t where t.NAME=@UserName"; DBParameter dbParam=new DBParameter(); dbParam.Add("@UserName", "aganqin",new MySqlParameter()); ExecutionResult result = _helper.ExecuteQueryDS(sqlText,dbParam.GetParameters()); if (result.Status) { DataSet ds = (DataSet)result.Anything; if (ds.Tables[0].Rows.Count > 0) { for (int i = 0; i < ds.Tables[0].Rows.Count; i++) { Console.WriteLine("UserId:" + ds.Tables[0].Rows[i][0] + ",User_Name:" + ds.Tables[0].Rows[i][1] + ",PASSWORD:" + ds.Tables[0].Rows[i][2]); } } } } [NUnit.Framework.Test] //不帶參數的方法 public void ExecuteUpdate() { string sqlText = @"UPDATE T_AUTH_USER SET [PASSWORD]=@PASSWORD where [NAME]=@UserName"; DBParameter dbParam = new DBParameter(); dbParam.Add("@UserName", "aganqin", new MySqlParameter()); dbParam.Add("@PASSWORD", "123456", new MySqlParameter()); ExecutionResult result = _helper.ExecuteUpdate(sqlText, dbParam.GetParameters()); if (result.Status) { ExecuteQueryDS2(); } else { Console.WriteLine(result.Message); } } } }
測試結果以下:
<?xml version="1.0"?> <configuration> <appSettings> <add key="Database.SqlServerConn" value="Data Source=localhost,1433;Network Library=DBMSSOCN;Initial Catalog=SecurityDB;User ID=root;Password=12345;" /> </appSettings> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" /> </startup> </configuration>
不一樣數據庫類型相應變更。
基本到這裏結束,簡單增長几個增,刪,改,查的功能,後續添加上支持事務的數據庫幫助類。