`
ghl116
  • 浏览: 164402 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

(摘抄)利用反射机制,将ResultSet处理为bean或list的方法

阅读更多

我自己的处理:写一个util类,然后封装方法

@SuppressWarnings("unchecked")
	public static List resultSetToList(ResultSet rs, Class cls)throws Exception {
	

			//取得Method 
	        Method[] methods = cls.getDeclaredMethods(); 
	       System.out.println(methods[0].getName());
			List lst = new ArrayList();
			// 用于获取列数、或者列类型
			ResultSetMetaData meta = rs.getMetaData();
			Object obj = null;
			while (rs.next()) {
				// 获取formbean实例对象
				obj = cls.newInstance(); // 用Class.forName方法实例化对象和new创建实例化对象是有很大区别的,它要求JVM首先从类加载器中查找类,然后再实例化,并且能执行类中的静态方法。而new仅仅是新建一个对象实例
				// 循环获取指定行的每一列的信息
				for (int i = 1; i <= meta.getColumnCount(); i++) {
					// 当前列名
					String colName = meta.getColumnName(i);
					
					// 设置方法名
					String setMethodName = "set" + colName;
					  
					
					 //遍历Method 
	                for (int j = 0; j < methods.length; j++) { 
	                    if (methods[j].getName().equalsIgnoreCase(setMethodName)) { 
	                        setMethodName = methods[j].getName(); 
	                        
	                        System.out.println(setMethodName);
	                    	// 获取当前位置的值,返回Object类型
	                        Object value = rs.getObject(colName); 
	                        if(value == null){
	                        	continue;
	                        }

	                        //实行Set方法 
	                        try { 
	                        	//// 利用反射获取对象
	                            //JavaBean内部属性和ResultSet中一致时候 
	                            Method setMethod = obj.getClass().getMethod( 
	                                    setMethodName, value.getClass()); 
	                            setMethod.invoke(obj, value); 
	                        } catch (Exception e) { 
	                            //JavaBean内部属性和ResultSet中不一致时候,使用String来输入值。 
	                           e.printStackTrace();
	                        } 
	                    } 
	                } 
				}
				lst.add(obj);
			}

			return lst;
		
	}
 

 

相关参考:

 

 

原文地址  http://blog.csdn.net/redria/article/details/2988158

其实反射也不是什么高深莫测的东西。反射就是我们对一个未知对象进行操作,由于它是未知的,所以我们需要从类型等方面下手,使用该对象共有的方法和属性,引用自该对象,从而得到我们想要的结果。

 

本文简单列举了一个利用反射将ResultSet的值自动赋值到POJO(JavaBean)对象的一个实例,便于大家学习。

 

package demo; 

import java.lang.reflect.Array; 
import java.lang.reflect.Method; 
import java.sql.ResultSetMetaData; 
import java.sql.ResultSet; 

/** 
 * 绑定数据处理 
 * Wrote by redria 
 */ 
public class BindData { 
    /** 
     * 从ResultSet绑定到JavaBean 
     *  
     * @param ResultSet 
     * @param DTO(JavaBean) 
     * @return DTO 
     */ 
    public static DTO bindDataToDTO(ResultSet rs, DTO dto) throws Exception { 

        //取得Method方法 
        Method[] methods = dto.getClass().getMethods(); 

        //取得ResultSet的列名 
        ResultSetMetaData rsmd = rs.getMetaData(); 
        int columnsCount = rsmd.getColumnCount(); 
        String[] columnNames = new String[columnsCount]; 
        for (int i = 0; i < columnsCount; i++) { 
            columnNames[i] = rsmd.getColumnLabel(i + 1); 
        } 

        //遍历ResultSet 
        while (rs.next()) { 
            //反射, 从ResultSet绑定到JavaBean 
            for (int i = 0; i < columnNames.length; i++) { 
                //取得Set方法 
                String setMethodName = "set" + columnNames[i]; 
                //遍历Method 
                for (int j = 0; j < methods.length; j++) { 
                    if (methods[j].getName().equalsIgnoreCase(setMethodName)) { 
                        setMethodName = methods[j].getName(); 
                        Object value = rs.getObject(columnNames[i]); 

                        //实行Set方法 
                        try { 
                            //JavaBean内部属性和ResultSet中一致时候 
                            Method setMethod = dto.getClass().getMethod( 
                                    setMethodName, value.getClass()); 
                            setMethod.invoke(dto, value); 
                        } catch (Exception e) { 
                            //JavaBean内部属性和ResultSet中不一致时候,使用String来输入值。 
                            Method setMethod = dto.getClass().getMethod( 
                                    setMethodName, String.class); 
                            setMethod.invoke(dto, value.toString()); 
                        } 
                    } 
                } 
            } 
        } 

        //戻り値 
        return dto; 
    } 

    /** 
     *从ResultSet绑定到JavaBean数组 
     *  
     * @param ResultSet 
     * @param DTO(JavaBean) 
     * @return DTO数组 
     */ 
    public static DTO[] bindDataToDTOS(ResultSet rs, DTO dto) throws Exception { 

        //取得Method 
        Method[] methods = dto.getClass().getMethods(); 

        //取得ResultSet的列名  
        ResultSetMetaData rsmd = rs.getMetaData(); 
        int columnsCount = rsmd.getColumnCount(); 
        String[] columnNames = new String[columnsCount]; 
        for (int i = 0; i < columnsCount; i++) { 
            columnNames[i] = rsmd.getColumnLabel(i + 1); 
        } 

        //取得Class 
        Class<? extends DTO> dtoClass = dto.getClass(); 

        //取得record数 
        rs.last(); 
        int rsCnt = rs.getRow(); 
        rs.beforeFirst(); 

        //DTO[]初期化 
        DTO[] dtos = (DTO[]) Array.newInstance(dtoClass, rsCnt); 

        int dtoNow = 0; 
        //遍历ResultSet 
        while (rs.next()) { 
            //DTO[]中DTO初期化 
            dtos[dtoNow] = (DTO) dtoClass.newInstance(); 
            //反射, 从ResultSet绑定到JavaBean 
            for (int i = 0; i < columnNames.length; i++) { 
                //取得Set方法 
                String setMethodName = "set" + columnNames[i]; 
                //遍历Method  
                for (int j = 0; j < methods.length; j++) { 
                    if (methods[j].getName().equalsIgnoreCase(setMethodName)) { 
                        setMethodName = methods[j].getName(); 
                        Object value = rs.getObject(columnNames[i]); 

                        //实行Set方法 
                        try { 
                            //JavaBean内部属性和ResultSet中一致时候 
                            Method setMethod = dto.getClass().getMethod( 
                                    setMethodName, value.getClass()); 
                            setMethod.invoke(dtos[dtoNow], value); 
                        } catch (Exception e) { 
                            //JavaBean内部属性和ResultSet中不一致时候,使用String来输入值。 
                            Method setMethod = dto.getClass().getMethod( 
                                    setMethodName, String.class); 
                            setMethod.invoke(dtos[dtoNow], value.toString()); 
                        } 
                    } 
                } 
            } 
            dtoNow++; 
        } 

        //返回值 
        return dtos; 
    } 
}
当然这里的DTO是一个普通的JavaBean类。我们可以建立一个基类,然后建立我们要的JavaBean子类来继承于该基类,将子类扔进来反射,我们就可以得到一个绑定好数据的子类。诚然,我这里对数据类型判别的也不多,不是和ResultSet中一直的,统统变成了String,这里可以根据需要自行修改。

 

注意:这里如果要绑定,则必须JavaBean中的属性名称和ResultSet中的列名一致,反射也需要有一个参照对象不是么,不然绑定到哪里去呢?呵呵……

 

原理么,就是拿ResultSet中的列名和JavaBean中的属性名配对,然后赋值。
 

 

 

 

http://www.blogjava.net/wanghl259748/articles/277261.html

 

一般做法是将ResultSet封装成一个个javabean然后将javabean放入list集合中返回。 

类似于: 
public   class   test   { 

DB   dbx   =   new   DB(); 

public   static   List   resultSetToList(String   sql)   throws   SQLException   { 
DB   dbx   =   new   DB(); 
ResultSet   rs   =   dbx.executeQuery(sql); 
ResultSetMetaData   md   =   rs.getMetaData(); 
for   (int   i   =   0;   i   <   md.getColumnCount();   i++)   { 
System.out.println(md.getColumnName(i)); 
System.out.println( "----------------- "); 
} 
List   list   =   new   ArrayList(); 
while   (rs.next())   { 
UserBean   bean   =   new   UserBean(); 
int   userid   =   rs.getInt( "userid "); 
String   username   =   rs.getString( "username "); 
bean.setUserid(userid   +   " "); 
bean.setUsername(username); 
list.add(bean); 
System.out.println(userid   +   "   "+username); 
} 
return   list; 
} 
}

 另外一种方法

package com.service;

import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;

import com.entity.Student;

public class Service {
    public List toList(ResultSet rs,Class cls)
    {
        try
        {
            
            List lst=new ArrayList();
            //用于获取列数、或者列类型
            ResultSetMetaData meta=rs.getMetaData();
            Object obj=null;
            while(rs.next())
            {
                //获取formbean实例对象
                obj=Class.forName(cls.getName()).newInstance();              //用Class.forName方法实例化对象和new创建实例化对象是有很大区别的,它要求JVM首先从类加载器中查找类,然后再实例化,并且能执行类中的静态方法。而new仅仅是新建一个对象实例
                //循环获取指定行的每一列的信息
                for(int i=1;i<=meta.getColumnCount();i++)
                {
                    //当前列名
                    String colName=meta.getColumnName(i);
                    //将列名第一个字母大写(为什么加+""ne ?是大写字母比小写字母多个字节?)
                    colName=colName.replace(colName.charAt(0)+"", new String(colName.charAt(0)+"").toUpperCase());
                    //设置方法名
                    String methodName="set"+colName;
                    System.out.println(methodName);
                    //获取当前位置的值,返回Object类型
                    Object value=rs.getObject(i);
                    //利用反射获取对象(反射概念很模糊?不太懂)
                    Method method=obj.getClass().getMethod(methodName, value.getClass());
                    method.invoke(obj, value);                 //感觉这段类似于obj.setMethodName(value)......对于静态方法的反射可以写成method.invoke(null,value),而不能把第一个参数省略,如果方法没有参数的话,第二个参数可以为空
                }
                lst.add(obj);
            }
            
            return lst;
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
            return null;
        }
        
    }
}
 

使用BeanUtils类简化request和resultset转换 
2009年06月01日 20:02
当提交表单时,如果没有使用Struts等框架的话,你的代码可能是这样

   User user=new User();
   user.setUsername(request.getParameter("username"));
   user.setPassword(request.getParameter("password"));
   user.setEmail(request.getParameter("email"));

如果表单项比较多,每次都要这样写是不是很烦?

OK,使用commons-beanutils吧。你只需要这样写

try {
    Map params=request.getParameterMap();
    BeanUtils.populate(user , params);
   } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   } 
那么处理ResultSet时,如果没有Hibernate等框架,你的代码可能是这样

if (rs.next()) {
    User user = new User();
    user.setId(rs.getLong("id"));
    user.setUsercode(rs.getString("usercode"));
    user.setSex(rs.getString("sex"));
    user.setPassword(rs.getString("password"));
    user.setPhone(rs.getString("phone"));
    user.setEmail(rs.getString("email"));
   users.add(user);
}

是不是也有点烦?OK,这样来写吧

ResultSetDynaClass rsdc = new ResultSetDynaClass(rs);
Iterator rows = rsdc.iterator();
ArrayList lists = new ArrayList();
while (rows.hasNext()) {
     User user = new User();
     DynaBean row = (DynaBean) rows.next();
     BeanUtils.copyProperties(user, row);
     lists.add(user)
}

如何,是否让你的工作更加有效率了呢?

 
分享到:
评论

相关推荐

    【岗位说明】酒店各个岗位职责.doc

    【岗位说明】酒店各个岗位职责

    机械设计注塑件水口冲切码盘设备_step非常好的设计图纸100%好用.zip

    机械设计注塑件水口冲切码盘设备_step非常好的设计图纸100%好用.zip

    【岗位说明】公司各部门组织架构和岗位职责.doc

    【岗位说明】公司各部门组织架构和岗位职责

    使用YOLOv5和LPRNet进行车牌检测+识别(CCPD数据集).zip

    使用YOLOv5和LPRNet进行车牌检测+识别(CCPD数据集)车牌识别项目(CCPD数据集)这个项目是利用YOLOv5和LPRNet对CCPD车牌进行检测和识别。之前一直在学习OCR相关的东西,就想着能不能做一个车牌识别的项目出来,之前也准备好车牌识别。我的打算是做一个轻量级的车牌识别项目,用YOLOv5进行车牌检测,用LPRNet进行车牌识别。目前仅支持识别蓝牌和绿牌(新能源车牌)等中国车牌。后续如果添加数据,可以再继续改装,可支持更多场景和更多类型车牌,提高识别准确率!主要参考以下四个仓库Githubhttps://github.com/ultralytics/yolov5Githubhttps ://github.com/sirius-ai/LPRNet_Pytorchhttps://gitee.com/reason1251326862/plate_classificationhttps://github.com/kiloGrand/License-Plate-Recognition如果对YOLOv5不熟悉源码的同学可以先看看我写的YOLOv5讲解

    基于.net的医院信息管理系统(C#)

    基于.net的医院信息管理系统(C#)。资源来源于网络分享,如有侵权请告知!

    【岗位说明】营销中心高级经理岗位职责.doc

    【岗位说明】营销中心高级经理岗位职责

    环戊二烯行业分析:预计至2031年年复合增长率(CAGR)高达4.8%

    环戊二烯行业分析:2024年全球环戊二烯市场销售额达到了8.83亿美元 环戊二烯,这一独特的化学品,在聚合物、制药、弹性体等多个领域展现出了广泛的应用前景。随着全球经济的持续增长和技术的不断进步,环戊二烯市场需求不断攀升。然而,面对复杂多变的市场环境和日益激烈的竞争,如何准确把握市场脉搏,制定有效的市场策略成为企业面临的关键问题。本文将带您深入了解全球环戊二烯市场的现状、趋势及机遇,为您的成功之路提供有力支持。 市场概况: 根据QYR(恒州博智)的统计及预测,2024年全球环戊二烯市场销售额达到了8.83亿美元,这一数字不仅彰显了市场的庞大规模,更预示着其强劲的增长势头。预计至2031年,市场规模将进一步扩大至12.25亿美元,年复合增长率(CAGR)高达4.8%。亚洲作为最大的市场,占有约45%的份额,展现出强劲的区域增长潜力。 技术创新与趋势: 技术创新是推动环戊二烯市场发展的核心动力。随着环保意识的提高和可持续发展理念的深入人心,市场对环保型环戊二烯产品的需求日益增长。同时,新型催化剂和合成技术的研发,为环戊二烯的生产和应用带来了更多可能性。 应用领域与细分市场: 环戊二烯在树脂

    配电柜光按钮检测图像数据集

    配电柜光按钮检测图像数据集,数据集总共700张左右图片,标注为VOC格式。内容来源于网络分享,如有侵权请联系我删除。另外如果没有积分的同学需要下载,请私信我。

    【岗位说明】销售人员岗位职责说明书.doc

    【岗位说明】销售人员岗位职责说明书

    【岗位说明】市场与销售类岗位说明书.doc

    【岗位说明】市场与销售类岗位说明书

    【岗位说明】销售部各职务详细岗位说明书描述.doc

    【岗位说明】销售部各职务详细岗位说明书描述

    图书管理程序,c语言运行程序

    c语言运行程序

    multisim声控流水灯仿真电路设计 功能: 制作一个声控的LED流水灯电路,20只灯珠依次点亮,当 音量高时流水灯切快,当音调低时流水灯切慢 1.制作拾音整形电路; 2.制作LED驱动电路; 3

    multisim声控流水灯仿真电路设计 功能: 制作一个声控的LED流水灯电路,20只灯珠依次点亮,当 音量高时流水灯切快,当音调低时流水灯切慢。 1.制作拾音整形电路; 2.制作LED驱动电路; 3.制作系统所需的直流电源; 资料包含:仿真源文件+原理说明书(仅参考)+演示视频

    基于Python的南京二手房数据采集及可视化分析.zip

    基于Python的南京二手房数据采集及可视化分析1 内容简介首先通过爬虫采集链家网上所有南京二手房的房源数据,对文献采集到的数据进行清理然后,对清理后的数据进行可视化背后的分析,探索隐藏在大量数据的规律最后,采用一个全新的对所有二手房数据进行算法分析,并根据奥迪分析的结果,将这些房源大致分类,以对所有数据的百年总结。通过上述分析,我们可以了解目前二手房各项基本情况特征及房源分配情况,帮助我们进行购房决策。2 应用技术介绍1)Python网络爬虫技术请求美丽的汤2)Python分析技术NumpyMatplotlib熊猫3)k-means聚类算法4)高德地图开发者应用JS API3 数据采集及数据清洗3.1 数据采集该部分通过网络爬虫程序抓取网上所有南京二手房的数据,收集原始数据,作为整个数据分析的基石。3.1.1链家网网站结构分析链家网二手房主页界面如图1、图2,主页上面红色方塔位置显示了目前南京房在售房源的各区域位置名称,中间红色方塔位置显示了房源的总数量,下面红色方方框显示了二手房源信息,该红色方框区域包含了二手房源页面的UR

    西门子变频器 SINAMICS STARTER V5.6 HF1 软件 STARTER V56 STARTERV56HF1 ISO 001

    西门子变频器 SINAMICS STARTER V5.6 HF1 软件 STARTER V56 STARTERV56HF1 ISO 001

    激光熔覆仿真comsol通过激光进行熔覆工艺进行仿真,对温度与应力进行研究 采用COMSOL中的固体传热等物理场进行耦合仿真 对激光熔覆工艺完成后的温度分布与应力分布以云图形式输出,并研究某一点温度与

    激光熔覆仿真comsol通过激光进行熔覆工艺进行仿真,对温度与应力进行研究 采用COMSOL中的固体传热等物理场进行耦合仿真 对激光熔覆工艺完成后的温度分布与应力分布以云图形式输出,并研究某一点温度与应力随时间变化的曲线关系,温度梯度随时间变化的曲线关系,第三主应力随时间变化的曲线关系。 以及整个激光熔覆工艺过程的动画。

    RoboMaster 智能数据集标注工具.zip

    RoboMaster 智能数据集标注工具RoboMaster 智能数据集标注工具基于[ Qt5+OpenCV(with OpenVINO) ],用于标注RoboMaster装甲板4个顶点的位置,灯条颜色,以及贴纸类型。开发中分支,建议下载release里的软件和源码本人的第一个Qt项目,写的不好的地方见谅项目介绍基于深度学习的自瞄准识别算法逐渐走进RoboMaster的赛场。相比于传统的视觉识别算法,基于深度学习的算法具有更强的鲁棒性和识别性,受到增强队伍的青睐。然而常规深度学习的目标检测算法只能识别出目标的映射,这给后续算法中的单目测距带来了困难。本项目希望能够建立一个方便的4点数据集标注工具,可以快速而准确的完成数据集的制作。主要功能亮点将标准装甲板贴纸图像添加到图片上,包括观察的一些结果。选点时局部放大,然后观察选点位置。智能预识别,弱人力。(需要带 OpenVINO 支持的 OpenCV,可以不用OpenVINO,但速度会变慢)图像的缩放与拖动。使用OpenVINO进行int8加速。(无OpenVINO时无法使用)一键自动标定所有图

    面经mini的一个小项目(简易版)

    面经mini的一个小项目(简易版)

    离散数学笔记-注意学习

    离散数学笔记-注意学习

    Pytorch实现基于LSTM的情感分析的代码和数据集

    Pytorch实现基于LSTM的情感分析的代码和数据集。内容来源于网络分享,如有侵权请联系我删除。另外如果没有积分的同学需要下载,请私信我。

Global site tag (gtag.js) - Google Analytics