利用反射实现ORM

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 
Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。 

Java代码   收藏代码
  1. package com.royzhou.reflect;  
  2.   
  3. import java.lang.reflect.Constructor;  
  4. import java.lang.reflect.Field;  
  5. import java.lang.reflect.Method;  
  6.   
  7. public class ReflectTest {  
  8.   
  9.     private String id;  
  10.   
  11.     private String name;  
  12.   
  13.     public String property;  
  14.   
  15.     public String getId() {  
  16.         return id;  
  17.     }  
  18.   
  19.     public void setId(String id) {  
  20.         this.id = id;  
  21.     }  
  22.   
  23.     public String getName() {  
  24.         return name;  
  25.     }  
  26.   
  27.     public void setName(String name) {  
  28.         this.name = name;  
  29.     }  
  30.   
  31.     public String getProperty() {  
  32.         return property;  
  33.     }  
  34.   
  35.     public void setProperty(String property) {  
  36.         this.property = property;  
  37.     }  
  38.   
  39.     public ReflectTest() {  
  40.         System.out.println("this is a constructor with no params!!!");  
  41.     }  
  42.   
  43.     public ReflectTest(String param) {  
  44.         System.out.println("this is a constructor with  param :" + param  
  45.                 + "!!!");  
  46.     }  
  47.   
  48.     /** 
  49.      * 创建对象 
  50.      *  
  51.      * @param clazz 
  52.      * @param paramTypes:构造函数参数,如果为null表示调用无参函数 
  53.      * @return 
  54.      * @throws Exception 
  55.      */  
  56.     public Object createObject(Class clazz, Class[] paramTypes)  
  57.             throws Exception {  
  58.         Object obj = null;  
  59.         if (paramTypes == null) {  
  60.             // 无参构造函数  
  61.             obj = clazz.newInstance();  
  62.         } else {  
  63.             // 有参构造函数  
  64.             Constructor con = clazz.getConstructor(paramTypes);  
  65.             obj = con.newInstance("Test String param");  
  66.         }  
  67.         return obj;  
  68.     }  
  69.   
  70.     /** 
  71.      * 激活对象的某个方法 
  72.      *  
  73.      * @param obj 
  74.      * @param methodName 
  75.      * @throws Exception 
  76.      */  
  77.     public void invokeMethod(Object obj, String methodName) throws Exception {  
  78.         Method[] methods = obj.getClass().getDeclaredMethods(); // 拿到当前类的全部方法,包括私有的和公有的  
  79.         methods = obj.getClass().getMethods(); // 拿到当前类以及父类的所有公有方法  
  80.         for (Method m : methods) {  
  81.             if (m.getName().equals(methodName)) {  
  82.                 m.invoke(obj, new Object[] {}); // 调用方法  
  83.             }  
  84.         }  
  85.     }  
  86.   
  87.     public void getFileds(Object obj) throws Exception {  
  88.         Field[] fields = obj.getClass().getFields(); // 获取公有的属性  
  89.         fields = obj.getClass().getDeclaredFields(); // 获取公有私有属性  
  90.         for (Field f : fields) {  
  91.             System.out.println(f.getName());  
  92.         }  
  93.     }  
  94.   
  95.     public void overload(String s) {  
  96.         System.out.println("param is String :" + s);  
  97.     }  
  98.   
  99.     public void overload(int i) {  
  100.         System.out.println("param is int :" + i);  
  101.     }  
  102.   
  103.     public void testInvoke() {  
  104.         System.out.println("this is a method for invoke test!!!");  
  105.     }  
  106.       
  107.     public static void main(String[] args) throws Exception {  
  108.         ReflectTest rt = new ReflectTest();  
  109.         Object obj = rt.createObject(ReflectTest.classnull);  
  110.         System.out.println("--------------");  
  111.         obj = rt.createObject(ReflectTest.classnew Class[] { String.class });  
  112.         System.out.println("--------------");  
  113.         rt.invokeMethod(obj, "testInvoke");  
  114.         System.out.println("--------------");  
  115.         Method m = obj.getClass().getMethod("overload"int.class);  
  116.         m.invoke(obj, new Object[] { 1 });  
  117.         System.out.println("--------------");  
  118.         m = obj.getClass().getMethod("overload", String.class);  
  119.         m.invoke(obj, new Object[] { "test overload String" });  
  120.         System.out.println("--------------");  
  121.         rt.getFileds(obj);  
  122.     }  
  123. }  


利用java的反射机制可以进行简单的ORM即对象关系映射 
如下面代码: 
Java代码   收藏代码
  1. import java.lang.reflect.Method;  
  2. import java.sql.Connection;  
  3. import java.sql.PreparedStatement;  
  4. import java.sql.ResultSet;  
  5. import java.sql.ResultSetMetaData;  
  6. import java.util.ArrayList;  
  7. import java.util.List;  
  8.   
  9. public class ORMTest {  
  10.   
  11.     /** 
  12.      * @param args 
  13.      * @throws Exception 
  14.      */  
  15.     public static void main(String[] args) throws Exception {  
  16.         User user = (User) getObject(  
  17.                 "select id as Id, name as Name from user where id=1",  
  18.                 User.class);  
  19.         System.out.println(user);  
  20.     }  
  21.   
  22.     public static List<Object> getObjects(String sql, Class clazz)  
  23.             throws Exception {  
  24.         Connection conn = null;  
  25.         PreparedStatement ps = null;  
  26.         ResultSet rs = null;  
  27.         try {  
  28.             conn = JdbcUtils.getConnection();  
  29.             ps = conn.prepareStatement(sql);  
  30.             rs = ps.executeQuery();  
  31.             String[] colNames = getColNames(rs);  
  32.   
  33.             List<Object> objects = new ArrayList<Object>();  
  34.             Method[] ms = clazz.getMethods();  
  35.             while (rs.next()) {  
  36.                 Object object = clazz.newInstance(); //  
  37.                 for (int i = 0; i < colNames.length; i++) {  
  38.                     String colName = colNames[i];  
  39.                     String methodName = "set" + colName;  
  40.                     for (Method m : ms) {  
  41.                         if (methodName.equals(m.getName())) {  
  42.                             m.invoke(object, rs.getObject(colName));  
  43.                             break;  
  44.                         }  
  45.                     }  
  46.                     objects.add(object);  
  47.                 }  
  48.             }  
  49.             return objects;  
  50.         } finally {  
  51.             JdbcUtils.free(rs, ps, conn);  
  52.         }  
  53.     }  
  54.   
  55.     private static String[] getColNames(ResultSet rs) throws Exception {  
  56.         ResultSetMetaData rsmd = rs.getMetaData();  
  57.         int count = rsmd.getColumnCount();  
  58.         String[] colNames = new String[count];  
  59.         for (int i = 1; i <= count; i++) {  
  60.             colNames[i - 1] = rsmd.getColumnLabel(i);  
  61.         }  
  62.         return colNames;  
  63.     }  
  64.   
  65.     public static Object getObject(String sql, Class clazz) throws Exception {  
  66.         Connection conn = null;  
  67.         PreparedStatement ps = null;  
  68.         ResultSet rs = null;  
  69.         try {  
  70.             conn = JdbcUtils.getConnection();  
  71.             ps = conn.prepareStatement(sql);  
  72.             rs = ps.executeQuery();  
  73.             String[] colNames = getColNames(rs);  
  74.   
  75.             Object object = null;  
  76.             Method[] ms = clazz.getMethods();  
  77.             if (rs.next()) {  
  78.                 object = clazz.newInstance();  
  79.                 for (int i = 0; i < colNames.length; i++) {  
  80.                     String colName = colNames[i];  
  81.                     String methodName = "set" + colName;  
  82.                     for (Method m : ms) {  
  83.                         if (methodName.equals(m.getName())) {  
  84.                             m.invoke(object, rs.getObject(colName));  
  85.                             break;  
  86.                         }  
  87.                     }  
  88.                 }  
  89.             }  
  90.             return object;  
  91.         } finally {  
  92.             JdbcUtils.free(rs, ps, conn);  
  93.         }  
  94.     }  
  95. }  

在这个简单的ORM中,利用Java的反射机制动态创建实例,不需要事先知道要生成什么对象或对象集合,只需要在调用的时候转型(当然也可以使用jdk1.5的泛型技术),使用m.invoke(object, rs.getObject(colName))方法动态设置实例的属性,注意,在这个例子中,user类必须是一个标准的Javabean,具有各个属性的setter/getter方法以及一个没有参数的构造函数,上面例子中使用sql的别名来实现动态调用对象的方法,(Hibernate使用配置文件.hbm.xml文件完成数据库字段到javabean的映射),只需要在写查询sql的时候指定好别名就可以完成javabean属性的设置。 

假如有另外一个类 Product 
Java代码   收藏代码
  1. public class Product {  
  2.       
  3.     private String id;  
  4.       
  5.     private String name;  
  6.       
  7.     private String manufatrue;  
  8.       
  9.     public String getId() {  
  10.         return id;  
  11.     }  
  12.   
  13.     public void setId(String id) {  
  14.         this.id = id;  
  15.     }  
  16.   
  17.     public String getManufatrue() {  
  18.         return manufatrue;  
  19.     }  
  20.   
  21.     public void setManufatrue(String manufatrue) {  
  22.         this.manufatrue = manufatrue;  
  23.     }  
  24.   
  25.     public String getName() {  
  26.         return name;  
  27.     }  
  28.   
  29.     public void setName(String name) {  
  30.         this.name = name;  
  31.     }  
  32.   
  33.     public Product() {  
  34.           
  35.     }  
  36. }  

这样我们在查询的时候只需要执行下面语句就可以获得封装好的Product对象/集合 
Java代码   收藏代码
  1. Product product= (Product ) getObject("select id as Id, name as Name ,manufature as Manufature from product where id=1",Product .class);  


这样的代码更具有动态性,不用每个查询写一个查询方法 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值