Java反射封装公有DAO

现在都是用框架去开发,既简单又快速,给我们提供了很多便利;有利便有弊,坏处就是依赖框架,忘记了Java基础,不在关注底层是怎么实现的,这里大家一起回顾一下最原始的jdbc写法:

第一步:导入jar包,这里不多说了,百度都有;

第二步:创建BaseDao(偷下懒,把所有方法都写在一个类里面了),上代码:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 公共dao类
 */
@Component
public class BaseDao {

    private final Logger logger = LoggerFactory.getLogger(BaseDao.class);
    private Connection conn = null;
    private PreparedStatement ps = null;
    private ResultSet rs = null;


    /**
     * 建立数据库连接
     * @return
     */
    private Connection getConnection() {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123456");

            if (!conn.isClosed()) {
                logger.info("################# 数据库连接成功 #################");
            }
        } catch (ClassNotFoundException e) {
            logger.error("加载jdbc.Driver异常", e);
            throw new RuntimeException("加载jdbc.Driver异常", e);
        } catch (SQLException e) {
            logger.error("建立数据库连接异常", e);
            throw new RuntimeException("建立数据库连接异常", e);
        }
        return conn;
    }

    /**
     * 方法用途: 公共查询方法,返回List集合
* 操作步骤: TODO
* ${tags} */ public List queryList(Class clazz, String sql, Object... params) { T t; List list = new ArrayList<>(); logger.info(sql); logger.info(null == params? "" : params.toString()); try { Field[] fields = getAllFields(clazz); conn = getConnection(); ps = conn.prepareStatement(sql); initParams(ps, params); rs = ps.executeQuery(); // 返回结果集 while (rs.next()) { t = getObjResult(fields, rs, clazz); list.add(t); } logger.info(String.format("################# 查询成功,共%s条记录 #################", list.size())); } catch (SQLException e) { logger.error("执行查询异常", e); throw new RuntimeException("执行查询异常", e); } finally { // 关闭数据库连接 closeDb(rs, ps, conn); } return list; } /** * 将每行结果存入map集合,对象属性名为key,查询出的结果为value * @param fields * @param rs * @return */ private T getObjResult(Field[] fields, ResultSet rs, Class clazz) { T t = null; Field field; Method method; String fieldName; String fieldType; try { t = clazz.newInstance(); for (int i = 0; i < fields.length; i++) { field = fields[i]; field.setAccessible(true); fieldName = field.getName(); if (fieldName.equals("serialVersionUID")) { continue; } fieldType = field.getType().getName(); method = getMethod(clazz, field, fieldName, fieldType); Object value = rs.getObject(initField(fieldName)); if (fieldType.equals("java.lang.String")) { method.invoke(t, value); } else if (fieldType.equals("java.lang.Integer")) { method.invoke(t, Integer.valueOf(value.toString())); } } } catch (SQLException e) { logger.error("rs获取结果异常", e); throw new RuntimeException("rs获取结果异常", e); } catch (InvocationTargetException e) { logger.error("method.invoke方法执行异常", e); throw new RuntimeException("method.invoke方法执行异常", e); } catch (IllegalAccessException e) { logger.error("method.invoke方法执行异常", e); throw new RuntimeException("method.invoke方法执行异常", e); } catch (InstantiationException e) { logger.error("建立T对象异常", e); throw new RuntimeException("建立T对象异常", e); } return t; } /** * 对象属性的set方法 * @param clazz * @param field * @param fieldName * @param fieldType * @return */ private Method getMethod(Class clazz, Field field, String fieldName, String fieldType){ Method method = null; try { if (fieldType.equals("java.lang.Boolean")) { method = clazz.getDeclaredMethod("is" + getMethodName(fieldName), field.getType()); } else { method = clazz.getDeclaredMethod("set" + getMethodName(fieldName), field.getType()); } } catch (NoSuchMethodException e) { Class superClazz = clazz.getSuperclass(); method = getMethod(superClazz, field, fieldName, fieldType); } return method; } /** * 获取所有属性(getSuperclass:获取父类属性) * @param clazz * @param * @return */ private Field[] getAllFields(Class clazz) { Class superClazz = clazz; List fieldList = new ArrayList<>(); while (null != superClazz) { fieldList.addAll(new ArrayList<>(Arrays.asList(superClazz.getDeclaredFields()))); superClazz = superClazz.getSuperclass(); } Field[] fields = new Field[fieldList.size()]; fieldList.toArray(fields); return fields; } /** * 将驼峰属性名转换为带下划线字段(xx_xx) * @param field * @return */ private String initField(String field) { StringBuilder newField = new StringBuilder(); for (int i = 0; i < field.length(); i++) { char c = field.charAt(i); if (Character.isUpperCase(c)) { newField.append("_").append(Character.toLowerCase(c)); } else { newField.append(c); } } return newField.toString(); } /** * 组装参数 * @param ps * @param params */ private void initParams(PreparedStatement ps, Object... params) { if (null != params && params.length > 0) { try { for (int i = 0; i < params.length; i++) { ps.setString(i, params[i].toString()); } } catch (SQLException e) { logger.error("ps设置参数异常", e); throw new RuntimeException("ps设置参数异常", e); } } } /** * 方法用途: 把一个字符串的第一个字母大写、效率是最高的
* 操作步骤: TODO
* ${tags} */ private static String getMethodName(String fildeName) { byte[] items = fildeName.getBytes(); items[0] = (byte) ((char) items[0] - 'a' + 'A'); return new String(items); } /** * 关闭数据库连接 * @param rs * @param ps * @param conn */ private void closeDb(ResultSet rs, PreparedStatement ps, Connection conn) { try { if (null != rs) { rs.close(); } if (null != ps) { ps.close(); } if (null != conn) { conn.close(); } logger.info("################# 连接关闭成功 #################"); } catch (SQLException e) { logger.error("关闭连接异常", e); throw new RuntimeException("关闭连接异常", e); } } }

好了,都是我手敲出来的代码,注释也都加上了,不懂的多读几遍代码吧,实在看不明白先回顾下Java反射的基础(Java反射基础案例)

你可能感兴趣的:(Java)