本帖內容轉自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