文档章节

Java反射技术/简单ORM

涩女郎
 涩女郎
发布于 2014/11/22 11:13
字数 1152
阅读 40
收藏 1

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);  



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


本文转载自:http://royzhou1985.iteye.com/blog/344256

涩女郎
粉丝 37
博文 104
码字总数 160210
作品 0
浦东
高级程序员
私信 提问
ORM轻量级框架---ActiveAndroid

ORM即Object-Relational Mapping,对象关系映射。简单理解就是把我们Java的对象与数据库里面的记录进行映射,可以把实体对象持久化到数据库中,也能把查询到的记录映射成Java对象。ORM让我们...

Jack_1900
2014/07/29
2.2K
0
MyBatis源码窥探:MyBatis整体架构解析

Mybatis的使用这里就不介绍了,不知道怎么使用的朋友可以点击 http://www.mybatis.org/mybatis-3/zh/index.html 这里面的教程很详细,包括xml的配置、映射、动态sql都有介绍,可以学习和使用...

java邵先生
01/15
0
0
Java面试无非也就这几个知识点,大家是否都掌握了

Java语言的关键点 掌握静态方法和属性 重视接口 学好集合框架 例外捕捉 多线程需要理解机理(多线程原理和多线程安全) 了解网络编程 不需要精通,掌握以下知识点,面试基本没有问题。 这里没有...

土豆宝
2016/08/22
9.5K
37
注解(Annotation)--注解处理器

如果没有用来读取注解的方法和工作,那么注解也就不会比注释更有用处了。使用注解的过程中,很重要的一部分就是创建于使用注解处理器。Java SE5扩展了反射机制的API,以帮助程序员快速的构造...

boonya
2015/04/17
136
0
java基础强化——注解原理解析和应用实战(简单ORM功能实现)

1.什么是注解 注解是java1.5引入的新特性,它是嵌入代码中的元数据信息,元数据是解释数据的数据。通俗的说,注解是解释代码的代码。这个定义强调了三点, 1.注解是代码 这意味着注解可以被程序...

takumiCX
2018/07/23
0
0

没有更多内容

加载失败,请刷新页面

加载更多

使用TensorFlow的AI程序运行报错AttributeError: module 'tensorflow' has no attribute 'xxx'

使用TensorFlow的AI程序,在运行时报错AttributeError: module 'tensorflow' has no attribute 'xxx',首先检查是否是包路径不对,一般是版本变化所致。...

织梦之魂
57分钟前
3
0
提示浏览器版本低

本文转载于:专业的前端网站➭提示浏览器版本低 网站网页在遇到浏览器低版本(尤其是IE浏览器)时,提示浏览器版本低(如IE8以及以下),建议用户升级浏览器以获得最好体验。以下是代码: 1...

前端老手
59分钟前
6
0
CentOS 7系统增加swap

转载请注明文章出处:CentOS 7系统增加swap swap是位于磁盘上的特殊文件(或分区),属于“虚拟内存”的一部分。通俗点就是内存的备胎,内存充足的情况下,基本上没swap什么事(和设置有关)...

tlanyan
今天
6
0
基于Prometheus和Grafana的监控平台 - 环境搭建

相关概念 微服务中的监控分根据作用领域分为三大类,Logging,Tracing,Metrics。 Logging - 用于记录离散的事件。例如,应用程序的调试信息或错误信息。它是我们诊断问题的依据。比如我们说...

JAVA日知录
今天
6
0
PHP运行时全局构造体

struct _php_core_globals { zend_bool magic_quotes_gpc; // 是否对输入的GET/POST/Cookie数据使用自动字符串转义。 zend_bool magic_quotes_runtime; //是否对运行时从外部资源产生的数据使...

冻结not
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部