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

清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>

遇到了若干问题:

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
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