zoukankan      html  css  js  c++  java
  • 自己动手写ORM框架(二):AdoHelper支持多数据库操作的封装(2)

    在上一篇文章中已经分析了AdoHelper的部分代码,接下来将继续分析剩余的部分代码,这里分析ExecuteNonQuery方法的实现,代码块1-1:

    // <summary>
    //通过提供的参数,执行无结果集的数据库操作命令
    // 并返回执行数据库操作所影响的行数。
    // </summary>
    // <param name="connectionString">数据库连接字符串</param>
    // <param name="commandType">执行命令的类型(存储过程或T-SQL,等等)</param>
    // <param name="commandText">存储过程名称或者T-SQL命令行<</param>
    // <param name="commandParameters">执行命令所需的参数数组</param>
    // <returns>返回通过执行命令所影响的行数</returns>
    public static int ExecuteNonQuery(string connectionString, CommandType cmdType, string cmdText, params IDbDataParameter[] commandParameters)
    {
        IDbCommand cmd = DbFactory.CreateDbCommand();
    
        using (IDbConnection conn = DbFactory.CreateDbConnection(connectionString))
        {
            PrepareCommand(cmd, conn, null, cmdType, cmdText, commandParameters);
            int val = cmd.ExecuteNonQuery();
            cmd.Parameters.Clear();
            return val;
        }
    }
    //=============================================================================================
    public static int ExecuteNonQuery(string connectionString, CommandType cmdType, string cmdText)
    {
        IDbCommand cmd = DbFactory.CreateDbCommand();
    
        using (IDbConnection conn = DbFactory.CreateDbConnection(connectionString))
        {
            PrepareCommand(cmd, conn, null, cmdType, cmdText, null);
            int val = cmd.ExecuteNonQuery();
            cmd.Parameters.Clear();
            return val;
        }
    }
    //=============================================================================================
    public static int ExecuteNonQuery(IDbConnection connection, CommandType cmdType, string cmdText, params IDbDataParameter[] commandParameters)
    {
        IDbCommand cmd = DbFactory.CreateDbCommand();
    
        PrepareCommand(cmd, connection, null, cmdType, cmdText, commandParameters);
        int val = cmd.ExecuteNonQuery();
        cmd.Parameters.Clear();
        return val;
    }
    //=============================================================================================
    public static int ExecuteNonQuery(IDbConnection connection, CommandType cmdType, string cmdText)
    {
        IDbCommand cmd = DbFactory.CreateDbCommand();
    
        PrepareCommand(cmd, connection, null, cmdType, cmdText, null);
        int val = cmd.ExecuteNonQuery();
        cmd.Parameters.Clear();
        return val;
    }
    //=============================================================================================
    // <summary>
    //通过提供的参数,执行无结果集返回的数据库操作命令
    //并返回执行数据库操作所影响的行数。
    // </summary>
    // <remarks>
    // e.g.:  
    //  int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
    // </remarks>
    // <param name="trans">sql事务对象</param>
    // <param name="commandType">执行命令的类型(存储过程或T-SQL,等等)</param>
    // <param name="commandText">存储过程名称或者T-SQL命令行<</param>
    // <param name="commandParameters">执行命令所需的参数数组</param>
    // <returns>返回通过执行命令所影响的行数</returns>
    public static int ExecuteNonQuery(IDbTransaction trans, CommandType cmdType, string cmdText, params IDbDataParameter[] commandParameters)
    {
        IDbConnection conn = null;
        if (trans == null)
        {
            conn = DbFactory.CreateDbConnection(ConnectionString);
        }
        else 
        {
            conn = trans.Connection;
        }
    
        IDbCommand cmd = DbFactory.CreateDbCommand();
        PrepareCommand(cmd, conn, trans, cmdType, cmdText, commandParameters);
        int val = cmd.ExecuteNonQuery();
        cmd.Parameters.Clear();
        return val;
    }
    //=============================================================================================
    public static int ExecuteNonQuery(IDbTransaction trans, CommandType cmdType, string cmdText)
    {
        IDbCommand cmd = DbFactory.CreateDbCommand();
        PrepareCommand(cmd, trans.Connection, trans, cmdType, cmdText, null);
        int val = cmd.ExecuteNonQuery();
        cmd.Parameters.Clear();
        return val;
    }
    //=============================================================================================

    上面都是对ExecuteNonQuery方法的重载,仅仅是参数有所变化,下面将第一个方法进行逐行的分析。

    line 1:public static int ExecuteNonQuery(string connectionString, CommandType cmdType, string cmdText, params IDbDataParameter[] commandParameters)

    参数1: string connectionString =>  数据库连接所需连接字符串

    参数2: CommandType cmdType=> 执行命令的类型(存储过程或T-SQL,等等)

    参数3: string cmdText=> 存储过程名称或者T-SQL命令行

    参数4: params IDbDataParameter[] commandParameters=>执行命令所需的参数数组

    line 2:IDbCommand cmd = DbFactory.CreateDbCommand();

        这里通过DbFactory类创建IDbCommand接口的实现类对象,这里为什么使用IDbCommand接口呢,如果我们项目中使用的SqlServer数据库的时候,我们习惯这样创建:

    SqlCommand cmd = new SqlCommand();

        但是如果这个项目上线了一阵,客户突然说要换成Oracle数据库,那么所有写成SqlCommand的地方都要改成OracleCommand,但要改的并不仅仅这些,计划所有ADO.NET与数据库相关的,比如SqlConnectionSqlDataAdapterSqlParameterSqlTransaction等等全部都要改,这工作量是很大的,还不说改动这么多会出现什么问题,所以我们可以通过工厂模式,采用面向接口编程来解决这个问题!

        下面我们看看DbFactory是如何工作的,代码块1-2:

    // <summary>
    // 根据配置文件中所配置的数据库类型
    // 来创建相应数据库命令对象
    // </summary>
    // <returns></returns>
    public static IDbCommand CreateDbCommand()
    {
        IDbCommand cmd = null;
        switch (AdoHelper.DbType)
        {
            case DatabaseType.SQLSERVER:
                cmd = new SqlCommand();
                break;
            case DatabaseType.ORACLE:
                cmd = new OracleCommand();
                break;
            case DatabaseType.ACCESS:
                cmd = new OleDbCommand();
                break;
            default: 
                throw new Exception("数据库类型目前不支持!");
        }
    
        return cmd;
    }
     

        这是DbFactory类中的静态方法CreateDbCommand(),根据AdoHelper类中获取到配置文件配置的数据库类型DbType,来创建对应数据库类型的Command对象,通过反编译System.Data.dll,我们可以知道SqlCommandOracleCommandOleDbCommand等等Command都实现了IDbCommand接口,这样我们将创建好的对象以IDbCommand接口类型返回即可。

    line 3:using (IDbConnection conn = DbFactory.CreateDbConnection(connectionString))

        根据数据库连接字符串connectionString,通过DbFactory.CreateDbConnection方法创建数据库连接对象,这里同样使用到了接口IDbConnection ,好处多多就不在此罗嗦了。

    line 4:PrepareCommand(cmd, conn, null, cmdType, cmdText, commandParameters);

        这里是将所有cmd对象所需的参数都传入PrepareCommand方法中,将参数给cmd对象,为执行数据操作做好准备工作,具体实现看代码块1-3:

    // <summary>
    // 为即将执行准备一个命令
    // </summary>
    // <param name="cmd">SqlCommand对象</param>
    // <param name="conn">SqlConnection对象</param>
    // <param name="trans">IDbTransaction对象</param>
    // <param name="cmdType">执行命令的类型(存储过程或T-SQL,等等)</param>
    // <param name="cmdText">存储过程名称或者T-SQL命令行, e.g. Select * from Products</param>
    // <param name="cmdParms">SqlParameters to use in the command</param>
    private static void PrepareCommand(IDbCommand cmd, IDbConnection conn, IDbTransaction trans, CommandType cmdType, string cmdText, IDbDataParameter[] cmdParms)
    {
        if (conn.State != ConnectionState.Open)
            conn.Open();
    
        cmd.Connection = conn;
        cmd.CommandText = cmdText;
    
        if (trans != null)
            cmd.Transaction = trans;
    
        cmd.CommandType = cmdType;
    
        if (cmdParms != null)
        {
            foreach (IDbDataParameter parm in cmdParms)
            cmd.Parameters.Add(parm);
        }
    }

        这里代码主要实现了将打开后的数据库连接对象conn、SQL语句cmdText、事物对象trans、执行命令的类型cmdType、以及命令参数cmdParms全部赋给cmd对象,为执行数据操作作准备。

    line 5、6、7:

    int val = cmd.ExecuteNonQuery();

    cmd.Parameters.Clear();

    return val;

    这里是cmd对象执行命令、清除cmd对象中的参数、返回执行操作后所影响的行数。

        分析完这个方法后,其它的方法都是大同小异,也无需再进行分析了,这里主要的重点就是采用接口编程,DbFactory是重点,这样用的好处我们能看得到,我们不需要在更换数据库类型的时候去更改任何代码,仅仅只需在web.config中将数据库类型dbType更改,除非你的数据库类型在DbFactory中不支持,即便不支持,也只需在DbFactory中添加少量的几行代码!

        至此,ExecuteNonQuery方法已经分析完成,后续还会继续分析AdoHelper类中的其它方法。

    Technorati 标签: ORM
  • 相关阅读:
    Java多线程实现1,继承Thread类
    Java学习笔记二:初始化(一)
    Java学习笔记一:对象与存储
    数据结构学习笔记4.5--二叉树效率
    数据结构学习笔记4.4--删除节点
    数据结构学习笔记4.3--遍历树
    数据结构学习笔记4.2--插入节点
    数据结构学习笔记4.1--查找节点
    数据结构学习笔记3.2—快速排序
    数据结构学习笔记3.1--划分
  • 原文地址:https://www.cnblogs.com/wangwei123/p/1766325.html
Copyright © 2011-2022 走看看