成员变量命名不规范导致的错误 Class has no flields;

JDBC 映射数据库时成员变量命名不规范导致的bug //未完待续,待补充测试信息;

JDBC连接数据库时,用新建的实体类去映射数据库中表信息,因为命名不规范,导致输出结果始终为空;

期间解析过程正常,添加过程正常

映射类:

public class Dep {
    private Integer Did;
    private String Dname;

    public Dep() {
    }

    public Dep(Integer did, String dname) {
        this.Did = did;
        this.Dname=dname;
    }

属性Did映射数据库中的表dep的字段Did,在解析多行内容时会将其打包成键值对对象添加到list中;

这里的错误是:成员变量did的首字母大写 Did,在解析过程会按照对待类的方式去解析,

而存在两种情况 ,具体是哪一个有待测试;

  1. 无法正常执行metaData.getColumnCount();

  2. 无法使getDecalerdField方法成功获得到字段;

代码:

第一部分:封装一个工具类

package util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class BaseDao {
    /**
     * 通用 Update 方法,用于处理 insert, delete, update SQL语句操作。
     *
     * @param sql        执行所需的SQL语句,字符串类型
     * @param parameters 针对当前SQL语句参数列表,为Object类型,不定长参数
     * @return 当前SQL语句操作,对数据表的影响行数。
     */
    public int update(String sql, Object... parameters) {
        // 1. 操作 SQL 语句必备变量准备和数据库连接对象获取
        PreparedStatement statement = null;
        Connection connection = JdbcUtils.getConnection();

        int affectedRows = 0;

        // 2. 判断用户给予当前方法 SQL 是否为null
        if (null == sql || sql.isEmpty()) {
            // 非法参数异常
            throw new IllegalArgumentException("SQL语句参数不合法");
        }

        try {
            // 3. 预处理SQL语句,得到PreparedStatement对象
            statement = connection.prepareStatement(sql);

            // 4. 赋值参数
            assignSqlParameters(statement, parameters);

            // 5. 执行SQL语句
            affectedRows = statement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.close(connection, statement);
        }

        return affectedRows;
    }


    /**
     * 用于满足通用查询操作的 query方法,指定用户给予的SQL语句,对应参数已经整个数据行对应的
     * 数据类型,转换为 List集合返回。
     * tips: 当前操作有且只能针对 类对象类型,不得用于基本类型查询操作。
     *
     * @param sql        String SQL 语句
     * @param cls        当前数据行映射对应的类型 Class类型【ROM思想 关系 对象 映射】
     * @param parameters 对应当前SQL语句参数
     * @param <T>        自定义泛型无意义占位符
     * @return 保存用户指定数据类型的List集合,如果没有数据查询结果,返回null
     */
    public <T> List<T> query(String sql, Class<T> cls, Object... parameters) {
        // 1. 判断用于给予当前方法参数是否合适
        if (null == sql || sql.isEmpty() || null == cls) {
            throw new IllegalArgumentException("给予当前query方法参数不合法");
        }

        // 2. 准备数据库操作必要内容
        ResultSet resultSet = null;
        PreparedStatement statement = null;
        Connection connection = JdbcUtils.getConnection();
        List<T> list = new ArrayList<>();

        try {
            // 3. 预处理SQL语句,得到PreparedStatement对象
            statement = connection.prepareStatement(sql);

            // 4. SQL语句参数赋值操作
            assignSqlParameters(statement, parameters);

            // 5. 执行SQL 语句 得到ResultSet结果集对象
            resultSet = statement.executeQuery();

            // 6. 获取结果集元数据
            ResultSetMetaData metaData = resultSet.getMetaData();

            // 7. 通过结果集元数据获取对应的字段个数
            int columnCount = metaData.getColumnCount();

            // 8. 解析数据
            while (resultSet.next()) {
                // 每一行数据对应一个类对象,当前类对象需要通过反射方式进行创建
                T object = cls.getConstructor().newInstance();

                // 解析字段数据 ==> 成员变量
                for (int i = 1; i <= columnCount; i++) {
                    // 获取字段名称 ==> 成员变量名
                    String columnName = metaData.getColumnName(i);
                    // 获取对应字段 String 数据
                    String value = resultSet.getString(columnName);

                    setProperty(object, columnName, value);
                }

                list.add(object);
            }
        } catch (SQLException | NoSuchMethodException | InstantiationException |
                IllegalAccessException | InvocationTargetException | NoSuchFieldException e) {
            e.printStackTrace();
        }

        return list.size() != 0 ? list : null;
    }

    private void assignSqlParameters(PreparedStatement statement, Object[] parameters) throws SQLException {
        // 4.1 获取 SQL 语句预处理对象元数据,得到参数个数
        int parameterCount = statement.getParameterMetaData().getParameterCount();

        // 4.2 判断参数数组数据个数 和当前 parameterCount 参数个数是否一致
        if (parameterCount != 0 && parameters.length == parameterCount) {
            for (int i = 0; i < parameterCount; i++) {
                statement.setObject(i + 1, parameters[i]);
            }
        }
    }

    /**
     * 私有化类内使用方法,用于处理指定类对象,指定成员变量名称,以及对应当前成员变量String类型数据,赋值
     * 转换过程。
     *
     * @param o         符合JavaBean规范类对象。
     * @param fieldName 指定成员变量名称
     * @param value     对应当前成员变量 String类型赋值数据
     */
    private void setProperty(Object o, String fieldName, String value) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        // 1. 根据字段名称获取对应的Field类对象
        Field declaredField = o.getClass().getDeclaredField(fieldName);
        declaredField.setAccessible(true);

        // 2. 获取当前成员变量对应数据类型 Integer ==> parseInt
        Class<?> type = declaredField.getType();

        // 3. 判断当前数据类型,进行赋值操作
        if (type.equals(Integer.class)) {
            declaredField.set(o, Integer.parseInt(value));
        } else if (type.equals(Character.class)) {
            declaredField.set(o, value.charAt(0));
        } else if (type.equals(String.class)) {
            declaredField.set(o, value);
        } else {
            // java.lang.Long ==> "Long"
            String typeName = type.getName().substring(type.getName().lastIndexOf('.') + 1);

            // 找出parseLong(String)
            Method method = type.getMethod("parse" + typeName, String.class);

            // method是对应的parseLong方法,value是对应需要进行的String类型数据,因为parse方法都是static方法
            // 执行操作无需类对象,直接null即可
            declaredField.set(o, method.invoke(null, value));
        }
    }
}

第二部分:测试方法:调用query查找数据库表内容;

package newpackage1;


import Util.BaseDao2;

import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;

public class test7ForQuery extends BaseDao2 {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InstantiationException, SQLException, InvocationTargetException, NoSuchFieldException, ClassNotFoundException {

        BaseDao2 baseDao2 = new BaseDao2();
        baseDao2.query("select * from  javaee2106.dep  where  Did <?",Dep.class,5);

    }
}
上一篇:2021-06-12-刘铁猛C#语言入门详解-学习笔记P14、P15表达式,语句详解[2、3]


下一篇:C语言控制语句:循环