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

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

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

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

34a59b3aad4baf0ca5e2e35c861c3a55.png

通过执行方法,由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计划奠定了更加坚实的基础。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值