ResultSet数据自动绑定到JavaBean中

由于需要用jdbc写点程序,不使用Hibernate , mybatis等框架,在设置结果集到bean时相当麻烦,所以写了一个专门完成此功能的类

 

package com.ehl.dc.authorization.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;
/**
 * @说明:利用反射机制从ResultSet自动绑定到JavaBean;根据记录集自动调用javaBean里边的对应方法。
 * 
 * @param <T>
 */
public class SetBean<T> {
	/**
	 * @param clazz
	 *            所要封装的javaBean
	 * @param rs
	 *            记录集
	 * @return ArrayList 数组里边装有 多个javaBean
	 * @throws Exception
	 */
	public List<T> getList(Class<T> clazz, ResultSet rs) {
		Field field = null;
		List<T> lists = new ArrayList<T>();
		try {
			// 取得ResultSet列名
			ResultSetMetaData rsmd = rs.getMetaData();
			// 获取记录集中的列数
			int counts = rsmd.getColumnCount();
			// 定义counts个String 变量
			String[] columnNames = new String[counts];
			// 给每个变量赋值(字段名称全部转换成小写)
			for (int i = 0; i < counts; i++) {
				columnNames[i] = rsmd.getColumnLabel(i + 1).toLowerCase();
			}
			// 变量ResultSet
			while (rs.next()) {
				T t = clazz.newInstance();
				// 反射, 从ResultSet绑定到JavaBean
				for (int i = 0; i < counts; i++) {

					// 设置参数类型,此类型应该跟javaBean 里边的类型一样,而不是取数据库里边的类型
					field = clazz.getDeclaredField(columnNames[i]);

					// 这里是获取bean属性的类型
					Class<?> beanType = field.getType();

					// 根据 rs 列名 ,组装javaBean里边的其中一个set方法,object 就是数据库第一行第一列的数据了
					Object value = rs.getObject(columnNames[i]);

					if (value != null) {

						// 这里是获取数据库字段的类型
						Class<?> dbType = value.getClass();

						// 处理日期类型不匹配问题
						if (dbType == java.sql.Timestamp.class
								&& beanType == java.util.Date.class) {
							// value = new
							// java.util.Date(rs.getTimestamp(columnNames[i]).getTime());
							value = new java.util.Date(
									((java.sql.Timestamp) value).getTime());
						}
						// 处理double类型不匹配问题
						if (dbType == java.math.BigDecimal.class
								&& beanType == double.class) {
							// value = rs.getDouble(columnNames[i]);
							value = new Double(value.toString());
						}
						// 处理int类型不匹配问题
						if (dbType == java.math.BigDecimal.class
								&& beanType == int.class) {
							// value = rs.getInt(columnNames[i]);
							value = new Integer(value.toString());
						}
					}

					String setMethodName = "set"
							+ firstUpperCase(columnNames[i]);
					// 第一个参数是传进去的方法名称,第二个参数是 传进去的类型;
					Method m = t.getClass().getMethod(setMethodName, beanType);

					// 第二个参数是传给set方法数据;如果是get方法可以不写
					m.invoke(t, value);
				}
				lists.add(t);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return lists;
	}

	/**
	 * @param clazz
	 *            bean类
	 * @param rs
	 *            结果集 (只有封装第一条结果)
	 * @return 封装了查询结果的bean对象
	 */
	public T getObj(Class<T> clazz, ResultSet rs) {
		Field field = null;
		T obj = null;
		try {
			// 取得ResultSet列名
			ResultSetMetaData rsmd = rs.getMetaData();
			// 获取记录集中的列数
			int counts = rsmd.getColumnCount();
			// 定义counts个String 变量
			String[] columnNames = new String[counts];
			// 给每个变量赋值(字段名称全部转换成小写)
			for (int i = 0; i < counts; i++) {
				columnNames[i] = rsmd.getColumnLabel(i + 1).toLowerCase();
			}
			// 变量ResultSet
			if (rs.next()) {
				T t = clazz.newInstance();
				// 反射, 从ResultSet绑定到JavaBean
				for (int i = 0; i < counts; i++) {
					try{
					// 设置参数类型,此类型应该跟javaBean 里边的类型一样,而不是取数据库里边的类型
					field = clazz.getDeclaredField(columnNames[i]);
					}catch(Exception ex){
						ex.printStackTrace();
						continue;
					}

					// 这里是获取bean属性的类型
					Class<?> beanType = field.getType();

					// 根据 rs 列名 ,组装javaBean里边的其中一个set方法,object 就是数据库第一行第一列的数据了
					Object value = rs.getObject(columnNames[i]);

					if (value != null) {

						// 这里是获取数据库字段的类型
						Class<?> dbType = value.getClass();

						// 处理日期类型不匹配问题
						if (dbType == java.sql.Timestamp.class
								&& beanType == java.util.Date.class) {
							// value = new
							// java.util.Date(rs.getTimestamp(columnNames[i]).getTime());
							value = new java.util.Date(
									((java.sql.Timestamp) value).getTime());
						}
						// 处理double类型不匹配问题
						if (dbType == java.math.BigDecimal.class
								&& beanType == double.class) {
							// value = rs.getDouble(columnNames[i]);
							value = new Double(value.toString());
						}
						// 处理int类型不匹配问题
						if (dbType == java.math.BigDecimal.class
								&& beanType == int.class) {
							// value = rs.getInt(columnNames[i]);
							value = new Integer(value.toString());
						}
					}

					String setMethodName = "set"
							+ firstUpperCase(columnNames[i]);
					// 第一个参数是传进去的方法名称,第二个参数是 传进去的类型;
					Method m = t.getClass().getMethod(setMethodName, beanType);

					// 第二个参数是传给set方法数据;如果是get方法可以不写
					m.invoke(t, value);
				}
				obj = t;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return obj;
	}

	// 首写字母变大写
	public static String firstUpperCase(String old) {
		return old.substring(0, 1).toUpperCase() + old.substring(1);
	}
}


 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值