step by step 之餐飲管理系統六(數據庫訪問模塊)


  距上次寫的博客已經好幾個月,一方面公司里面有很多的東西要學,平時的時候又要寫代碼,所以沒有及時更新,不過現在還好,已經成型了,現在把之前的東西貼出來,先看一下現在做的幾個界面吧。第一個界面是用顏色用區分台狀態的,后來感覺這樣沒有圖片好,於是用第二個界面

改進后的界面

系統登錄界面.

上面的截圖主要是前一段時間寫的台桌界面,回到數據庫訪問模塊吧.

數據庫訪問模塊在網上的資源也非常的多,所以我也不想講太多.

首先定義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實現的接口如下圖所示:查詢所有的實現對象,單個實體對象,然后就是插入,更新與刪除.

 上面主要講主要的構想,當然還要好多代碼要去寫,這里就不一一貼出來了,就是圍繞增刪查改來進行的,下次寫實體層,就是構建表的實體類,下面是為了生成這些代碼寫的代碼生成器,先一睹為快

寫這個工具還真沒有用多長時間,下次講具體的實現.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM