码迷,mamicode.com
首页 > 数据库 > 详细

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

时间:2016-05-18 19:59:01      阅读:548      评论:0      收藏:0      [点我收藏+]

标签:

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());
		}
		
	}
}




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

标签:

原文地址:http://blog.csdn.net/qq_32079585/article/details/51397743

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!