从数据库读取数据后利用反射为对应的实体类的属性赋值

1、连接数据库并关闭连接(jdbctools.java)

package com.xiaojie.dao;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class Jdbctools {
	private static DataSource ds=null;
    //数据库连接池应只被初始化一次
    static{
        ds=new ComboPooledDataSource("helloc3p0");
    }
    //获取数据库连接
    public static  Connection getConnection() throws ClassNotFoundException, SQLException, IOException{
        return ds.getConnection();
    }
    public static void shifanglianjie(Connection ct, PreparedStatement ps,ResultSet rs) {
    	if(rs!=null){
    		try {
				rs.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	}
    	if(ps!=null){
    		try {
				ps.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	}
    	if(ct!=null){
    		try {
				ct.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	}
    }

}

2、DAO 模块

package com.xiaojie.dao;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.xiaojie.beans.Trade;

import java.sql.SQLException;
public class DAO<T> {
//查询一条记录,返回对应的对象
	public <T> T query(Class<T> clazz,String sql,Object...args){
		T example=null;
		Connection ct=null;
		PreparedStatement ps=null;
		ResultSet rs=null;
		try {
			//1、获取connection
			ct=Jdbctools.getConnection();
			System.out.println("query获取到数据库的连接了");
			//2、获取PreparedStatement
			ps=ct.prepareStatement(sql);
			//3、填充占位符
			for(int i=0;i<args.length;i++){
				ps.setObject(i+1, args[i]);
			}
			//4、进行查询,得到ResultSet
			rs=ps.executeQuery();
			//5、准备一个Map<String,Object>:(前提是结果集中要有记录)
			if(rs.next()){
					Map<String,Object> values=new HashMap<String,Object>();

				//6、得到ResultSetMetaData对象
				ResultSetMetaData rsd=rs.getMetaData();
				//7、处理ResultSet,把指针向下移动一个单位

				//8、由ResultSetMetaData对象得到结果集中有多少列
				int lieshu=rsd.getColumnCount();
				//9、由ResultSetMetaData对象得到每一列的别名,由ResultSet得到具体每一列的值
				for(int i=0;i<lieshu;i++){
					String lieming=rsd.getColumnLabel(i+1);
					Object liezhi=rs.getObject(i+1);
					//10、填充Map对象
					values.put(lieming,liezhi);
				}

				//11、用反射创建Class对应的对象
				example=clazz.newInstance();
				//12、遍历Map对象,用反射填充对象的属性值,
				for(Map.Entry<String, Object> ent:values.entrySet()){
					String name=ent.getKey();
					Object value=ent.getValue();
					//用反射赋值
					ReflectionUtils.setFieldValue(example, name,  value);

				}
			}
		} catch (Exception e) {
				e.printStackTrace();
		}finally{
			Jdbctools.shifanglianjie(ct, ps, rs);
		}
		return example;

	}
	//查询多条记录,返回多个对应的对象
	public List<T>  querylist(Class<T> clazz,String sql,Object...args){
		T example=null;
		Connection ct=null;
		PreparedStatement ps=null;
		ResultSet rs=null;
		List li=new ArrayList();
		try {
			//1、获取connection
			ct=Jdbctools.getConnection();
			System.out.println("querylist获取到数据库的连接了");
			//2、获取PreparedStatement
			ps=ct.prepareStatement(sql);
			//3、填充占位符
			for(int i=0;i<args.length;i++){
				ps.setObject(i+1, args[i]);
			}
			//4、进行查询,得到ResultSet
			rs=ps.executeQuery();
			//5、准备一个Map<String,Object>:(前提是结果集中要有记录)

			while(rs.next()){
					Map<String,Object> values=new HashMap<String,Object>();

				//6、得到ResultSetMetaData对象
				ResultSetMetaData rsd=rs.getMetaData();
				//7、处理ResultSet,把指针向下移动一个单位

				//8、由ResultSetMetaData对象得到结果集中有多少列
				int lieshu=rsd.getColumnCount();
				//9、由ResultSetMetaData对象得到每一列的别名,由ResultSet得到具体每一列的值
				for(int i=0;i<lieshu;i++){
					String lieming=rsd.getColumnLabel(i+1);
					Object liezhi=rs.getObject(i+1);
					//10、填充Map对象
					values.put(lieming,liezhi);
				}

				//11、用反射创建Class对应的对象
				example=clazz.newInstance();
				//12、遍历Map对象,用反射填充对象的属性值,
				for(Map.Entry<String, Object> ent:values.entrySet()){
					String name=ent.getKey();
					Object value=ent.getValue();
					//用反射赋值
					ReflectionUtils.setFieldValue(example, name,  value);

				}
				li.add(example);
			}
		} catch (Exception e) {
				e.printStackTrace();
		}finally{
			Jdbctools.shifanglianjie(ct, ps, rs);
		}
		return li;

	}
}

3、反射工具类

package com.xiaojie.dao;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * 反射的 Utils 函数集合
 * 提供访问私有变量, 获取泛型类型 Class, 提取集合中元素属性等 Utils 函数
 * @author Administrator
 *
 */
public class ReflectionUtils {

	/**
	 * 通过反射, 获得定义 Class 时声明的父类的泛型参数的类型
	 * 如: public EmployeeDao extends BaseDao<Employee, String>
	 * @param clazz
	 * @param index
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Class getSuperClassGenricType(Class clazz, int index){
		Type genType = clazz.getGenericSuperclass();

		if(!(genType instanceof ParameterizedType)){
			return Object.class;
		}

		Type [] params = ((ParameterizedType)genType).getActualTypeArguments();

		if(index >= params.length || index < 0){
			return Object.class;
		}

		if(!(params[index] instanceof Class)){
			return Object.class;
		}

		return (Class) params[index];
	}

	/**
	 * 通过反射, 获得 Class 定义中声明的父类的泛型参数类型
	 * 如: public EmployeeDao extends BaseDao<Employee, String>
	 * @param <T>
	 * @param clazz
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static<T> Class<T> getSuperGenericType(Class clazz){
		return getSuperClassGenricType(clazz, 0);
	}

	/**
	 * 循环向上转型, 获取对象的 DeclaredMethod
	 * @param object
	 * @param methodName
	 * @param parameterTypes
	 * @return
	 */
	public static Method getDeclaredMethod(Object object, String methodName, Class<?>[] parameterTypes){

		for(Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){
			try {
				//superClass.getMethod(methodName, parameterTypes);
				return superClass.getDeclaredMethod(methodName, parameterTypes);
			} catch (NoSuchMethodException e) {
				//Method 不在当前类定义, 继续向上转型
			}
			//..
		}

		return null;
	}

	/**
	 * 使 filed 变为可访问
	 * @param field
	 */
	public static void makeAccessible(Field field){
		if(!Modifier.isPublic(field.getModifiers())){
			field.setAccessible(true);
		}
	}

	/**
	 * 循环向上转型, 获取对象的 DeclaredField
	 * @param object
	 * @param filedName
	 * @return
	 */
	public static Field getDeclaredField(Object object, String filedName){

		for(Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){
			try {
				return superClass.getDeclaredField(filedName);
			} catch (NoSuchFieldException e) {
				//Field 不在当前类定义, 继续向上转型
			}
		}
		return null;
	}

	/**
	 * 直接调用对象方法, 而忽略修饰符(private, protected)
	 * @param object
	 * @param methodName
	 * @param parameterTypes
	 * @param parameters
	 * @return
	 * @throws InvocationTargetException
	 * @throws IllegalArgumentException
	 */
	public static Object invokeMethod(Object object, String methodName, Class<?> [] parameterTypes,
			Object [] parameters) throws InvocationTargetException{

		Method method = getDeclaredMethod(object, methodName, parameterTypes);

		if(method == null){
			throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + object + "]");
		}

		method.setAccessible(true);

		try {
			return method.invoke(object, parameters);
		} catch(IllegalAccessException e) {
			System.out.println("不可能抛出的异常");
		} 

		return null;
	}

	/**
	 * 直接设置对象属性值, 忽略 private/protected 修饰符, 也不经过 setter
	 * @param object
	 * @param fieldName
	 * @param value
	 */
	public static void setFieldValue(Object object, String fieldName, Object value){
		Field field = getDeclaredField(object, fieldName);

		if (field == null)
			throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");

		makeAccessible(field);

		try {
			field.set(object, value);
		} catch (IllegalAccessException e) {
			System.out.println("不可能抛出的异常");
		}
	}

	/**
	 * 直接读取对象的属性值, 忽略 private/protected 修饰符, 也不经过 getter
	 * @param object
	 * @param fieldName
	 * @return
	 */
	public static Object getFieldValue(Object object, String fieldName){
		Field field = getDeclaredField(object, fieldName);

		if (field == null)
			throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");

		makeAccessible(field);

		Object result = null;

		try {
			result = field.get(object);
		} catch (IllegalAccessException e) {
			System.out.println("不可能抛出的异常");
		}

		return result;
	}
}

4、数据库对应的那个Javabeans实体类

package com.xiaojie.beans;

import java.util.Date;

public class Trade {
	private int tradeid;
	private int userid;
	private Date tradetime;
	public int getTradeid() {
		return tradeid;
	}
	public void setTradeid(int tradeid) {
		this.tradeid = tradeid;
	}
	public int getUserid() {
		return userid;
	}
	public void setUserid(int userid) {
		this.userid = userid;
	}
	public Date getTradetime() {
		return tradetime;
	}
	public void setTradetime(Date tradetime) {
		this.tradetime = tradetime;
	}
	public Trade(int tradeid, int userid, Date tradetime) {
		super();
		this.tradeid = tradeid;
		this.userid = userid;
		this.tradetime = tradetime;
	}
	public Trade() {
		super();
	}

}

5、写了一个测试类试一下效果(前提是该导入的jar包都导入了,而且数据库建有相应的Javabeans的表,c3p0配置文件等都弄好了)

package com.xiaojie.test;

import java.io.IOException;
import java.sql.Date;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

import com.xiaojie.beans.Trade;
import com.xiaojie.dao.DAO;

public class Daotest {
	private DAO dao=new DAO();
<span style="white-space:pre">	</span>//以下测试方法是测试从数据库查询一条记录给相应的Javabean的属性赋值,并在控制台显示出一条打印结果
	@Test
	public void testquery() throws ClassNotFoundException, SQLException, IOException{
		String sql="select * from trade where tradeid=?";
		Trade trade=new Trade();
		trade= (Trade) dao.query(Trade.class,sql,1);
		System.out.println("tradeid:"+trade.getTradeid()+"\nuserid:"+trade.getUserid()+"\ntradetiem:"+trade.getTradetime());

	}
	//以下测试方法是从数据库查询后的结果(不只一条记录)给相应的Javabean的属性赋值,并在控制台显示出多条打印结果
	@Test
	public void testquerylist(){
		String sql="select * from trade";
		Trade trade=new Trade();

		List<Trade>trades=new ArrayList<Trade>();
		trades=(List<Trade>) dao.querylist(Trade.class,sql);
		for(Trade trade1:trades){

			System.out.println("tradeid:"+trade1.getTradeid()+"\nuserid:"+trade1.getUserid()+"\ntradetiem:"+trade1.getTradetime());
		}

	}
}


				
时间: 2025-01-19 21:38:12

从数据库读取数据后利用反射为对应的实体类的属性赋值的相关文章

从数据库读取数据后显示成html标签

也许很多人从数据库中读的数据是不需要数据成html标签的,但是也许有一天你们会发现当我们需要输出成html标签时编译器却自动帮我们输出成字符串了这是我们可以这样来 方法1: 最常用的方法,使用JS或JQ JQ: 1 $("#div").html("<span>我是HTML代码</span>"); JS: 1 var dobj=document.getElementById("div"); 2 dobj.innerHTML

从数据库读取数据后将其输出成html标签

最常用的方法,使用JS或JQ JQ: $("#div").html("<span>我是HTML代码</span>"); JS: var dobj=document.getElementById("div"); dobj.innerHTML = "<span>我是HTML代码</span>";

echarts通过ajax向服务器发送post请求,servlet从数据库读取数据并返回前端

1.echarts的官网上的demo,都是直接写死的随机数据,没有和数据库的交互,所以就自己写了一下,ok,我们开始一步一步走一遍整个流程吧. 就以官网最简单的那个小demo来做修改吧.官网上的小demo的效果图如下:(很熟悉,有没有) 2.按照echarts的使用方法新建一个echarts.html文件.为ECharts准备一个具备大小(宽高)的Dom(讲的有点细,熟悉的朋友直接跳过) <!DOCTYPE html> <head> <meta charset="u

10天学会phpWeChat——第三天:从数据库读取数据到视图

在第二天,我们创建了我们的第一个phpWeChat功能模块,但是比较简单.实际生产环境中,我们不可能有如此简单的需求.更多的情况是数据存储在MySql数据库中,我们开发功能模块的作用就是将这些数据从MySql读取并通过视图多样化的呈现给用户. 今天我们进入<10天学会phpWeChat>系列教程的第三天:从数据库读取数据到视图. 一.首先,我们创建一个MySql数据文章表(pw_wechat_hello_article)用来存储要显示给用户的数据. 为了简单明了,这个表我们只保留3个字段: I

jquery.datatable插件从数据库读取数据

一.分页 分页的基本思想是根据datatable的页码及每页显示的行数,将数据从数据库分段提出,然后再填充到表格中,以达到分页的效果. 这里需要用到datatable插件的几个属性: "sEcho":这个属性需要原封不动地传回给datatable,具体的作用我也不清楚,但是根据它值的变化情况来看,好像是一个操作次数的计数(之前我一直把它当做是pageindex来用,结果发现,不论我在datatable中是翻下一页还是翻上一页,它一直在增加.) "iDisplayStart&q

C#实现从数据库读取数据到Excel

用第三方组件:NPOI来实现 先去官网:http://npoi.codeplex.com/下载需要引入dll(可以选择.net2.0或者.net4.0的dll),然后在网站中添加引用.使用 NPOI 你就可以在没有安装 Office 或者相应环境的机器上对 WORD/EXCEL 文档进行读写. 创建一个实体类: [Table("Customer") ] public class Customer { [Key] public int Id { get; set; } public st

C++ 从数据库读取数据,将数据显示在界面上的TreeCtrl上

oracle数据库读取数据如下所示: 代码如下: //构造节点 struct AREA { long id; long parent_area_id; string area_name; std::vector<AREA> children; } //从AREA表中根据id读一个结构体Area的数据 void Id2FindAreaTree(Session ses, AREA& Area, int id) { Statement select(ses); select <<

利用反射机制动态的调用类信息

public class reflectTest { /** * 利用反射设置实体类的属性 * * @return * @throws ClassNotFoundException * @throws IllegalAccessException * @throws InstantiationException * @throws NoSuchFieldException * @throws SecurityException * @throws NoSuchMethodException *

java 中利用反射机制获取和设置实体类的属性值

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. JAVA反射(放射)机制:"程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言".从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言.但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可