zoukankan      html  css  js  c++  java
  • JDBC----ReflectionUtils

    1.如何利用反射的机制得到泛型的类型的理解:  注意反射时候 新建的对象的属性名 与反射时候的反射字符串必须保持一致

      1 package com.tetsReflection;
      2 
      3 /**JDBC 查询得到属性字段 反射机制返回到 JavaBean中相同类属性名的对象中
      4  * */
      5 import java.lang.reflect.*;
      6 public class ReflectionUtils {
      7 
      8     /**
      9      * 使 filed 变为可访问
     10      * @param field
     11      */
     12     public static void makeAccessible(Field field){
     13         if(!Modifier.isPublic(field.getModifiers())){
     14             field.setAccessible(true);
     15         }
     16     }
     17     /**
     18      * 直接设置对象的属性,忽略 private/protected 修饰符, 也不经过 setter
     19      * @param object
     20      * @param fieldName 属性名称
     21      * @param value*/
     22     public static void setFieldValue(Object object, String fieldName, Object value){
     23     
     24          Field field=getDeclaredField(object,fieldName);
     25          if(field==null)
     26                 throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");
     27         
     28          // 让 private 元素变得可以访问,field.setAccessible();
     29          makeAccessible(field);
     30          
     31          try {
     32             field.set(object, value);
     33         } catch (IllegalArgumentException | IllegalAccessException e) {
     34             // TODO Auto-generated catch block
     35             e.printStackTrace();
     36         }
     37     }
     38     
     39     /**
     40      * 循环向上转型, 获取对象的 DeclaredField
     41      * @param object
     42      * @param filedName
     43      * @return
     44      */
     45     public static Field getDeclaredField(Object object, String filedName)
     46     {
     47         // 一步步的循环得到 获取声明对象的祖宗类
     48         for(Class<?> superClass=object.getClass() ; superClass!=Object.class;superClass=superClass.getSuperclass())
     49         {
     50                try {
     51                 return superClass.getDeclaredField(filedName);
     52             } catch (NoSuchFieldException | SecurityException e) {
     53                 // TODO Auto-generated catch block
     54                 e.printStackTrace();
     55             }
     56         }
     57         return null;
     58     }
     59     
     60     /**
     61      * 直接读取对象的属性值, 忽略 private/protected 修饰符, 也不经过 getter
     62      * @param object
     63      * @param fieldName
     64      * @return
     65      */
     66     public static Object getFieldValue(Object object, String fieldName){
     67         Field field=getDeclaredField(object,fieldName);
     68         
     69         if (field == null)
     70             throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");
     71         
     72         makeAccessible(field);
     73         Object result=null;
     74         
     75         try {
     76             result=field.get(object);
     77         } catch (IllegalArgumentException | IllegalAccessException e) {
     78             // TODO Auto-generated catch block
     79             e.printStackTrace();
     80         }
     81         return result;
     82     }
     83     /**
     84      * 循环向上转型, 获取对象的 DeclaredMethod
     85      * @param object
     86      * @param methodName
     87      * @param parameterTypes: 指定特定成员方法有重载可能性,必须指定特定的类型变量
     88      * @return
     89      */
     90     public static Method getDeclaredMethod(Object object, String methodName, Class<?>[] parameterTypes)
     91     {
     92         for(Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){
     93             try {
     94                 //superClass.getMethod(methodName, parameterTypes);
     95                 return superClass.getDeclaredMethod(methodName, parameterTypes);
     96             } catch (NoSuchMethodException e) {
     97                 //Method 不在当前类定义, 继续向上转型
     98             }
     99             //..
    100         }
    101         
    102         return null;
    103     }
    104     /**
    105      * 直接调用对象方法, 而忽略修饰符(private, protected)
    106      * @param object
    107      * @param methodName
    108      * @param parameterTypes
    109      * @param parameters
    110      * @return
    111      * @throws InvocationTargetException 
    112      * @throws IllegalArgumentException 
    113      */
    114     public static Object invokeMethod(Object object, String methodName, Class<?> [] parameterTypes,
    115             Object [] parameters) throws InvocationTargetException{
    116         Method method=getDeclaredMethod(object,methodName, parameterTypes);
    117         
    118         if(method==null)
    119             throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + object + "]");
    120         method.setAccessible(true);
    121         
    122         // 使用 method.invoke()方法进行运行
    123         try {
    124             method.invoke(object, parameters);
    125         } catch (IllegalAccessException | IllegalArgumentException e) {
    126             // TODO Auto-generated catch block
    127             e.printStackTrace();
    128         }
    129         return method;
    130     }
    131     
    132     /**
    133      * 通过反射, 获得定义 Class 时声明的父类的泛型参数的类型
    134      * 如: public EmployeeDao extends BaseDao<Employee, String>
    135      * @param clazz
    136      * @param index
    137      * @return
    138      */
    139     public static Class getSuperClassGenricType(Class clazz,int index)
    140     {
    141         Type genType=clazz.getGenericSuperclass();
    142         
    143         // 判定s是否是ParameterType相对应的
    144         if(!(genType instanceof  ParameterizedType) )
    145             return Object.class;
    146         
    147         // 强制转换 获取超类泛型参数实际类型,返回genType 是类的接口,基本类型或者void
    148         Type []params=((ParameterizedType)genType).getActualTypeArguments();
    149         
    150         if(index>=params.length || index<0)
    151             return Object.class;
    152         
    153         if(!(params[index] instanceof Class))
    154             return Object.class;
    155         return (Class) params[index];
    156     }
    157 }

     2.

     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.util.HashMap;
     8 import java.util.Map;
     9 
    10 import org.junit.Test;
    11 
    12 public class JDBCTest {
    13 
    14     @Test
    15     public void testGet()
    16     {
    17         String sql=null;
    18         sql="select id studentid,username studentname,address studentaddress,phone studentphone from EMP where id=?";
    19         
    20         Student student=get(Student.class,sql,2);
    21         System.out.println(student);
    22         
    23     }
    24     public <T> T get(Class <T>clazz,String sql,Object...args)
    25     {
    26         // 不清楚对象是什么 
    27         T entiry=null;
    28         Connection conn=null;
    29         PreparedStatement ps=null;
    30         ResultSet rs=null;
    31         
    32         try {
    33              conn=JDBCUtils.getMysqlConn();
    34              
    35              ps=conn.prepareStatement(sql);
    36              
    37              for(int i=0;i<args.length;i++)
    38                 {
    39                     ps.setObject(i+1,args[i]);
    40                     
    41                 }
    42              rs=ps.executeQuery();
    43              
    44              // 将 rs 的属性存储到Map 对象
    45              Map<String,Object> map=new HashMap<String,Object>();
    46              
    47             while(rs.next())
    48              {
    49                  entiry= clazz.newInstance();
    50                  
    51                  // 不清楚从SQL 返回几个字段 采用SQL语句解析选择哪些列 
    52                  // 得到对哪些属性进行赋值
    53                  
    54                  // 1. 得到SQLMetaData columnname;数据库别名与类的属性对应
    55                  ResultSetMetaData rsmd=rs.getMetaData();
    56                  
    57                  int countCoumn=rsmd.getColumnCount();
    58                  // 每一条记录就是一个对象,rs.next()多条记录就有多个对象
    59                  for(int i=0;i<countCoumn;i++)
    60                  {
    61                      String columnLabel=rsmd.getColumnLabel(i+1);
    62                      Object columnValue=rs.getObject(i+1);
    63                      map.put(columnLabel, columnValue);
    64                  }
    65              }
    66                  // 利用反射机制进行 创建新的对象
    67                  if(!map.isEmpty())
    68                  {
    69                     
    70                      for(Map.Entry<String, Object> entiry1:map.entrySet())
    71                      {
    72                            String property=entiry1.getKey();
    73                             Object value=entiry1.getValue();
    74                             // c测试打印一下
    75                             System.out.println(property +": "+value);
    76                             // 注意 反射时 属性名反射的value 保持一致
    77                             ReflectionUtils.setFieldValue(entiry,property, value);
    78                      }
    79                  }
    80              
    81              
    82         } catch (Exception e) {
    83             // TODO Auto-generated catch block
    84             e.printStackTrace();
    85         }
    86         finally{
    87             JDBCUtils.closeMysql(rs, ps, conn);
    88         }
    89         return entiry;
    90         
    91     
    92         
    93     }
    94 }

     3. getClass()--这是一个非静态的方法得到Class clazz---

    问题一:反射过程中 如果不知道 原先类,怎么样去确定clazz=***.class

        由于 反射条件中Class clazz=Person.class,写DAO中事先不清楚clazz属于什么类型的.clazz ,下面的构造器中 初始化过程中 确定 clazz=***.class

       知识:

             我们一般使用对象简介的继承Object类,在Object类中包含一个 getClass的方法,利用这个方法获取一个实体的类型类,类型类 表示这个实体属于哪个类,  同时所有的类型类都是 Class类的实体, getClass()获取本子类属于的类型

     1 Type surperclass= getClass().getGenericSuperclass();
     2      //// getClass() 表示本子类,得到父类的泛型
     3      if(surperclass instanceof ParameterizedType)
     4      {
     5          ParameterizedType param=(ParameterizedType)surperclass;
     6          Type[] typeargs=param.getActualTypeArguments();
     7          
     8          if(typeargs!=null && typeargs.length>0 )
     9          {
    10               if(typeargs[0] instanceof Class)
    11                   this.clazz=(Class<T>) typeargs[0];
    12          }
    13      }

        

  • 相关阅读:
    C++中Map的使用 (个人简单的对于String的使用)
    具体数学二项式至生成函数章-----致敬Kunth
    C++中String的使用
    C++中Set的使用
    费马小定理,欧拉函数
    数论---同余法则定理
    灵活利用单链表,顺带一提可持久化链表。
    第2章 数字之魅——数字中的技巧
    Mail.Ru Cup 2018 Round 1
    Lyft Level 5 Challenge 2018
  • 原文地址:https://www.cnblogs.com/woainifanfan/p/6673820.html
Copyright © 2011-2022 走看看