JDBC --反射(二)

1.利用反射机制,得到SQL中通用的查询方法:得到SQL查询通用方式

  1 package com.atguigu.mvcapp;
  2 
  3 import java.sql.Connection;
  4 import java.sql.PreparedStatement;
  5 import java.sql.ResultSet;
  6 import java.sql.ResultSetMetaData;
  7 import java.sql.SQLException;
  8 import java.util.HashMap;
  9 import java.util.Map;
 10 
 11 /**熟悉DAO设计 实现数据的CRUD*/
 12 public class DAO1 {
 13  static Connection conn=null;
 14  static PreparedStatement ps=null;
 15  static ResultSet rs=null;
 16  
 17  public DAO1(){
 18      // 建立连接
 19      try {
 20          conn=JDBCUtils.getMysqlConn();
 21          
 22          // 通过占位符进行修饰
 23     } catch (Exception e) {
 24         // TODO Auto-generated catch block
 25         e.printStackTrace();
 26     }
 27  }
 28     public static void main(String[] args) {
 29         // TODO Auto-generated method stub
 30         
 31         
 32         
 33     }
 34     
 35     public static void update(String sql,Object ...args)
 36     {
 37         // args 表示占位符 insert ,delete,修改
 38         
 39          try {
 40             ps=conn.prepareStatement(sql);
 41             for(int i=0;i<args.length;i++)
 42             {
 43                 ps.setObject(i+1,args[i]);
 44             }
 45             
 46             ps.executeUpdate();
 47             
 48         } catch (SQLException e) {
 49             // TODO Auto-generated catch block
 50             e.printStackTrace();
 51         }
 52          finally{
 53              JDBCUtils.closeMysql(ps, conn);
 54          }
 55     }
 56     // 查询通用方法,同时返回其中记录中字段
 57     public static <T> T get(Class<T> clazz,String sql,Object ...args)
 58     {  //得到 SQL属性,但是事先不知道,采用反射机制
 59         // 1.PreparedStatement, ResultSet ,不清楚SQL记录中字段属性
 60         // 2.Map<String ,Object>
 61         // 3.处理ResultMap 遍历有多少个属性,得到每一属性和属性值
 62         // 4.填充Map对象
 63         // 5. 用反射创建Class 对应的对象
 64         T entiry=null;
 65         try {
 66             ps=conn.prepareStatement(sql);
 67             for(int i=0;i<args.length;i++)
 68             {
 69                 ps.setObject(i+1,args[i]);
 70             }
 71             
 72             rs=ps.executeQuery();
 73             
 74             if(rs.next())
 75             {
 76                 // 将 记录名称 与其中值进行反射
 77                 Map<String,Object> map=new HashMap<String ,Object>();
 78                 
 79                 // 查询完了之后建立ResultSetMapData 记录的类名称
 80                 ResultSetMetaData rsmd= rs.getMetaData();
 81                 
 82                 int columnCount=rsmd.getColumnCount();
 83                 for(int i=0;i<columnCount;i++)
 84                 {
 85                     String columnLabel=rsmd.getColumnLabel(i+1);
 86                     Object columnValue=rs.getObject(i+1);
 87                     // 填充Map对象
 88                     map.put(columnLabel,columnValue);
 89                 }
 90                 // 利用反射机制Class对应对象
 91                 if(map.size()>0)
 92                 {
 93                 Object object=clazz.newInstance();
 94                 
 95                 for(Map.Entry<String,Object> entiry1:map.entrySet())
 96                 {
 97                     String property=entiry1.getKey();
 98                     Object value=entiry1.getValue();
 99                     
100                     // 直接就可反射 建立起
101                     ReflectionUtils.setFieldValue(object, property, value);
102                 }
103             }
104         }
105         } catch (SQLException e) {
106             // TODO Auto-generated catch block
107             e.printStackTrace();
108         } catch (InstantiationException e) {
109             // TODO Auto-generated catch block
110             e.printStackTrace();
111         } catch (IllegalAccessException e) {
112             // TODO Auto-generated catch block
113             e.printStackTrace();
114         }
115         finally
116         {
117             JDBCUtils.closeMysql(rs, ps, conn);
118         }
119         
120         return entiry;
121         
122     }
123 }
View Code

下面Java 中反射机制 代码封装:

  1 package com.atguigu.jdbc;
  2 
  3 import java.lang.reflect.Field;
  4 import java.lang.reflect.InvocationTargetException;
  5 import java.lang.reflect.Method;
  6 import java.lang.reflect.Modifier;
  7 import java.lang.reflect.ParameterizedType;
  8 import java.lang.reflect.Type;
  9 
 10 /**
 11  * 反射的 Utils 函数集合
 12  * 提供访问私有变量, 获取泛型类型 Class, 提取集合中元素属性等 Utils 函数
 13  * @author Administrator
 14  *
 15  */
 16 public class ReflectionUtils {
 17 
 18     
 19     /**
 20      * 通过反射, 获得定义 Class 时声明的父类的泛型参数的类型
 21      * 如: public EmployeeDao extends BaseDao<Employee, String>
 22      * @param clazz
 23      * @param index
 24      * @return
 25      */
 26     @SuppressWarnings("unchecked")
 27     public static Class getSuperClassGenricType(Class clazz, int index){
 28         Type genType = clazz.getGenericSuperclass();
 29         
 30         if(!(genType instanceof ParameterizedType)){
 31             return Object.class;
 32         }
 33         
 34         Type [] params = ((ParameterizedType)genType).getActualTypeArguments();
 35         
 36         if(index >= params.length || index < 0){
 37             return Object.class;
 38         }
 39         
 40         if(!(params[index] instanceof Class)){
 41             return Object.class;
 42         }
 43         
 44         return (Class) params[index];
 45     }
 46     
 47     /**
 48      * 通过反射, 获得 Class 定义中声明的父类的泛型参数类型
 49      * 如: public EmployeeDao extends BaseDao<Employee, String>
 50      * @param <T>
 51      * @param clazz
 52      * @return
 53      */
 54     @SuppressWarnings("unchecked")
 55     public static<T> Class<T> getSuperGenericType(Class clazz){
 56         return getSuperClassGenricType(clazz, 0);
 57     }
 58     
 59     /**
 60      * 循环向上转型, 获取对象的 DeclaredMethod
 61      * @param object
 62      * @param methodName
 63      * @param parameterTypes
 64      * @return
 65      */
 66     public static Method getDeclaredMethod(Object object, String methodName, Class<?>[] parameterTypes){
 67         
 68         for(Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){
 69             try {
 70                 //superClass.getMethod(methodName, parameterTypes);
 71                 return superClass.getDeclaredMethod(methodName, parameterTypes);
 72             } catch (NoSuchMethodException e) {
 73                 //Method 不在当前类定义, 继续向上转型
 74             }
 75             //..
 76         }
 77         
 78         return null;
 79     }
 80     
 81     /**
 82      * 使 filed 变为可访问
 83      * @param field
 84      */
 85     public static void makeAccessible(Field field){
 86         if(!Modifier.isPublic(field.getModifiers())){
 87             field.setAccessible(true);
 88         }
 89     }
 90     
 91     /**
 92      * 循环向上转型, 获取对象的 DeclaredField
 93      * @param object
 94      * @param filedName
 95      * @return
 96      */
 97     public static Field getDeclaredField(Object object, String filedName){
 98         
 99         for(Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){
100             try {
101                 return superClass.getDeclaredField(filedName);
102             } catch (NoSuchFieldException e) {
103                 //Field 不在当前类定义, 继续向上转型
104             }
105         }
106         return null;
107     }
108     
109     /**
110      * 直接调用对象方法, 而忽略修饰符(private, protected)
111      * @param object
112      * @param methodName
113      * @param parameterTypes
114      * @param parameters
115      * @return
116      * @throws InvocationTargetException 
117      * @throws IllegalArgumentException 
118      */
119     public static Object invokeMethod(Object object, String methodName, Class<?> [] parameterTypes,
120             Object [] parameters) throws InvocationTargetException{
121         
122         Method method = getDeclaredMethod(object, methodName, parameterTypes);
123         
124         if(method == null){
125             throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + object + "]");
126         }
127         
128         method.setAccessible(true);
129         
130         try {
131             return method.invoke(object, parameters);
132         } catch(IllegalAccessException e) {
133             System.out.println("不可能抛出的异常");
134         } 
135         
136         return null;
137     }
138     
139     /**
140      * 直接设置对象属性值, 忽略 private/protected 修饰符, 也不经过 setter
141      * @param object
142      * @param fieldName
143      * @param value
144      */
145     public static void setFieldValue(Object object, String fieldName, Object value){
146         Field field = getDeclaredField(object, fieldName);
147         
148         if (field == null)
149             throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");
150         
151         makeAccessible(field);
152         
153         try {
154             field.set(object, value);
155         } catch (IllegalAccessException e) {
156             System.out.println("不可能抛出的异常");
157         }
158     }
159     
160     /**
161      * 直接读取对象的属性值, 忽略 private/protected 修饰符, 也不经过 getter
162      * @param object
163      * @param fieldName
164      * @return
165      */
166     public static Object getFieldValue(Object object, String fieldName){
167         Field field = getDeclaredField(object, fieldName);
168         
169         if (field == null)
170             throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");
171         
172         makeAccessible(field);
173         
174         Object result = null;
175         
176         try {
177             result = field.get(object);
178         } catch (IllegalAccessException e) {
179             System.out.println("不可能抛出的异常");
180         }
181         
182         return result;
183     }
184 }
View Code

 2.Java中反射机制的研究:动态语言的关键,在执行的过程能够获取任何类的内部信息,并且直接操作任何对象的内部属性和成员方法,JDBC需要反射,在查询过程中得到记录的字段

 

1.放射机制普通方法:运行过程中 Class.getMethod();clazz.getDeclaredField("age");f2.setAccessible(true)获取对象成员变量和属性

Field f2=clazz.getDeclaredField("age");
f2.setAccessible(true);

 1 package com.tetsReflection;
 2 
 3 import java.lang.reflect.Field;
 4 import java.lang.reflect.InvocationTargetException;
 5 import java.lang.reflect.Method;
 6 
 7 public class tets1 {
 8 
 9     /** 反射之前*/
10     public tets1()
11     {
12         Person p=new Person();
13         p.setAge(10);
14         p.setName("TanWei");
15         
16     }
17     
18     //反射之后,在运行构建对象
19     public static void tets2() throws InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException
20     {
21         // src中 person.class文本文件 当做实例
22         @SuppressWarnings("rawtypes")
23         Class clazz=Person.class;
24         
25         // 1.创建clazz运行时类person的对象
26         Person p=(Person) clazz.newInstance();//相当于 new Person()
27         Field f1=clazz.getField("name");
28     
29         //2.  适合于public 类型
30         f1.set(p, "jjjj"); 
31         System.out.println(p.getName());
32         
33         // 3.运行时候private类型
34         Field f2=clazz.getDeclaredField("age");
35         f2.setAccessible(true);
36         f2.setInt(p,10);
37         System.out.println(p.getAge());
38         
39         // 4.通过反射调用成员方法
40         @SuppressWarnings("unchecked")
41         Method m1=clazz.getMethod("show",String.class);//如果void 不写,其他类就可以什么类
42         m1.invoke(p);
43     }
44     public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException
45     {
46         tets2();
47     }
48 }
View Code

 

静态代理:

  1).被代理类 和 代理实现同一个接口方法

 2). 创建代理类的对象中实际上传入被代理类对象

main():

 1 NikeFactory Nike=new NikeFactory();

2 proxyFactory proxy=new proxyFactory(Nike); 3

 proxy.xxx的方法 

 动态代理:

 1 package com.tetsReflection;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 import java.lang.reflect.Proxy;
 6 
 7 // 动态代理的使用
 8 interface Subject
 9 {
10     void action();
11 }
12 
13 class RealSubject implements Subject
14 {
15 
16     @Override
17     public void action() {
18         // TODO Auto-generated method stub
19         System.out.println("我是被代理类记得执行我");
20     }
21     
22 }
23 
24 // 使用动态代理 使用InvocationHander接口
25 class MyInvocationHandler implements InvocationHandler
26 {
27     Object obj;//实现了接口中被代理类对象的声明
28     
29     public Object blind(Object obj)
30     {
31         this.obj=obj;//后一个obj是被代理类对象
32         //返回一个代理类的对象  被代理类加载器+ 被代理类实现接口+this
33         return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
34     }
35     @Override
36     // 被代理类对象 对重写方法调用时候,会自动转换成invoke方法
37     public Object invoke(Object proxy, Method method, Object[] args)
38             throws Throwable {
39         // TODO Auto-generated method stub
40         
41       Object returnVal=method.invoke(obj, args);
42         return returnVal;
43     }
44 }
45 public class test2 {
46   public static void main(String[] args)
47   {
48       //创建被代理类对象
49       RealSubject real=new RealSubject();
50       
51       // 2.
52       MyInvocationHandler handler=new MyInvocationHandler ();
53      // 动态创建 代理类对象调用blind(),
54       Object obj=null;
55       obj=  handler.blind(real);
56       
57     // 此时sub是代理类方法强制转换成被代理类型
58       Subject sub=(Subject)obj;
59       
60       sub.action();//自动调用invoke方法,会执行被代理类的action
61   }
62 }

 5.类加载器:

/********************************************************************************************************************************************/

总结;获取反射过程中属性和成员方法 同时获取父类的泛型 和泛型的类型JDBC()

 1 package com.tetsReflection;
 2 
 3 
 4 import java.lang.reflect.*;
 5 
 6 public class TestField {
 7 
 8     /**获取运行时的属性*/
 9     public static void tets1()
10     {
11         Class clazz=Person.class;
12         
13         // clazz 只能得到public属性 本类和父类的public 属性
14         Field[] fields=clazz.getFields();
15         for(int i=0;i<fields.length;i++)
16             System.out.println(fields[i]);
17         
18         // 2.得到private属性
19         Field [] fields1=clazz.getDeclaredFields();
20         for(Field f:fields1)
21             System.out.println(f.getName());
22     }
23     
24     // 获取属性的各个部分内容
25     public static void test2()
26     {
27         Class clazz=Person.class;
28         Field [] fields1=clazz.getDeclaredFields();
29         for(Field f:fields1)
30         {
31             // 成员修饰符:1.public 2.private decode
32              int i=  f.getModifiers();
33             String str=Modifier.toString(i);
34             System.out.println(str +" "+f.getName());
35             
36             // 属性的类型
37             Class type=f.getType();
38                  System.out.println(type.getName());
39         
40         }
41     }
42     public static void test3()
43     {
44         Class clazz=Person.class;
45         Method[] m1=clazz.getMethods();
46         
47         // 1.本类和父类中 非private方法
48         for(Method m:m1)
49             System.out.println(m.getName());
50         
51         // 2. 获取运行时候本类private
52         Method[] m2=clazz.getDeclaredMethods();
53         for(Method m:m2)
54             System.out.println(m.getName());
55     }
56     public static void test4() throws ClassNotFoundException, NoSuchMethodException, SecurityException
57     {
58         // 获取所有构造器
59         String className="com.tetsReflection.Person.java";
60         // 通过包下string 创建一个Class 类
61         Class clazz=Class.forName(className);
62         
63         Constructor[] cons=clazz.getDeclaredConstructors();
64         
65         
66     }
67     // 获取父类的泛型
68     public static void test5()
69     {
70         Class clazz=Person.class;
71         Type type=clazz.getGenericSuperclass();
72         
73         // 强转换成 子类
74         ParameterizedType param=(ParameterizedType)type;
75         
76         // JDBC 多个
77         Type[] args=param.getActualTypeArguments();
78         
79         // args强制转换类型 输出 得到父类的泛型
80         System.out.println(((Class)args[0]).getName());
81     }
82     public static void main(String[] args)
83     {
84         //tets1();
85         //test2();
86         test5();
87     }
88 }
原文地址:https://www.cnblogs.com/woainifanfan/p/6665284.html