第二步:将ResultSet转化为实体对象

本帖内容转自http://blog.csdn.net/stevene/article/details/575141

      在我以往开发所用的商业平台里,有一个Record对象,它类似ResultSet,是执行sql查询语句返回的结果集,它有一个toBean方法,可以将Record对象转换成实体对象。

      就像某些登录案例中User表和User对象,其数据表字段和User类成员变量是一一对应的,当用select * from user得到一个ResultSet后,Record就不需要rs.getString(字段名)这样麻烦得获取了,只要类似有toBean(User.class)这样的方法,就可以得到一个List<User>。那么处理list.get(i)要比rs.next()要方便得多了。

      在csdn上找到一个解决方法,测试可行。根据TDD,我先贴出测试代码,只是修改了第一步里的测试代码。

第二步:将ResultSet转化为实体对象

通过执行方法,由rs和Plan类得到一个Object数组。这个数组里每一个对象可以被强制转换成Plan类型。可能作者为了展示一个由数据表到Bean的过程,在我所使用的商业中间件中,参数不是用"com.plan.dao.Plan"而是Plan.class,所以返回的也就是Plan类型。

通过那个网址也可以复制下代码,在这里我将运行成功的代码贴出来。以开源中国的代码空间,复制起来更容易一点。

ConvertResultSetToEntity.java


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计划奠定了更加坚实的基础。

你可能感兴趣的:(第二步:将ResultSet转化为实体对象)