标签:lang 需要 jdb bean rdf arraylist sql 语句 except exe
JDBC 映射数据库时成员变量命名不规范导致的bug //未完待续,待补充测试信息;
映射类:
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,在解析过程会按照对待类的方式去解析,
而存在两种情况 ,具体是哪一个有待测试;
无法正常执行metaData.getColumnCount();
无法使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); } }
成员变量命名不规范导致的错误 Class has no flields;
标签:lang 需要 jdb bean rdf arraylist sql 语句 except exe
原文地址:https://www.cnblogs.com/msslearning/p/14960483.html