Dao设计模式下的JDBC反射机制&手写dbUtils源码

版权声明:本博主所有播客均为原创作品,如有商业用途,抄袭等,必追究其法律程序。 https://blog.csdn.net/wangzijian121/article/details/82500320

Dao设计模式下的JDBC反射机制实现的更新和查询对象的(手写dbUtils源码)。
涉及到的知识:1.JDBC元数据(ResultSetMetaData)
2.反射机制,泛型
3.preparedStatement

Dao.java

package Les_10_Dao设计模式;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import Les_8_反射机制_JDBC_元数据.ReflectionUtils;

/**
 * @author zijian wang
 *  *Dao: Data Access OBJect
 *  功能:访问数据信息的类,包含了对数据的CRUD (create ,read , update ,delete)
 *      而不包含任何业务相关的信息,实现功能的模块化更有利于代码的更新。
 */
public class Dao {

    // insert ,update ,delete操作都可以包含在其中
    public void update(String sql, Object... args) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
            connection = JDBC_tools.getConnection();
            preparedStatement = connection.prepareStatement(sql);
            for (int i = 0; i < args.length; i++) {
                preparedStatement.setObject(i + 1, args[i]);
            }
            preparedStatement.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBC_tools.close(connection, preparedStatement);
        }
    }

    // 查询一条记录,返回对应的对象
    public <T> T get(Class<T> clazz, String sql, Object... args) {
        T entity = 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()) {
                ResultSetMetaData rsmd = resultSet.getMetaData();
                Map<String, Object> map = new HashMap<String, Object>();
                int columnCount = rsmd.getColumnCount();
                for (int i = 0; i < columnCount; i++) {
                    String columnLabel = rsmd.getColumnLabel(i + 1);
                    Object columnValue = resultSet.getObject(columnLabel);
                    map.put(columnLabel, columnValue);
                }
                entity = clazz.newInstance();
                for (Map.Entry<String, Object> entry : map.entrySet()) {
                    String propertyName = entry.getKey();
                    Object value = entry.getValue();
                    ReflectionUtils.setFieldValue(entity, propertyName, value);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBC_tools.close(connection, preparedStatement, resultSet);
        }

        return entity;
    }

JDBC_tools.java

package Les_10_Dao设计模式;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBC_tools {

    // 获取连接
    public static Connection getConnection() {
        String driver = "com.mysql.jdbc.Driver";
        String url = "jdbc:mysql://localhost:3306/test?characterEncoding=utf8&amp;useSSL=false";
        String user = "root";
        String password = "root";
        Connection conn = null;
        try {
            Class.forName(driver);
            conn = DriverManager.getConnection(url, user, password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conn;
    }

    // 关闭连接 和PreparedStatement(任何时候都不要使用 Statement!!!)
    public static void close(Connection connection, PreparedStatement preparedStatement) {
        if (connection != null) {
            try {
                connection.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (preparedStatement != null) {
            try {
                preparedStatement.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    // 关闭连接,权限, Resulset
    public static void close(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet) {
        if (connection != null) {
            try {
                connection.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (preparedStatement != null) {
            try {
                preparedStatement.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 执行sql语句,可以执行任何添加和修改的操作
     * 
     * @param sql:insert
     *            ,update ,delete 不包含select
     * @param args:填写sql占位符的可变参数
     */
    public static void update2(String sql, Object... args) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
            connection = JDBC_tools.getConnection();
            preparedStatement = connection.prepareStatement(sql);
            for (int i = 0; i < args.length; i++) {
                preparedStatement.setObject(i + 1, args[i]);
            }
            preparedStatement.executeUpdate();
            System.out.println("更新成功!!");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBC_tools.close(connection, preparedStatement, null);
        }
    }

    /**
     * 执行sql的方法
     * 
     * @param sql:insert
     *            ,update ,delete 不包含select
     * @throws SQLException
     */
    public static void update(String sql) throws SQLException {
        Connection connection = getConnection();
        // 2.准备插入的SQL语句
        // 3执行插入操作 (1.获取操作sql语句的Statement 对象 2.
        Statement statement = connection.createStatement();
        try {
            // 调用Statement对象的executeUpdate(sql)执行SQL语句执行插入)
            statement.execute(sql);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                /*
                 * 关闭的顺序是:先关闭后获取的,先关闭Statement 后关闭Connection 关闭的顺序可能是
                 * 先关闭后获取的,先关闭Statement 后关闭Connection
                 */
                if (statement != null) {
                    // 4.关闭Statement对象
                    statement.close();
                }
            } catch (Exception e2) {
                // 关闭connection对象
                connection.close();
            }
        }
    }
}

ReflectionUtils.java

package Les_10_Dao设计模式;

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;

import com.mysql.jdbc.Field;

/**
 * 反射的 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(java.lang.reflect.Field field) {
        if (!Modifier.isPublic(field.getModifiers())) {
            field.setAccessible(true);
        }
    }

    /**
     * 循环向上转型, 获取对象的 DeclaredField
     * @param object
     * @param filedName
     * @return
     */
    public static java.lang.reflect.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) {
        java.lang.reflect.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) {
        java.lang.reflect.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;
    }
}

Student.java

public class Student {

    private int id;
    private String name;
    private String grade;

    public Student() {
        super();
    }

    public Student(int id, String name, String grade) {
        super();
        this.id = id;
        this.name = name;
        this.grade = grade;
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getGrade() {
        return grade;
    }

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

}

猜你喜欢

转载自blog.csdn.net/wangzijian121/article/details/82500320