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 }
下面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 }
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 }
静态代理:
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 }