zoukankan      html  css  js  c++  java
  • 写一个MyORM--利用反射的方法

    本文的目的是为了更加深刻的理解反射。

    ORM:Object Relational Mapping对象关系映射,是解决了面向对象语言和关系型数据库不匹配的问题。

    ORM是一种思想,实现这种思想的技术有很多,如C#中的Entity Framework,NHibernate,Java中的Hibernate。

    新建一个控制台应用程序,添加一个类,Person.cs

    1 public class Person
    2     {
    3        public int Id { get; set; }
    4        public string Name { get; set; }
    5        public int Age { get; set; }
    6     }

    添加一个类,MyORM.cs

     1 public class MyORM
     2     {
     3         private static readonly string connstr = ConfigurationManager.ConnectionStrings["connstr"].ConnectionString;
     4         //假设:表名和类名一致
     5         /// <summary>
     6         /// 插入一条数据
     7         /// </summary>
     8         /// <param name="obj">插入的对象</param>
     9         /// <returns>受影响函数</returns>
    10         public int Insert(object obj)
    11         {
    12             Type type = obj.GetType();
    13             string className = type.Name;//person
    14             //insert into Person(Name,Age)values("哈哈",10)
    15             PropertyInfo[] props = type.GetProperties();
    16             List<string> propNames = new List<string>();//属性名列表
    17             List<string> paraNames = new List<string>();//参数名列表
    18             List<MySqlParameter> paramters = new List<MySqlParameter>();//参数
    19             foreach (PropertyInfo prop in props)
    20             {
    21                 string propName = prop.Name;
    22                 if (propName != "Id")
    23                 {
    24                     propNames.Add(propName);
    25                     paraNames.Add("@" + propName);
    26                    MySqlParameter para=new MySqlParameter(propName,prop.GetValue(obj));
    27                    paramters.Add(para);
    28                 }
    29             }
    30             StringBuilder sqlsb = new StringBuilder();
    31             sqlsb.Append("insert into ").Append(className).Append("(").Append(string.Join(",", propNames)).Append(")values(").Append(string.Join(",", paraNames)).Append(")");
    32            return MySqlHelper.ExecuteNonQuery(connstr, sqlsb.ToString(), paramters.ToArray());
    33         }
    34         //根据Id查询
    35         public object SelectById(Type type, int id)
    36         {
    37            object obj= Activator.CreateInstance(type);
    38             //select * from Person where Id=1
    39            string className = type.Name;
    40            string sql = "select * from " + className + " where Id=@Id";
    41            MySqlParameter para = new MySqlParameter("@Id",id);
    42           DataSet ds= MySqlHelper.ExecuteDataset(connstr, sql, para);
    43           DataTable table = ds.Tables[0];
    44           if (table.Rows.Count<=0)
    45           {
    46               return null;//没有查到数据
    47           }
    48           else if (table.Rows.Count>1)
    49           {
    50               throw new Exception("出大问题了");
    51           }
    52           DataRow row = table.Rows[0];
    53           foreach (var prop in type.GetProperties())
    54           {
    55               prop.SetValue(obj,row[prop.Name]);
    56           }
    57           return obj;
    58         }
    59         
    60     }

    这里有一个先决条件:类名要和数据库表名一致

    Insert方法实现的是只要传一个类Object就可以将这个类对应的数据添加到数据库表中,主要是通过反射的方法获取类名、属性名和属性值,通过这些拼接sql语句,完成insert操作。

    SelectById方法是根据类的Type和属性Id的值,从数据库中查询数据并且赋值给Object.先从数据库中查询数据,通过反射的方法为object的每个属性赋值,返回object.

    为了事先规定Type的类型,我们还可以把SelectById方法更改为泛型的方法

      //根据Id查询
            public T SelectById<T>( int id) where T:new()//泛型约束有无参的构造函数
            {
                Type type = typeof(T);
               //object obj= Activator.CreateInstance(type);
                T obj = new T();
                //select * from Person where Id=1
               string className = type.Name;
               string sql = "select * from " + className + " where Id=@Id";
               MySqlParameter para = new MySqlParameter("@Id",id);
              DataSet ds= MySqlHelper.ExecuteDataset(connstr, sql, para);
              DataTable table = ds.Tables[0];
              if (table.Rows.Count<=0)
              {
                  return default(T);//没有查到数据
              }
              else if (table.Rows.Count>1)
              {
                  throw new Exception("出大问题了");
              }
              DataRow row = table.Rows[0];
              foreach (var prop in type.GetProperties())
              {
                  prop.SetValue(obj,row[prop.Name]);
              }
              return obj;//T类型的
            }

    在主程序中调用的代码

     1            //插入数据到数据库
     2             Person p1 = new Person();
     3             MyORM orm = new MyORM();
     4             p1.Name = "哈哈";
     5             p1.Age = 20;
     6             orm.Insert(p1);
     7             Console.ReadKey();
     8 
     9             //根据查询数据
    10              Person p2 = (Person)orm.SelectById(typeof(Person), 1);
    11             Console.WriteLine(p2.Name);
    12             Console.ReadKey();
    13 
    14            //泛型的方法查询
    15           Person P3=orm.SelectById<Person>(1);
    16           Console.WriteLine(p3.Name);
    17           Console.ReadKey();
  • 相关阅读:
    Js特效之放大镜(淘宝商品展示)
    关于使用JavaScript实现图片点击切换(附带改变导航图片 方案二)
    关于使用JavaScript实现图片点击切换(附带改变导航图片 方案一)
    JavaScript常用的方法和函数(setInterval和setTimeout)
    When to use dequeueReusableCellWithIdentifier vs dequeueReusableCellWithIdentifier: forIndexPath
    iOS 7.1 安装 企业应用 提示 无法下载应用程序
    Git忽略规则及.gitignore规则不生效的解决办法
    Core Animation 学习
    AutoLayout那些坑
    欲善其事必先利其器---Xcode插件
  • 原文地址:https://www.cnblogs.com/lucyliang/p/4987706.html
Copyright © 2011-2022 走看看