zoukankan      html  css  js  c++  java
  • 通过反射,将datatable转换为List集合(反射读取实体类的属性,并赋值),通过接口来实现MySql和MsSql数据的切换(二层反射),静态构造函数,抽象类和接口的区别

    image

    1: BLL层的  DataProvider.cs   这个类,是一个抽象类,用来描述各种各样的DAL层的方法(但是没有方法的实现),他是DAL层的 MySqlDataProvider.cs的基类

    同时,他还根据 web.config 里面设置的 数据库的类型,来反射是 MySql的数据库操作,还是MsSql的数据库的操作

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Data;
    using System.Configuration;
    using Model;
    
    namespace BLL
    {
        public abstract class DataProvider  //这个抽象类,相当于是父类
        {
            private static DataProvider objProvider = null;
    
            //读取需要反射的类型, 是mysql还是mssql
            private static string DataBaseType = ConfigurationManager.AppSettings["DataBaseType"];
    
            //静态构造函数,在类初始化的时候执行,不用加 public / private 没有意义,因为这个.net自动来调用
            //在创建第一个类实例或任何静态成员被引用时,.NET将自动调用静态构造函数来初始化类
            static DataProvider()   
            {
                Type type = Type.GetType(DataBaseType, true);
                objProvider = (DataProvider)Activator.CreateInstance(type);//反射一个数据库操作类的实例,并用父类来指向
            }
    
            public static DataProvider Instance()
            {
                return objProvider;
            }
    
            #region 用户添加的各种 抽象方法
            //获得所有的人,返回一个datatable
            public abstract DataTable GetAllPerson();
    
            //添加一个人
            public abstract bool AddUser(Model.Person p);
    
            //获得所有的人,这里用的是用T来表示 泛型约束
            public abstract List<T> GetList<T>(DataTable dt);
            #endregion
        }
    }
    
    

    web.config

    <appSettings>
            <add key="DataBaseType" value="DAL.MySqlDataProvider,DAL"/>
        </appSettings>
        <connectionStrings>
            <add name="connStr" connectionString="database=fanshetest;Password=123456;uid=root;server=localhost;Port=3306;" />
        </connectionStrings>
    

     

     

    2: DAL层的 MySqlProvider.cs  ,继承 BLL层的 DataProvider.cs  ,实现里面的各个读取数据库增删改查的方法。同时,也有反射在里面,用于根据 Model层来反射出Model层的各个属性,把数据表每一行的每一个字段的值,赋值给每个Model的属性

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Data;              //datatable之类
    using MySql.Data.MySqlClient;   //mysql
    using Model;                    //实体
    using System.Reflection;        //反射
    using BLL;
    
    namespace DAL
    {
        public class MySqlDataProvider :BLL.DataProvider
        {
    
            //mysql数据库的助手类
            MySqlHelper helper = null;
            public MySqlDataProvider()
            {
                helper = new MySqlHelper();
            }
            //获得所有的人,返回一个datatable
            public override DataTable GetAllPerson()
            {
                DataTable dt = new DataTable();
                MySqlDataReader dr = helper.ExecuteReader(System.Data.CommandType.Text, "select * from person");
                dt.Load(dr);
                return dt;
            }
    
            //添加一个人
            public override bool AddUser(Model.Person p)
            {
                MySqlParameter[] para = new MySqlParameter[]{
                    new MySqlParameter("@UserName",MySqlDbType.VarChar,200),
                    new MySqlParameter("@AddTime",MySqlDbType.DateTime),
                    new MySqlParameter("@Address",MySqlDbType.VarChar,200)
                };
                para[0].Value = p.UserName;
                para[1].Value = p.AddTime;
                para[2].Value = p.Address;
                int res = helper.ExecuteNonQuery(CommandType.Text, "INSERT INTO person(UserName,AddTime,Address) VALUES(@UserName,@AddTime,@Address)", para);
                return res > 0 ? true : false;
            }
    
            //获得所有的人,这里用的是用T来表示 泛型约束
            public override List<T> GetList<T>(DataTable dt)
            {
                List<T> list = new List<T>();
    
                if (dt == null || dt.Rows.Count < 1) return list;
    
                //default(int) 则是0    default(Person)表示person的默认值,也就是null。
    
                //default(T)的值是null,也就是说 T t出来的值是null,可否直接相当于是 T t出来一个Model.Person呢?
                //可以,Activator.CreateInstance<T>()实例出来的就是Model.Person 
                //那么下面获得所有属性可以用 t.GetType().GetProperties()
                T t = default(T);
    
                System.Reflection.PropertyInfo[] pro = typeof(T).GetProperties();//t不为null的时候可以用t.GetType().GetProperties()
    
                foreach (DataRow row in dt.Rows)        //循环每一行的值
                {
                    t = Activator.CreateInstance<T>(); //每次循环,必须重新弄一个出来
                    foreach (PropertyInfo item in pro)  //循环每一列,进行绑定
                    {
                        string tempname = item.Name;
                        object value = row[tempname];
    
                        //数据库里面的值不能为null,或者说不能为System.DBNull
                        item.SetValue(t, value, null);//这里是用的属性来绑定值  属性.SetValue(你要绑定的对象,属性值,索引)
                    }
                    list.Add(t);
    
                }
    
                return list;
            }
        }
    }
    
    

     

    3: DAL层的 MySqlHelper.cs  这个是 Mysql数据库的数据库操作助手类,用于编写  最底层的代码,实际就是最底层的 ExecuteNonQuery,ExecuteScalar,ExecuteReader

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Data;
    using System.Configuration;//不仅仅在这里学using,还要在项目中右键引用
    using MySql.Data.MySqlClient;// MySql
    
    
    namespace DAL
    {
        /// <summary>基于MySQL的数据层基类
        /// 
        /// </summary>
        public  class MySqlHelper
        {
            #region 数据库连接字符串
            public readonly static string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["connStr"].ToString();
            #endregion
    
            #region PrepareCommand -> Command预处理
            /// <summary>
            /// Command预处理
            /// </summary>
            /// <param name="conn">MySqlConnection对象</param>
            /// <param name="trans">MySqlTransaction对象,可为null</param>
            /// <param name="cmd">MySqlCommand对象</param>
            /// <param name="cmdType">CommandType,存储过程或命令行</param>
            /// <param name="cmdText">SQL语句或存储过程名</param>
            /// <param name="cmdParms">MySqlCommand参数数组,可为null</param>
            private  void PrepareCommand(MySqlConnection conn, MySqlTransaction trans, MySqlCommand cmd, CommandType cmdType, string cmdText, MySqlParameter[] 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 (MySqlParameter parm in cmdParms)
                        cmd.Parameters.Add(parm);
                }
            }
            #endregion
    
            #region ExecuteNonQuery  ->执行命令
            /// <summary>
            /// 执行命令
            /// </summary>
            /// <param name="cmdType">命令类型(存储过程或SQL语句)</param>
            /// <param name="cmdText">SQL语句或存储过程名</param>
            /// <param name="cmdParms">MySqlCommand参数数组</param>
            /// <returns>返回受引响的记录行数</returns>
            public  int ExecuteNonQuery( CommandType cmdType, string cmdText, params MySqlParameter[] cmdParms)
            {
                MySqlCommand cmd = new MySqlCommand();
    
                using (MySqlConnection conn = new MySqlConnection(connectionString))
                {
                    PrepareCommand(conn, null, cmd, cmdType, cmdText, cmdParms);
                    int val = cmd.ExecuteNonQuery();
                    cmd.Parameters.Clear();
                    return val;
                }
            }
    
            /// <summary>
            /// 执行命令
            /// </summary>
            /// <param name="conn">Connection对象</param>
            /// <param name="cmdType">命令类型(存储过程或SQL语句)</param>
            /// <param name="cmdText">SQL语句或存储过程名</param>
            /// <param name="cmdParms">MySqlCommand参数数组</param>
            /// <returns>返回受引响的记录行数</returns>
            public  int ExecuteNonQuery(MySqlConnection conn, CommandType cmdType, string cmdText, params MySqlParameter[] cmdParms)
            {
                MySqlCommand cmd = new MySqlCommand();
    
                PrepareCommand(conn, null, cmd, cmdType, cmdText, cmdParms);
                int val = cmd.ExecuteNonQuery();
                cmd.Parameters.Clear();
                return val;
            }
    
            /// <summary>
            /// 执行事务
            /// </summary>
            /// <param name="trans">MySqlTransaction对象</param>
            /// <param name="cmdType">命令类型(存储过程或SQL语句)</param>
            /// <param name="cmdText">SQL语句或存储过程名</param>
            /// <param name="cmdParms">MySqlCommand参数数组</param>
            /// <returns>返回受引响的记录行数</returns>
            public  int ExecuteNonQuery(MySqlTransaction trans, CommandType cmdType, string cmdText, params MySqlParameter[] cmdParms)
            {
                MySqlCommand cmd = new MySqlCommand();
    
                PrepareCommand(trans.Connection, trans, cmd, cmdType, cmdText, cmdParms);
                int val = cmd.ExecuteNonQuery();
                cmd.Parameters.Clear();
                return val;
            }
            #endregion
    
            #region ExecuteScalar ->执行命令,返回第一行第一列的值
            /// <summary>
            /// 执行命令,返回第一行第一列的值
            /// </summary>
            /// <param name="cmdType">命令类型(存储过程或SQL语句)</param>
            /// <param name="cmdText">SQL语句或存储过程名</param>
            /// <param name="cmdParms">MySqlCommand参数数组</param>
            /// <returns>返回Object对象</returns>
            public  object ExecuteScalar( CommandType cmdType, string cmdText, params MySqlParameter[] cmdParms)
            {
                MySqlCommand cmd = new MySqlCommand();
    
                using (MySqlConnection connection = new MySqlConnection(connectionString))
                {
                    PrepareCommand(connection, null, cmd, cmdType, cmdText, cmdParms);
                    object val = cmd.ExecuteScalar();
                    cmd.Parameters.Clear();
                    return val;
                }
            }
    
            /// <summary>
            /// 执行命令,返回第一行第一列的值
            /// </summary>
            /// <param name="connectionString">数据库连接字符串</param>
            /// <param name="cmdType">命令类型(存储过程或SQL语句)</param>
            /// <param name="cmdText">SQL语句或存储过程名</param>
            /// <param name="cmdParms">MySqlCommand参数数组</param>
            /// <returns>返回Object对象</returns>
            public  object ExecuteScalar(MySqlConnection conn, CommandType cmdType, string cmdText, params MySqlParameter[] cmdParms)
            {
                MySqlCommand cmd = new MySqlCommand();
    
                PrepareCommand(conn, null, cmd, cmdType, cmdText, cmdParms);
                object val = cmd.ExecuteScalar();
                cmd.Parameters.Clear();
                return val;
            }
            #endregion
    
            #region ExecuteReader ->执行命令或存储过程,返回MySqlDataReader对象
            /// <summary>
            /// 执行命令或存储过程,返回MySqlDataReader对象
            /// 注意MySqlDataReader对象使用完后必须Close以释放MySqlConnection资源
            /// </summary>
            /// <param name="cmdType">命令类型(存储过程或SQL语句)</param>
            /// <param name="cmdText">SQL语句或存储过程名</param>
            /// <param name="cmdParms">MySqlCommand参数数组</param>
            /// <returns></returns>
            public  MySqlDataReader ExecuteReader( CommandType cmdType, string cmdText, params MySqlParameter[] cmdParms)
            {
                MySqlCommand cmd = new MySqlCommand();
                MySqlConnection conn = new MySqlConnection(connectionString);
    
                try
                {
                    PrepareCommand(conn, null, cmd, cmdType, cmdText, cmdParms);
                    MySqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                    cmd.Parameters.Clear();
                    return dr;
                }
                catch
                {
                    conn.Close();
                    throw;
                }
            }
            #endregion
    
            #region ExecuteDataSet ->执行命令或存储过程,返回DataSet对象
            /// <summary>
            /// 执行命令或存储过程,返回DataSet对象
            /// </summary>
            /// <param name="cmdType">命令类型(存储过程或SQL语句)</param>
            /// <param name="cmdText">SQL语句或存储过程名</param>
            /// <param name="cmdParms">MySqlCommand参数数组(可为null值)</param>
            /// <returns></returns>
            public  DataSet ExecuteDataSet( CommandType cmdType, string cmdText, params MySqlParameter[] cmdParms)
            {
                MySqlCommand cmd = new MySqlCommand();
    
                using (MySqlConnection conn = new MySqlConnection(connectionString))
                {
                    PrepareCommand(conn, null, cmd, cmdType, cmdText, cmdParms);
                    MySqlDataAdapter da = new MySqlDataAdapter(cmd);
                    DataSet ds = new DataSet();
                    da.Fill(ds);
                    conn.Close();
                    cmd.Parameters.Clear();
                    return ds;
                }
            }
            #endregion
    
        }
    }
    
    

    4:Model层的 Person 类,对应数据库里面的数据结构


    using
    System;
    using System.Collections.Generic;
    using System.Text;

    namespace Model
    {
        public class Person
       
    {
            public int Id { get; set; }
            public string UserName { get; set; }
            public DateTime AddTime { get; set; }
            public string Address { get; set; }
        }
    }

    5:前台页面调用方式


    using
    System; using System.Collections.Generic; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using BLL; using Model; namespace FanSheWeb { public partial class _Default : System.Web.UI.Page { DataProvider dp = DataProvider.Instance(); protected void Page_Load(object sender, EventArgs e) { gvResult.DataSource = dp.GetList<Person>(dp.GetAllPerson()); gvResult.DataBind(); } protected void btnAdd_Click(object sender, EventArgs e) { string user = txtUser.Text.Trim(); string address = txtAddress.Text.Trim(); dp.AddUser(new Model.Person() { UserName = user, Address = address, AddTime = DateTime.Now }); Response.Redirect(Request.RawUrl); } } }
     

    在使用静态构造函数的时候应该注意以下几点:

    1、静态构造函数既没有访问修饰符,也没有参数。

      --因为是.NET调用的,所以像public和private等修饰符就没有意义了。

    2、在创建第一个类实例或任何静态成员被引用时,.NET将自动调用静态构造函数来初始化类。

      --也就是说我们无法直接调用静态构造函数,也不可能知道静态构造函数何时会被调用。

    3、一个类只能有一个静态构造函数。

    4、无参数的构造函数可以与静态构造函数共存。

      --尽管参数列表相同,但一个属于类,一个属于实例,所以不会冲突。

    5、最多只运行一次。

    6、静态构造函数不可以被继承。

    7、如果没有写静态构造函数,而类中包含带有初始值设定的静态成员,那么编译器会自动生成默认的静态构造函数。

     

     

    一个类可以有多个接口 只能有继承一个父类
    抽象类可以有构造方法,接口中不能有构造方法。
    抽象类中可以有普通成员变量,接口中没有普通成员变量.
    接口里边全部方法都必须是abstract的 抽象类的可以有实现了的方法
    抽象类中的抽象方法的访问类型可以是public,protected   但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型
    抽象类中可以包含静态方法,接口中不能包含静态方法
    抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。

  • 相关阅读:
    NBUT 1120 Reimu's Teleport (线段树)
    NBUT 1119 Patchouli's Books (STL应用)
    NBUT 1118 Marisa's Affair (排序统计,水)
    NBUT 1117 Kotiya's Incantation(字符输入处理)
    NBUT 1115 Cirno's Trick (水)
    NBUT 1114 Alice's Puppets(排序统计,水)
    188 Best Time to Buy and Sell Stock IV 买卖股票的最佳时机 IV
    187 Repeated DNA Sequences 重复的DNA序列
    179 Largest Number 把数组排成最大的数
    174 Dungeon Game 地下城游戏
  • 原文地址:https://www.cnblogs.com/joeylee/p/2757218.html
Copyright © 2011-2022 走看看