通过反射,将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类型。

posted @ 2012-11-06 16:27  梨花驿路  阅读(961)  评论(0编辑  收藏  举报