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

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

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

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

 public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}

添加一个类,MyORM.cs

 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[];
if (table.Rows.Count<=)
{
return null;//没有查到数据
}
else if (table.Rows.Count>)
{
throw new Exception("出大问题了");
}
DataRow row = table.Rows[];
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方法更改为泛型的方法

  //根据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[];
if (table.Rows.Count<=)
{
return default(T);//没有查到数据
}
else if (table.Rows.Count>)
{
throw new Exception("出大问题了");
}
DataRow row = table.Rows[];
foreach (var prop in type.GetProperties())
{
prop.SetValue(obj,row[prop.Name]);
}
return obj;//T类型的
}

在主程序中调用的代码

            //插入数据到数据库
Person p1 = new Person();
MyORM orm = new MyORM();
p1.Name = "哈哈";
p1.Age = ;
orm.Insert(p1);
Console.ReadKey(); //根据查询数据
Person p2 = (Person)orm.SelectById(typeof(Person), );
Console.WriteLine(p2.Name);
Console.ReadKey(); //泛型的方法查询
Person P3=orm.SelectById<Person>();
Console.WriteLine(p3.Name);
Console.ReadKey();

写一个MyORM--利用反射的方法的更多相关文章

  1. 利用反射调用方法时,处理ref,out参数需要注意的问题(转)

    转自:http://www.68idc.cn/help/buildlang/ask/20150318283817.html 项目中如下的泛型方法,因为要在运行时,动态指定类型参数,所以要利用反射来实现 ...

  2. javascript : 写一个类似于 jquery css() 的方法

    我们知道,jquery css() 方法可以很方便的更改DOM的样式. 但从原理上,这个并不复杂,我们完全可以自己写一个. 上代码. updateDOMStyle(DOM, obj){ Object. ...

  3. asp.net一般处理程序利用反射定位方法

    asp.net的一般处理程序我想大家用得都不少,经常会如下如下的代码: using System; using System.Collections.Generic; using System.Lin ...

  4. java工具类-接受请求参数,并利用反射调用方法

    public String a(HttpServletRequest request,HttpServletResponse response) throws JSONException, IOExc ...

  5. java将配置信息写在数据库(利用反射)

    Demo出处: 1. package com.fpx.pcs.prealert.process.xml.service.impl; public class CainiaoPushMessageSer ...

  6. Java_jdbc 基础笔记之八 数据库连接(写一个查询Student对象的方法)

    public Student getStudent(String sql, Object... args) { // 查询Student对象 Student stu = null; Connectio ...

  7. Python基础篇【第3篇】: Python异常处理、反射、动态导入、利用反射的web框架

    异常处理 什么是异常? 异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行. 一般情况下,在Python无法正常处理程序时就会发生一个异常.异常是Python对象,表示一个错误.当P ...

  8. 反射main方法

    利用Java反射机制去调用其他类的main方法基于这种情形: 当程序中的某个类在运行到某处需要去调用其他类的main方法时,如果此程序并不知道此main方法所属类的名称,而只是在程序中接受某一代表此m ...

  9. C#利用反射调用PB编译的COM组件

    问题: 1.根据COM组件的ProgID,得到COM组件公开的类型 2.创建COM组件提供的类型的对象 3.调用执行方法 正确姿势 C#利用反射调用(后期绑定)PB编译的COM组件 C#调用COM组件 ...

随机推荐

  1. spring-boot 测试

    在线项目构建:http://start.spring.io/ 下载:bookpub.zip 导入Idea15.0.1 运行: y@y:bookpub$ ./gradlew clean bootRun ...

  2. CMOS和TTL的區別

    TTL電路是晶體管-晶體管邏輯電路的英文縮寫(Transister-Transister-Logic ),是數字集成電路的一大門類.它采用雙極型工藝制造,具有高速度低功耗和品種多等特點. CMOS是: ...

  3. C51 库函数(3)

    3.3 STRING.H:串函数 串函数通常将指针串作输入值.一个串就包括2个或多个字符.串结以空字符表示.在函数memcmp,memcpy,memchr,memccpy,memmove和memset ...

  4. 使用Qt编写模块化插件式应用程序

    动态链接库技术使软件工程师们兽血沸腾,它使得应用系统(程序)可以以二进制模块的形式灵活地组建起来.比起源码级别的模块化,二进制级别的模块划分使得各模块更加独立,各模块可以分别编译和链接,模块的升级不会 ...

  5. 【HDOJ】2571 命运

    DP. /* 2571 */ #include <cstdio> #include <cstring> #include <cstdlib> #define MAX ...

  6. COJ 1007 WZJ的数据结构(七) 树上操作

    传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=983 WZJ的数据结构(七) 难度级别:C: 运行时间限制:1000ms: ...

  7. COJ 3012 LZJ的问题 (有向图判环)

    传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=1042 试题描述: LZJ有一个问题想问问大家.他在写函数时有时候很头疼,如 ...

  8. G - Arctic Network - poj2349

    在北极圈有一些基地,这些基地需要建立通讯网络,他们可以通过卫星直接通信或者无线通信,基地有S个卫星,N个基地,不过无线通信的传输距离是D,距离越远费用越高,现在想知道D最小是多少. 分析:使用krus ...

  9. 错误 是否保存对以下各项的更改 devenv.sin

    描述: 打开VS2012项目时,提示 是否保存对以下各项的更改 devenv.sin google了一下,没找到...纠结.百度了一下,竟然有的...擦一直以为google很给力,看来对于中文的解析不 ...

  10. Linux内核-内核线程

    线程分类:内核线程.用户线程(指不需要内核支持而完全建立在用户空间的线程库,这种线程效率高,由于Linux内核没有轻量级进程(线程)的概念,因此不能独立的对用户线程进行调度,而是由一个线程运行库来组织 ...