| 注册
请输入搜索内容

热门搜索

Java Linux MySQL PHP JavaScript Hibernate jQuery Nginx
cp66
10年前发布

利用反射及JDBC元数据编写通用的查询方法

遇到了若干问题:

1.从oracle返回的列名都是大写,再用反射,就找不到相对应得 名字

2.oracle 中number类型 返回来,就变成了BigDecimal

    public static void main(String[] args){                String sql = "SELECT IDCARD , examcard , "                        + "studentname ,"                                                + "lacation LoCATION,grade "                        + " FROM student WHERE IDCARD = ?";                Student s = get(Student.class, sql, 7);                System.out.println(s);            }                    //String sql = "SELECT id, name, email, birth "        <span style="white-space:pre">    </span>//<span style="white-space:pre">         </span>+ "FROM customers WHERE id = ?";                        public static <T> T get(Class<T> clazz, String sql, Object... args) {                T entity = null;                        Connection connection = null;                PreparedStatement preparedStatement = null;                ResultSet resultSet = null;                        try {                    //1. 得到 ResultSet 对象                    connection = JDBC_Tools.getConnection();                    preparedStatement = connection.prepareStatement(sql);                    for (int i = 0; i < args.length; i++) {                        preparedStatement.setObject(i + 1, args[i]);                    }                    resultSet = preparedStatement.executeQuery();                            //2. 得到 ResultSetMetaData 对象                    ResultSetMetaData rsmd = resultSet.getMetaData();                                        //3. 创建一个 Map<String, Object> 对象, 键: SQL 查询的列的别名,                     //值: 列的值                    Map<String, Object> values = new HashMap<>();                                        //4. 处理结果集. 利用 ResultSetMetaData 填充 3 对应的 Map 对象                    if(resultSet.next()){                        for(int i = 0; i < rsmd.getColumnCount(); i++){                            //从 ResultSetMetaData 获取列的别名                            String columnLabel = rsmd.getColumnLabel(i + 1);                            //从 结果集 中获取列的值                            Object columnValue = resultSet.getObject(i + 1);                                                        values.put(columnLabel, columnValue);                        }                    }                    //5. 若 Map 不为空集, 利用反射创建 clazz 对应的对象                    if(values.size() > 0){                        entity = clazz.newInstance();                                                //5. 遍历 Map 对象, 利用反射为 Class 对象的对应的属性赋值.                         for(Map.Entry<String, Object> entry: values.entrySet()){                            String fieldName = entry.getKey();                            Object value = entry.getValue();                            //System.out.println(fieldName+":"+value);                        ReflectionUtils.setFieldValue(entity, fieldName, value); //出问题                            //System.out.println(ReflectionUtils.getDeclaredField(entity,fieldName));                        }                    }                } catch (Exception e) {                    e.printStackTrace();                } finally {                    JDBC_Tools.relaseSource(resultSet, connection, preparedStatement);                }                return entity;            }        }     

ReflectionUtils.setFieldValue(entity, fieldName, value);出问题

java.lang.IllegalArgumentException: Can not set int field xuezaipiao3.Student.GRADE to java.math.BigDecimal
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168)
at sun.reflect.UnsafeIntegerFieldAccessorImpl.set(UnsafeIntegerFieldAccessorImpl.java:98)
at java.lang.reflect.Field.set(Field.java:741)
at xuezaipiao3.ReflectionUtils.setFieldValue(ReflectionUtils.java:156)
at xuezaipiao3.ThinkInJDBC.get(ThinkInJDBC.java:77)
at xuezaipiao3.ThinkInJDBC.main(ThinkInJDBC.java:45)
Student [IDCARD=0, EXAMCARD=0, STUDENTNAME=null, LOCATION=7, GRADE=0]


Oracle  中 number类型 通过ResultSet 的 getObject() 返回的是 BigDecimal ,无法强制转化,而且 ResultSetMetaData 的 getColumnLabel() 取回的 列的别名是大写 

MySQL不存在这样的问题

用的  Oracle 10g 


ReflectionUtils

    package xuezaipiao3;                import java.lang.reflect.Field;        import java.lang.reflect.InvocationTargetException;        import java.lang.reflect.Method;        import java.lang.reflect.Modifier;        import java.lang.reflect.ParameterizedType;        import java.lang.reflect.Type;                /**        * 反射的 Utils 函数集合        * 提供访问私有变量, 获取泛型类型 Class, 提取集合中元素属性等 Utils 函数        * @author Administrator        *        */        public class ReflectionUtils {                                /**            * 通过反射, 获得定义 Class 时声明的父类的泛型参数的类型            * 如: public EmployeeDao extends BaseDao<Employee, String>            * @param <T>            * @param clazz            * @param index            * @return            */            @SuppressWarnings("unchecked")            public static  Class getSuperClassGenricType(Class clazz, int index){                Type genType = clazz.getGenericSuperclass();                                if(!(genType instanceof ParameterizedType)){                    return Object.class;                }                                Type [] params = ((ParameterizedType)genType).getActualTypeArguments();                                if(index >= params.length || index < 0){                    return Object.class;                }                                if(!(params[index] instanceof Class)){                    return Object.class;                }                                return (Class) params[index];            }                        /**            * 通过反射, 获得 Class 定义中声明的父类的泛型参数类型            * 如: public EmployeeDao extends BaseDao<Employee, String>            * @param <T>            * @param clazz            * @return            */            @SuppressWarnings("unchecked")            public static<T> Class<T> getSuperGenericType(Class<T> clazz){                return getSuperClassGenricType(clazz, 0);            }                        /**            * 循环向上转型, 获取对象的 DeclaredMethod            * @param object            * @param methodName            * @param parameterTypes            * @return            */            public static Method getDeclaredMethod(Object object, String methodName, Class<?>[] parameterTypes){                                for(Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){                    try {                        //superClass.getMethod(methodName, parameterTypes);                        return superClass.getDeclaredMethod(methodName, parameterTypes);                    } catch (NoSuchMethodException e) {                        //Method 不在当前类定义, 继续向上转型                    }                    //..                }                                return null;            }                        /**            * 使 filed 变为可访问            * @param field            */            public static void makeAccessible(Field field){                if(!Modifier.isPublic(field.getModifiers())){                    field.setAccessible(true);                }            }                        /**            * 循环向上转型, 获取对象的 DeclaredField            * @param object            * @param filedName            * @return            */            public static Field getDeclaredField(Object object, String filedName){                                for(Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){                    try {                        return superClass.getDeclaredField(filedName);                    } catch (NoSuchFieldException e) {                        //Field 不在当前类定义, 继续向上转型                    }                }                return null;            }                        /**            * 直接调用对象方法, 而忽略修饰符(private, protected)            * @param object            * @param methodName            * @param parameterTypes            * @param parameters            * @return            * @throws InvocationTargetException             * @throws IllegalArgumentException             */            public static Object invokeMethod(Object object, String methodName, Class<?> [] parameterTypes,                    Object [] parameters) throws InvocationTargetException{                                Method method = getDeclaredMethod(object, methodName, parameterTypes);                                if(method == null){                    throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + object + "]");                }                                method.setAccessible(true);                                try {                    return method.invoke(object, parameters);                } catch(IllegalAccessException e) {                    System.out.println("不可能抛出的异常");                }                                 return null;            }                        /**            * 直接设置对象属性值, 忽略 private/protected 修饰符, 也不经过 setter            * @param object            * @param fieldName            * @param value            */            public static void setFieldValue(Object object, String fieldName, Object value){                Field field = getDeclaredField(object, fieldName);                                if (field == null)                    throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");                                makeAccessible(field);                                try {                                        field.set(object, value);                } catch (IllegalAccessException e) {                    System.out.println("不可能抛出的异常");                }            }                        /**            * 直接读取对象的属性值, 忽略 private/protected 修饰符, 也不经过 getter            * @param object            * @param fieldName            * @return            */            public static Object getFieldValue(Object object, String fieldName){                Field field = getDeclaredField(object, fieldName);                                if (field == null)                    throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");                                makeAccessible(field);                                Object result = null;                                try {                    result = field.get(object);                } catch (IllegalAccessException e) {                    System.out.println("不可能抛出的异常");                }                                return result;            }        }  

来自:http://blog.csdn.net/wjw0130/article/details/43760487