距上次寫的博客已經好幾個月,一方面公司里面有很多的東西要學,平時的時候又要寫代碼,所以沒有及時更新,不過現在還好,已經成型了,現在把之前的東西貼出來,先看一下現在做的幾個界面吧。第一個界面是用顏色用區分台狀態的,后來感覺這樣沒有圖片好,於是用第二個界面
改進后的界面
系統登錄界面.
上面的截圖主要是前一段時間寫的台桌界面,回到數據庫訪問模塊吧.
數據庫訪問模塊在網上的資源也非常的多,所以我也不想講太多.

首先定義DataAccess層的結構,用不同的文件夾區分它們,核心的類放在DBCore文件夾中,通用的類放在DBUtil中,然后再是配置類,Map中放ORM相關的類,其他的就是不同數據庫類型的相關類.
首稱定義數據庫訪問層要實現的接口,其實主要都差不多的啦
using System; using System.Data.Common; using System.Data; using System.Collections.Generic; namespace RMS.DataAccess { /// <summary> /// 數據庫通用操作接口. /// </summary> /// <author>xucj</author> /// <date>2013-05-15</date> public interface IDbOperation { /// <summary> /// 執行查詢,並返回查詢所返回的結果集中第一行的第一列. /// </summary> /// <param name="commandText">命令文本(SQL語句).</param> /// <returns>結果集中第一行的第一列.</returns> object ExecuteScalar(string commandText); /// <summary> /// 執行查詢,並返回查詢所返回的結果集中第一行的第一列. /// </summary> /// <param name="commandType">操作類型.</param> /// <param name="commandText">命令文本(SQL語句).</param> /// <returns>結果集中第一行的第一列.</returns> object ExecuteScalar(CommandType commandType, string commandText); /// <summary> /// /// </summary> /// <param name="commandText"></param> /// <returns></returns> DbDataReader ExecuteReader(string commandText); /// <summary> /// 返回DbDataReader對象. /// </summary> /// <param name="commandType">操作類型.</param> /// <param name="commandText">命令文本(SQL語句).</param> /// <returns>DbDataReader對象</returns> DbDataReader ExecuteReader(CommandType commandType, string commandText); /// <summary> /// 返回DbDataReader對象. /// </summary> /// <param name="commandType">操作類型.</param> /// <param name="commandText">命令文本(SQL語句).</param> /// <param name="commandParameters">命令參數.</param> /// <returns>DbDataReader對象</returns> DbDataReader ExecuteReader(CommandType commandType, string commandText, params DbParameter[] commandParameters); /// <summary> /// 對連接對象執行SQL語句. /// </summary> /// <param name="commandText">命令文本(SQL語句).</param> /// <returns>受影響的行數.</returns> int ExecuteNonQuery(string commandText); /// <summary> /// 對連接對象執行SQL語句. /// </summary> /// <param name="commandType">操作類型.</param> /// <param name="commandText">命令文本(SQL語句).</param> /// <returns>受影響的行數.</returns> int ExecuteNonQuery(CommandType commandType, string commandText); /// <summary> /// 對連接對象執行SQL語句. /// </summary> /// <param name="commandText">命令文本(SQL語句).</param> /// <param name="commandParameters">操作類型.</param> /// <returns>受影響的行數.</returns> int ExecuteNonQuery(string commandText, params DbParameter[] commandParameters); /// <summary> /// 對連接對象執行SQL語句. /// </summary> /// <param name="commandType">操作類型.</param> /// <param name="commandText">命令文本(SQL語句).</param> /// <param name="commandParameters">命令參數.</param> /// <returns>受影響的行數.</returns> int ExecuteNonQuery(CommandType commandType, string commandText, params DbParameter[] commandParameters); /// <summary> /// 對連接對象執行SQL語句. /// </summary> /// <param name="transaction">事務.</param> /// <param name="commandText">命令文本(SQL語句).</param> /// <returns>受影響的行數.</returns> int ExecuteNonQuery(DbTransaction transaction, string commandText); /// <summary> /// 對連接對象執行SQL語句. /// </summary> /// <param name="transaction">事務.</param> /// <param name="commandText">命令文本(SQL語句).</param> /// <param name="commandParameters">命令參數.</param> /// <returns>受影響的行數.</returns> int ExecuteNonQuery(DbTransaction transaction, string commandText, params DbParameter[] commandParameters); /// <summary> /// 返回DataSet數據集. /// </summary> /// <param name="commandText">命令文本(SQL語句).</param> /// <returns>DataSet數據集</returns> DataSet FillDataset(string commandText); /// /// <summary> /// 返回DataSet數據集. /// </summary> /// /// <param name="transaction">事務.</param> /// <param name="commandText">命令文本(SQL語句).</param> /// <returns>DataSet數據集</returns> DataSet FillDataset(DbTransaction transaction, string commandText); /// <summary> /// 返回DataSet數據集. /// </summary> /// <param name="commandText">命令文本(SQL語句).</param> /// <param name="commandParameters">命令參數.</param> /// <returns>DataSet數據集.</returns> DataSet FillDataset(string commandText, params DbParameter[] commandParameters); /// <summary> /// 返回DataSet數據集. /// </summary> /// <param name="transaction">事務.</param> /// <param name="commandText">命令文本(SQL語句).</param> /// <param name="commandParameters">命令參數.</param> /// <returns>DataSet數據集.</returns> DataSet FillDataset(DbTransaction transaction, string commandText, params DbParameter[] commandParameters); /// <summary> /// 返回DataSet數據集. /// </summary> /// <param name="commandType">操作類型.</param> /// <param name="commandText">命令文本(SQL語句).</param> /// <returns>DataSet數據集.</returns> DataSet FillDataset(CommandType commandType, string commandText); /// <summary> /// 返回DataSet數據集. /// </summary> /// <param name="commandType">操作類型.</param> /// <param name="commandText">命令文本(SQL語句).</param> /// <param name="parameters">命令參數.</param> /// <returns>DataSet數據集.</returns> DataTable FillDataTable(CommandType commandType, string commandText, params DbParameter[] parameters); /// <summary> /// 返回DataSet數據集. /// </summary> /// <param name="commText">命令文本(SQL語句).</param> /// <returns>DataSet數據集.</returns> DataTable FillDataTable(string commText); /// <summary> /// 返回DataSet數據集. /// </summary> /// <param name="commandType">操作類型.</param> /// <param name="commText">命令文本(SQL語句).</param> /// <returns>DataSet數據集.</returns> DataTable FillDataTable(CommandType commandType, string commText); /// <summary> /// 返回DataSet數據集. /// </summary> /// <param name="commandType">操作類型.</param> /// <param name="commandText">命令文本(SQL語句).</param> /// <param name="commandParameters">命令參數.</param> /// <returns>DataSet數據集.</returns> DataSet FillDataset(CommandType commandType, string commandText, params DbParameter[] commandParameters); } }
然后定義工廠類,這里主要使用泛型,我們知道不同的數據庫訪問主要是引擎名稱與連接字符串不同,所以把它們定義成泛型
using System; using System.Data; using System.Data.Common; using RMS.Logging; namespace RMS.DataAccess { /// <summary> /// 數據庫工廠類. /// </summary> /// <typeparam name="C">實現IDbConnectionString接口的連接串類.</typeparam> /// <typeparam name="P">實現IDbProviderName接口的數據庫引擎名稱.</typeparam> public class DbFactory<C, P> where C : IDbConnectionString, new() where P : IDbProviderName, new() { #region private member /// <summary> /// 數據引擎實現工廠. /// </summary> private static DbProviderFactory m_factory; /// <summary> /// 數據引擎實現工廠接口. /// </summary> private static IDbProvider m_provider = null; private static object lockObject = new object(); #endregion /// <summary> /// 返回實現IDbProvider接口的具體數據引擎. /// </summary> public static IDbProvider Provider { get { if (m_provider == null) { lock (lockObject) { if (m_provider == null) { string providerName = typeof(DbFactory<C, P>).Namespace + "." + new P().DbProviderName + "Provider"; // 用於反射 try { m_provider = (IDbProvider)Activator.CreateInstance(Type.GetType(providerName)); } catch (DbException dex) { LoggerManager.GetILog("Data Provider").Error(dex.StackTrace); throw new Exception("創建數據庫實例失敗,請確認存在 " + providerName + " 的類"); } } } } return m_provider; } } /// <summary> /// 數據庫引擎實現工廠. /// </summary> public static DbProviderFactory Factory { get { if (m_factory == null) { m_factory = Provider.Instance(); } return m_factory; } } /// <summary> /// 重置數據引擎. /// </summary> public static void ResetDbProvider() { m_factory = null; m_provider = null; } #region Make parameter. /// <summary> /// 生成參數. /// </summary> /// <param name="ParamName">參數名稱.</param> /// <param name="DbType">參數類型.</param> /// <param name="Size">參數大小..</param> /// <param name="Value">參數值.</param> /// <returns>生成后的參數.</returns> public static DbParameter MakeInParam(string ParamName, DbTypeWrapper DbType, int Size, object Value) { return MakeParam(ParamName, DbType, Size, ParameterDirection.Input, Value); } /// <summary> /// 生成參數. /// </summary> /// <param name="ParamName">參數名稱.</param> /// <param name="DbType">參數類型.</param> /// <param name="Value">參數值.</param> /// <returns>生成后的參數.</returns> public static DbParameter MakeInParam(string ParamName, DbTypeWrapper DbType, object Value) { return MakeParam(ParamName, DbType, 0, ParameterDirection.Input, Value); } /// <summary> /// 生成參數. /// </summary> /// <param name="ParamName">參數名稱.</param> /// <param name="DbType">參數類型.</param> /// <param name="Size">參數大小.</param> /// <returns>生成后的參數.</returns> public static DbParameter MakeOutParam(string ParamName, DbTypeWrapper DbType, int Size) { return MakeParam(ParamName, DbType, Size, ParameterDirection.Output, null); } /// <summary> /// 生成參數. /// </summary> /// <param name="ParamName">參數名稱.</param> /// <param name="DbType">參數類型.</param> /// <param name="Size">參數大小.</param> /// <param name="Direction">參數方向.</param> /// <param name="Value">參數值.</param> /// <returns>生成后的參數.</returns> public static DbParameter MakeParam(string ParamName, DbTypeWrapper DbType, Int32 Size, ParameterDirection Direction, object Value) { DbParameter param; param = Provider.MakeParam(ParamName, DbType, Size); param.Direction = Direction; if(!(Direction == ParameterDirection.Output && Value == null)) { param.Value = Value; } return param; } #endregion Make parameter end } }
這樣根據不同的數據庫使用不同的引擎名稱與字符串,就實現了類似多態的功能,下面是實現接口的具體方法,代碼太多,就截圖了
為了實現一個ORM,定義下面的類, T就是對應數據庫表的一個實體類
下面是獲取T所表示的對象的屬性值,后面會根據它的值來生成Sql語句.
this.m_type = typeof(T); string tablename = string.Empty; if(!this.m_type.IsClass) { throw new Exception("Only class is supported!"); } object[] attributes = this.m_type.GetCustomAttributes(false); if(attributes.Length > 0) { foreach(object attr in attributes) { if(attr is DataTableNameAttribute) { tablename = (attr as DataTableNameAttribute).TableName; containsIdentification = (attr as DataTableNameAttribute).ContainsIdentification; } } } else { tablename = m_type.Name; } this.m_tableName = tablename.ToUpper(); List<string> paramnames = new List<string>(); Dictionary<string, PropertyInfo> dicPropertyInfo = new Dictionary<string, PropertyInfo>(); foreach(PropertyInfo propertyInfo in m_type.GetProperties()) { paramnames.Add(propertyInfo.Name); dicPropertyInfo[propertyInfo.Name] = propertyInfo; } this.m_propertyInfoDictonary = dicPropertyInfo; this.m_propertyNameList = paramnames; int colCount = this.m_propertyNameList.Count; this.m_dbParams = new string[colCount + 1]; this.m_fullDbParamsForUpdateOrDelete = new string[colCount * 2 + 1]; this.m_dbParams[0] = "TransactionStatement"; this.m_fullDbParamsForUpdateOrDelete[0] = "TransactionStatement"; for(int index = 1; index <= colCount; index++) { string colname = this.m_propertyNameList[index - 1].ToUpper(); this.m_dbParams[index] = colname; this.m_fullDbParamsForUpdateOrDelete[index] = colname; this.m_fullDbParamsForUpdateOrDelete[index + colCount] = String.Concat("where_", colname); } }
ORM實現的接口如下圖所示:查詢所有的實現對象,單個實體對象,然后就是插入,更新與刪除.
上面主要講主要的構想,當然還要好多代碼要去寫,這里就不一一貼出來了,就是圍繞增刪查改來進行的,下次寫實體層,就是構建表的實體類,下面是為了生成這些代碼寫的代碼生成器,先一睹為快
寫這個工具還真沒有用多長時間,下次講具體的實現.
