第二步:將ResultSet轉化爲實體對象

本帖內容轉自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();
		}
	}
}



MethodEntity.java

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

相關文章
相關標籤/搜索