当前位置:首页 > .Net > 自己动手写一个MyORM

自己动手写一个MyORM

ORM到底是个什么呢,简单的说就是利用放射的方法,来对类class进行操作。

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

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

废话不多说,进入正题。

微软

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

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

添加一个类,MyORM.cs

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

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

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//根据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
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//插入数据到数据库
            Person p1 = new Person();
            MyORM orm = new MyORM();
            p1.Name = "哈哈";
            p1.Age = 20;
            orm.Insert(p1);
            Console.ReadKey();
 
            //根据查询数据
             Person p2 = (Person)orm.SelectById(typeof(Person), 1);
            Console.WriteLine(p2.Name);
            Console.ReadKey();
 
           //泛型的方法查询
          Person P3=orm.SelectById<Person>(1);
          Console.WriteLine(p3.Name);
          Console.ReadKey();

代码总结

这样一个简单的ORM我们就做好了,现在比较流行ORM框架有EF和dapper,大家有时间的话可以去研究研究这两个,各有优点,都是非常不错的框架,用起来也是比较方便的。

  • << Lucene全方检索框架入门篇
  • 15个PHP正则表达式 >>
  • 作者:
    除非注明,本文原创:知道91,欢迎转载!转载请以链接形式注明本文地址,谢谢。
    原文链接:http://www.zhidao91.com/diy-myorm/

    相关文章 近期热评 最新文章

    • oracle数据库相关操作注意事项
      修改Oracle SGA(共享内存) 很多网站说修改Oracle的内存通过命令 如果你这么做了,那么恭喜你,你的Oracle数据库无法启动了。如果你已经这么做了,恢复Oracle启动的方...
    • 使用微信JDK实现微信接口签名验证
      要使用微信的接口必须在绑定的域名下测试;签名必须先向微信请求到access_token,然后用access_token再去请求jsapi_ticket,最后用jsapi_ticket和相关的参数按照ASCII码...
    • ABP开发指南系列教程(2) – 多层架构...
      为了减少复杂性和提高代码的可重用性,采用分层架构是一种被广泛接受的技术。为了实现分层的体系结构,ABP遵循DDD(领域驱动设计)的原则,将工程分为四个层: 展现层(...
    • ABP开发指南系列教程(1) – 入...
      ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称。 ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应用程序的新起点,它旨在成为一个通用的WE...
    • Windows下 JIRA + Agile + Mysql 破解...
      本文讲述了Windows下 JIRA + Agile + Mysql 破解安装示例教程
    • c#类的构造函数继承关系示例剖析
      本文通过示例代码讲解了c#子类的构造函数与父类的关系,子类怎样集成父类的构造函数的。