本帖内容转自http://blog.csdn.net/stevene/article/details/575141 java
在我以往开发所用的商业平台里,有一个Record对象,它相似ResultSet,是执行sql查询语句返回的结果集,它有一个toBean方法,能够将Record对象转换成实体对象。 sql
就像某些登陆案例中User表和User对象,其数据表字段和User类成员变量是一一对应的,当用select * from user获得一个ResultSet后,Record就不须要rs.getString(字段名)这样麻烦得获取了,只要相似有toBean(User.class)这样的方法,就能够获得一个List<User>。那么处理list.get(i)要比rs.next()要方便得多了。 数组
在csdn上找到一个解决方法,测试可行。根据TDD,我先贴出测试代码,只是修改了第一步里的测试代码。 测试
经过执行方法,由rs和Plan类获得一个Object数组。这个数组里每个对象能够被强制转换成Plan类型。可能做者为了展现一个由数据表到Bean的过程,在我所使用的商业中间件中,参数不是用"com.plan.dao.Plan"而是Plan.class,因此返回的也就是Plan类型。 this
经过那个网址也能够复制下代码,在这里我将运行成功的代码贴出来。以开源中国的代码空间,复制起来更容易一点。 .net
ConvertResultSetToEntity.java code
package com.plan.entity; import java.lang.reflect.Array; import java.lang.reflect.Method; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.util.HashMap; public class ConvertResultSetToEntity { /** * 实现结果集到实体对象/值对象/持久化对象转换 * * @param rsResult * ResultSet * @param strEntity * String * @throws Exception * @return Object[] */ public static Object[] parseDataEntityBeans(ResultSet rsResult, String strEntity) throws Exception { DataTableEntity dataTable = null; java.util.List listResult = new java.util.ArrayList(); // 注册实体,strEntity指定的实体类名称字符串 Class classEntity = Class.forName(strEntity); // 获取实体中定义的方法 HashMap hmMethods = new HashMap(); for (int i = 0; i < classEntity.getDeclaredMethods().length; i++) { MethodEntity methodEntity = new MethodEntity(); // 方法的名称 String methodName = classEntity.getDeclaredMethods()[i].getName(); String methodKey = methodName.toUpperCase(); // 方法的参数 Class[] paramTypes = classEntity.getDeclaredMethods()[i] .getParameterTypes(); methodEntity.setMethodName(methodName); methodEntity.setMethodParamTypes(paramTypes); // 处理方法重载 if (hmMethods.containsKey(methodKey)) { methodEntity.setRepeatMethodNum(methodEntity .getRepeatMethodNum() + 1); methodEntity.setRepeatMethodsParamTypes(paramTypes); } else { hmMethods.put(methodKey, methodEntity); } } // 处理ResultSet结构体信息 if (rsResult != null) { ResultSetMetaData rsMetaData = rsResult.getMetaData(); int columnCount = rsMetaData.getColumnCount(); dataTable = new DataTableEntity(columnCount); // 获取字段名称,类型 for (int i = 0; i < columnCount; i++) { String columnName = rsMetaData.getColumnName(i + 1); int columnType = rsMetaData.getColumnType(i + 1); dataTable.setColumnName(columnName, i); dataTable.setColumnType(columnType, i); } } // 处理ResultSet数据信息 while (rsResult.next()) { // 调用方法,根据字段名在hsMethods中查找对应的set方法 Object objResult = ParseObjectFromResultSet(rsResult, dataTable, classEntity, hmMethods); listResult.add(objResult); } // 以数组方式返回 Object objResutlArray = Array.newInstance(classEntity, listResult.size()); listResult.toArray((Object[]) objResutlArray); return (Object[]) objResutlArray; } /** * 从Resultset中解析出单行记录对象,存储在实体对象中 */ public static Object ParseObjectFromResultSet(ResultSet rs, DataTableEntity dataTable, Class classEntity, java.util.HashMap hsMethods) throws Exception { Object objEntity = classEntity.newInstance(); Method method = null; int nColumnCount = dataTable.getColumnCount(); String[] strColumnNames = dataTable.getColumnNames(); for (int i = 0; i < nColumnCount; i++) { // 获取字段值 Object objColumnValue = rs.getObject(strColumnNames[i]); // HashMap中的方法名key值 String strMethodKey = null; // 获取set方法名 if (strColumnNames[i] != null) { strMethodKey = String.valueOf("SET" + strColumnNames[i].toUpperCase()); } // 值和方法都不为空,这里方法名不为空便可,值能够为空的 if (strMethodKey != null) { // 判断字段的类型,方法名,参数类型 try { MethodEntity methodEntity = (MethodEntity) hsMethods .get(strMethodKey); String methodName = methodEntity.getMethodName(); int repeatMethodNum = methodEntity.getRepeatMethodNum(); Class[] paramTypes = methodEntity.getMethodParamTypes(); method = classEntity.getMethod(methodName, paramTypes); // 若是重载方法数 > // 1,则判断是否有java.lang.IllegalArgumentException异常,循环处理 try { // 设置参数,实体对象,实体对象方法参数 method.invoke(objEntity, new Object[] { objColumnValue }); } catch (java.lang.IllegalArgumentException e) { // 处理重载方法 for (int j = 1; j < repeatMethodNum; j++) { try { Class[] repeatParamTypes = methodEntity .getRepeatMethodsParamTypes(j - 1); method = classEntity.getMethod(methodName, repeatParamTypes); method.invoke(objEntity, new Object[] { objColumnValue }); break; } catch (java.lang.IllegalArgumentException ex) { continue; } } } } catch (NoSuchMethodException e) { throw new NoSuchMethodException(); } catch (Exception ex) { ex.printStackTrace(); } } } return objEntity; } }
这个类还须要以下两个类 中间件
DataTableEntity.java 对象
public class DataTableEntity { // 查询出的ReslutSet中的字段数量 private int columnCount = 0; // 字段名称数组 private String[] columnNames; // 字段类型数组 private int[] columnTypes; // 默认构造器 public DataTableEntity() { this(0); } // 初始化构造器 public DataTableEntity(int columnCount) { this.columnCount = columnCount; this.columnNames = new String[columnCount]; this.columnTypes = new int[columnCount]; } // 获取字段数量 public int getColumnCount() { return this.columnCount; } // 获取字段名称数组 public String[] getColumnNames() { return this.columnNames; } // 获取第index个字段名称,若是index字段不存在,则抛出ArrayIndexOutOfBoundsException异常 public String getColumnName(int index) { if (index <= this.columnCount) { return this.columnNames[index]; } else { throw new ArrayIndexOutOfBoundsException(); } } // 设置字段名称数组 public void setColumnNames(String[] columnNames) { this.columnNames = columnNames; } // 设置第index个字段名称,若是index字段不存在,则抛出ArrayIndexOutOfBoundsException异常 public void setColumnName(String columnName, int index) { if (index <= this.columnCount) { this.columnNames[index] = columnName; } else { throw new ArrayIndexOutOfBoundsException(); } } // 获取字段类型数组 public int[] getColumnTypes() { return this.columnTypes; } // 获取字段类型 public int getColumnType(int index) { if (index <= this.columnCount) { return this.columnTypes[index]; } else { throw new ArrayIndexOutOfBoundsException(); } } // 设置字段类型数组 public void setColumnTypes(int[] columnTypes) { this.columnTypes = columnTypes; } // 获取字段类型 public void setColumnType(int columnType, int index) { if (index <= this.columnCount) { this.columnTypes[index] = columnType; } else { throw new ArrayIndexOutOfBoundsException(); } } }
import java.util.ArrayList; public class MethodEntity { // 方法名称 private String methodName; // 重载方法个数 private int repeatMethodNum = 1; // 方法参数类型列表 private Class[] methodParamTypes; // 存放重载方法参数 private ArrayList repeatMethodsParamTypes; /** * 获取参数名称 * * @return */ public String getMethodName() { return methodName; } /** * 获取方法参数类型列表 * * @return */ public Class[] getMethodParamTypes() { return methodParamTypes; } /** * 设置参数名称 * * @param string */ public void setMethodName(String string) { methodName = string; } /** * 设置参数类型列表 * * @param classes */ public void setMethodParamTypes(Class[] classes) { methodParamTypes = classes; } /** * 获取重载方法个数 * * @return */ public int getRepeatMethodNum() { return repeatMethodNum; } /** * 获取第i个重载方法参数列表 * * @return */ public Class[] getRepeatMethodsParamTypes(int i) { int count = this.repeatMethodsParamTypes.size(); if (i <= count) { return (Class[]) this.repeatMethodsParamTypes.get(i); } else { throw new ArrayIndexOutOfBoundsException(); } } /** * 设置重载方法个数 * * @param i */ public void setRepeatMethodNum(int i) { repeatMethodNum = i; } /** * 设置重载方法参数类型 * * @param list */ public void setRepeatMethodsParamTypes(ArrayList list) { repeatMethodsParamTypes = list; } /** * 获取重载方法类型 * * @return */ public ArrayList getRepeatMethodsParamTypes() { return repeatMethodsParamTypes; } /** * 设置重载方法参数类型列表 * * @param paramTypes */ public void setRepeatMethodsParamTypes(Class[] paramTypes) { if (this.repeatMethodsParamTypes == null) this.repeatMethodsParamTypes = new ArrayList(); repeatMethodsParamTypes.add(paramTypes); } }
好了,如今我能够将ResultSet查询结果以对象的形式操做了,无疑为个人小Plan计划奠基了更加坚实的基础。 blog