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类型。

  • 相关阅读:
    [CF1076D] Edge Deletion
    [CF1081D] Maximum Distance
    [CF1095F] Make It Connected
    [CF1328E] Tree Queries
    [CF1328F] Make k Equal
    Codeforces Round #629 (Div. 3) 总结
    [CF1131D] Gourmet choice
    [CF1176D] Recover it!
    [CF1205B] Shortest Cycle
    [CF1213G] Path Queries
  • 原文地址:https://www.cnblogs.com/joeylee/p/2757218.html
Copyright © 2011-2022 走看看