JDBC_反射及JDBC元数据编写通用的查询

1.实体类

 

package com.jdbc.DBUpdate;

/**
 * @author hyj
 * @date 2018-03-26 15:19
 */
public class Grade {
    private Integer id;
    private String name;
    private String sex;
    private Float grade;

    public Grade ( ) {
    }

    public Grade (Integer id, String name, String sex, Float grade) {
        this.id = id;
        this.name = name;
        this.sex = sex;
        this.grade = grade;
    }

    public Integer getId ( ) {
        return id;
    }

    public void setId (Integer id) {
        this.id = id;
    }

    public String getName ( ) {
        return name;
    }

    public void setName (String name) {
        this.name = name;
    }

    public String getSex ( ) {
        return sex;
    }

    public void setSex (String sex) {
        this.sex = sex;
    }

    public Float getGrade ( ) {
        return grade;
    }

    public void setGrade (Float grade) {
        this.grade = grade;
    }

    @Override
    public String toString ( ) {
        return "Grade{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", grade=" + grade +
                '}';
    }
}

2.普通方法获取实体,需要为静态方法

 

public static Grade getGrade (String sql, Object... args) {
    Grade grade=null;
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    ResultSet resultSet = null;
    try {
        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();
        if (resultSet.next()) {
            grade=new Grade();
            grade.setId(resultSet.getInt(1));
            grade.setName(resultSet.getNString(2));
            grade.setSex(resultSet.getString(3));
            grade.setGrade(resultSet.getFloat(4));
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        JDBC_Tools.relaseSource(resultSet, preparedStatement, connection);
    }
    return grade;

}

测试方法;

 

@Test
public void testGet() {
    String sql = "select id,name,sex,grade "
            + " from Grade where id=?";
    System.out.println(sql);
    Grade grade= JDBC_Tools.getGrade(sql, 5);
    System.out.println(grade);
}

3.改进查询方法

加入

ReflectionUtils反射工具类
package com.jdbc.DBUpdate;  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; /**  * @author hyj  * @date 2018-03-28 10:46  * 反射工具类  */ /**  * 反射的 Utils 函数集合  * 提供访问私有变量, 获取泛型类型 Class, 提取集合中元素属性等 Utils 函数  * @author Administrator  *  */ public class ReflectionUtils { /**  * 通过反射, 获得定义 Class 时声明的父类的泛型参数的类型  * 如: public EmployeeDao extends BaseDao<Employee, String>  * @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 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;  } } 
改进方法:
/**  * 通用的查询方法:可以根据传入的 SQL、Class 对象返回 SQL 对应的记录的对象  * @param clazz: 描述对象的类型  * @param sql: SQL 语句。可能带占位符  * @param args: 填充占位符的可变参数。  * @return  */ public <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++){ 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();  ReflectionUtils.setFieldValue(entity, fieldName, value);  } } } catch (Exception e) { e.printStackTrace();  } finally { JDBC_Tools.relaseSource(resultSet, preparedStatement, connection);  } return entity; }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值