Java反射技术/简单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);  



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


你可能感兴趣的:(Java反射技术/简单ORM)