zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    前端利用百度开发文档给的web服务接口实现对某个区域周边配套的检索
    libevent源码学习(13):事件主循环event_base_loop
    libevent源码学习(11):超时管理之min_heap
    libevent源码学习(10):min_heap数据结构解析
    libevent源码学习(8):event_signal_map解析
    libevent源码学习(9):事件event
    libevent源码学习(6):事件处理基础——event_base的创建
    libevent源码学习(5):TAILQ_QUEUE解析
    仿Neo4j里的知识图谱,利用d3+vue开发的一个网络拓扑图
    element表格内每一行删除提示el-popover的使用要点
  • 原文地址:https://www.cnblogs.com/woainifanfan/p/6665284.html
Copyright © 2011-2022 走看看