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实现的接口如下图所示:查询所有的实现对象,单个实体对象,然后就是插入,更新与删除.

上面主要讲主要的构想,当然还要好多代码要去写,这里就不一一贴出来了,就是围绕增删查改来进行的,如果要要源码的请mark下并推荐下,我会把注释与代码整理好发到相应的地方,如果没人相应那就算了,下次写实体层,就是构建表的实体类,下面是为了生成这些代码写的代码生成器,先一睹为快

写这个工具还真没有用多长时间,下次讲具体的实现.

时间: 2024-08-18 02:57:05

step by step 之餐饮管理系统六(数据库访问模块)的相关文章

step by step 之餐饮管理系统五(Util模块)

这段时间一直在修改日志模块,现在基本上写好了,也把注释什么的都加上了,昨天邮件发送给mark的园友一直报失败,老是退回来,真是报歉,如下图所示: 没有办法,只好放这里了,想看源代码的请猛戳这里 如果有什么问题,欢迎跟我交流! 从今天开始写Util模块,这个模块几乎所有的系统项目都需要的,想减少重复代码的编写,就依靠这个模块了.大的模块主要是以下几个方面: 1.加解密 这个我也不多说了,也就是MD5等加密算法: using System; using System.Security.Cryptog

在数据库访问项目中使用微软企业库Enterprise Library,实现多种数据库的支持

在我们开发很多项目中,数据访问都是必不可少的,有的需要访问Oracle.SQLServer.Mysql这些常规的数据库,也有可能访问SQLite.Access,或者一些我们可能不常用的PostgreSQL.IBM DB2.或者国产达梦数据库等等,这些数据库的共同特点是关系型数据库,基本上开发的模型都差不多,不过如果我们基于ADO.NET的基础上进行开发的话,那么各种数据库都有自己不同的数据库操作对象,微软企业库Enterprise Library是基于这些不同数据库的操作做的抽象模型,适合多数据

step by step 之餐饮管理系统二

昨天写了餐饮管理系统的相关需求,得到了园友的一些好的建议,感到很高兴,确实写的也不全面,现在补充一下需要的业务,这次主要做的主要是前台收银系统,所以业务主要集中在前台点菜收银这块,而后面数据管理这块则暂时先不考虑. 至于像权限,不同的组门应该有不同的权限不同级别的员工也有相应的权限,比如收银员只有9折的打折权限,而收银主管则可以打折到8.5折,而经理可以打折到8折.至于一个园友说的前景,希望系统可以应用在中小型的餐饮,都说民以食为天,特别是现在社会发展如此快,人民对生活水平的需求越来越高,她们不

数据库设计 Step by Step (1)——扬帆启航

引言:一直在从事数据库开发和设计工作,也看了一些书籍,算是略有心得.很久之前就想针 对关系数据库设计进行整理.总结,但因为种种原因迟迟没有动手,主要还是惰性使然.今天也算是痛下决心开始这项卓绝又令我兴奋的工作.这将是一个系列的文 章,我将以讲座式的口吻展开讨论(个人偷懒,这里的总结直接拿去公司培训新人用). 系列的第一讲我们先来回答下面几个问题 数据库是大楼的根基 大多数程序员都很急切,在了解基本需求之后希望很快的进入到编码阶段(可能只有产出代码才能反映工作量),对于数据库设计思考得比较少. 这

数据库设计 Step by Step (2)——数据库生命周期

引言:数据库设计 Step by Step (1)得到这么多朋友的关注着实出乎了我的意外.这也坚定了我把这一系列的博文写好的决心.近来工作上的事务比较繁重,加之我期望这个系列的文章能尽可能的系统.完整,需要花很多时间整理.思考数据库设计的各种资料,所以文章的更新速度可能会慢一些,也希望大家能够谅解. 系列的第二讲我们将站在高处俯瞰一下数据库的生命周期,了解数据库设计的整体流程 数据库生命周期 大家对软件生命周期较为熟悉,数据库也有其生命周期,如下图所示. 图(1)数据库生命周期 数据库的生命周期

step byt step之餐饮管理系统一

之前写过2015年的工作计划,其中有一项就是写一套管理系统,一来可以练练手,二来可以加强自己的学习,三来可以多园友多交流,共同进步.所以从今天开始把写系统的过程记录下来.先需求分析开始. 第一部分 引言 一.编写目的 1.此分析说明书整理餐饮收银系统中的需求,为后面的系统设计作准备,也就是描述了项目设计的要求. 二.背景 1.名称:餐饮管理系统,英文缩写名:RMS(restaurant manager system). 2.任务提出者:LZ 开发者:LZ, 本系统将实现客人进入餐饮邢台,点菜,传

SQL Server 维护计划实现数据库备份(Step by Step)(转)

SQL Server 维护计划实现数据库备份(Step by Step) 一.前言 SQL Server 备份和还原全攻略,里面包括了通过SSMS操作还原各种备份文件的图形指导,SQL Server 数据库最小宕机迁移方案,里面使用SQL脚本(T-SQL)完成完全备份.差异备份.完全还原.差异还原等:        有了上面的基础,我们加入了数据库的备份元素,通过维护计划来生成数据库的备份文件,这包括两种文件,数据库的完全备份与差异备份,有了这两个文件,我们可以通过SQL Server 备份和还

WPF Step By Step 自定义模板

WPF Step By Step 自定义模板 回顾 上一篇,我们简单介绍了几个基本的控件,本节我们将讲解每个控件的样式的自定义和数据模板的自定义,我们会结合项目中的具体的要求和场景来分析,给出我们实现的方案和最终的运行效果. 本文大纲 1.控件模板及数据模板 2.ListBox深度定制模板. 3.TreeView高级模板使用实例. 控件模板及数据模板 控件模板 什么是控件模板,指定可以在控件的多个实例之间共享 Control 的可视结构和性能方面的方面.控件模板其实就是我们在可视方面的自定义模板

WinForm RDLC SubReport Step by step

最近在做的一个PO管理系统,因为要用到订单打印,没有用水晶报表,直接使用VS2010的Reporting.参考了网上的一些文章,但因为找到的数据是用于WebForm的,适配到WinForm有点区别,竟然花了很久才搞通.所以现在做个Step By Step以记录. 参考Jimmy.Yang的博文: http://www.cnblogs.com/yjmyzz/archive/2011/09/19/2180940.html 开发环境:      VS2010 C# 第一步,新建项目 2.在项目中新建数