java 反射机制构建JDBC查询方法

经过前面的一篇文章的学习、学会了利用Class.formName("")去获取Class对象、在通过Class对象提供的静态方法、获取类或接口的字段、方法、构造这些成员。

了解了反射的一些基础、个人觉得学习编程应该充分的动起手来。在使用过Hibernate的查询过后、突然觉得普通的JDBC查询对查询结果的封装很是麻烦!

于是仿造它、构建一个简单的JDBC查询。

数据库连接类:

/**
 * 数据连接类
 * @author 胡汉三
 *
 */
public class UtilDao {
    static Properties properties = null;
    public UtilDao(){
    	//读取属性文件
		properties = new Properties();
		java.io.InputStream in = (java.io.InputStream) this.getClass()
				.getResourceAsStream("/mysqlDB.properties");
		try {
			properties.load(in);
		} catch (IOException ex) {  
			System.out.println(ex.getMessage());
			ex.printStackTrace();
		}
    }
    public Connection getConn(){
    	Connection connection = null;
    	try{
    		Class.forName(properties.getProperty("DBDriver"));
    		connection = DriverManager.getConnection(properties.getProperty("url"),properties.getProperty("name"),properties.getProperty("pass"));
    	}catch (Exception err) {
        	System.out.println("连接ConDB-->getCon()____JDBC错误!");
            err.printStackTrace();  
            return null;   
        }
        return connection;
    }
    /**
     * 以下是关闭重载方法
     * @param rs
     * @param st
     * @param cs
     * @param conn
     * @throws SQLException
     */
    public void closeAll(ResultSet rs,Statement st ,CallableStatement cs ,Connection conn) throws SQLException{
    	if(rs!=null){
			rs.close();
		}
		if(st!=null){
			st.close();
		}
		if(cs!=null){
			cs.close();
		}
		if(conn!=null){  
			conn.close();
		}
    }
    public void closeAll(ResultSet rs,Statement st,Connection conn) throws SQLException{
    	if(rs!=null){
			rs.close();
		}
		if(st!=null){
			st.close();
		}
		if(conn!=null){  
			conn.close();
		}
    }
    public void closeAll(ResultSet rs,PreparedStatement ps,Connection conn) throws SQLException{
    	if(rs!=null){
			rs.close();
		}
    	if(ps!=null){
			ps.close();
		}
		if(conn!=null){  
			conn.close();
		}  
    }
    public void closeAll(PreparedStatement ps,Connection conn) throws SQLException{
    	if(ps!=null){
			ps.close();
		}
		if(conn!=null){  
			conn.close();
		}  
    }
    public void closeAll(Statement st,Connection conn) throws SQLException{
    	if(st!=null){
			st.close();
		}
		if(conn!=null){  
			conn.close();
		}  
    }
    public void closeAll(Connection conn) throws SQLException{
		if(conn!=null){  
			conn.close();
		}  
    }
}
属性文件:

DBDriver=com.mysql.jdbc.Driver
url=jdbc\:mysql\://localhost\:3306/hzw
name=root
pass=root
characterEncoding=utf8
数据层接口:

/**
 * 访问数据方法接口
 * @author 胡汉三
 * @param <T>
 *
 */
@SuppressWarnings("unchecked")
public interface IDao<T> {
	/**
	 * 分页查询方法
	 * @param objClass 类对象
	 * @param sql 查询语句
	 * @param params 参数
	 * @return 分页数据
	 * @throws Exception
	 */
	public List<T> findList(Object objClass,String sql, List params)throws Exception;
	
	/**
	 * 查询一条数据
	 * @param objClass 类对象
	 * @param sql 查询语句
	 * @param params 参数
	 * @return 一条数据信息
	 * @throws Exception
	 */
	public T findInfo(Object objClass,String sql ,List params)throws Exception;
	
}

数据层接口实现:

/**
 * 访问数据方法实现类
 * @author 胡汉三
 *
 * @param <T>
 */
@SuppressWarnings({"unchecked","unused"})
public class DaoImpl<T> implements IDao<T> {

	private UtilDao dao = new UtilDao();
	private Connection conn = null;
	private ResultSet rs = null;
	private PreparedStatement ps = null;

	/*
	 * 查询一条数据
	 */
	public T findInfo(Object objClass,String sql, List params) throws Exception {
		Class c = objClass.getClass(); 
		try{
			conn = dao.getConn();
			ps = conn.prepareStatement(sql);
			for (int i = 0; i < params.size(); i++) {
				if(params.get(i)!=null){
					Object obj = params.get(i);
					if(obj.getClass().getName().equals("java.lang.String")){
						ps.setString(i+1, obj.toString());
					}else if(obj.getClass().getName().equals("java.lang.Integer")){
						ps.setInt(i+1, Integer.valueOf(obj.toString()));
					}else{
						ps.setObject(i+1, obj);    
					}
				}
			}
			rs = ps.executeQuery();
			Class type = null ; //属性类型
			if(rs.next()){
				objClass = c.newInstance();
				List<String> list = Reflect003.getKeys(c);
				Method method = null;
				for (int i = 0; i < list.size(); i++) {
					String key = list.get(i);
					String mName = "set"+key.substring(0,1).toUpperCase()+key.substring(1);
					String typeName = c.getDeclaredField(key).getType().getName();
					if(typeName.equals("int")){
						type = int.class;
						method = c.getMethod(mName, type);
						method.invoke(objClass, rs.getInt(key));  
					}else if(typeName.equals("java.lang.String")){
						type = java.lang.String.class;   
						method = c.getMethod(mName, type);
						method.invoke(objClass, rs.getString(key));    
					}
				}
			}
		}catch(Exception e){
			System.out.println("访问数据方法实现类findInfo方法出错");
			e.printStackTrace(); 
		}finally{   
			dao.closeAll(rs,ps,conn);
		}  
		return (T)objClass; 
	} 

	/*
	 * 分页查询方法
	 */
	public List<T> findList(Object objClass,String sql, List params)
	throws Exception {
		/*
		 * 创建返回值对象
		 */
		List<Object> info = new ArrayList<Object>();  
		//获得Class对象
		Class c = objClass.getClass(); 
		try{
			conn = dao.getConn();
			ps = conn.prepareStatement(sql);
			for (int i = 0; i < params.size(); i++) {
				if(params.get(i)!=null){
					Object obj = params.get(i);
					/*
					 * 判断参数的原始类型
					 * 暂时判断Integer跟String类型
					 */
					if(obj.getClass().getName().equals("java.lang.String")){
						ps.setString(i+1, obj.toString());
					}else if(obj.getClass().getName().equals("java.lang.Integer")){
						ps.setInt(i+1, Integer.valueOf(obj.toString()));
					}else{
						ps.setObject(i+1, obj);    
					}
				}
			}
			rs = ps.executeQuery();
			Class type = null ; //属性类型
			while(rs.next()){
				//创建一个实例
				objClass = c.newInstance();
				
				//获取所有的字段名称
				List<String> list = Reflect003.getKeys(c);
				
				Method method = null;//声明Method对象
				
				for (int i = 0; i < list.size(); i++) {
					String key = list.get(i);
					String mName = getSetMethodName(key); //组装set方法名称
					String typeName = c.getDeclaredField(key).getType().getName();  //获取字段类型名称
					/*
					 * 判断字段类型
					 */
					if(typeName.equals("int")){
						type = int.class; //赋值属性类型
						method = c.getMethod(mName, type); //获得Method实例
						method.invoke(objClass, rs.getInt(key));  //调用该set方法
					}else if(typeName.equals("java.lang.String")){
						type = java.lang.String.class;   
						method = c.getMethod(mName, type);
						method.invoke(objClass, rs.getString(key));    
					}
				}
				info.add(objClass);
			}  
		}catch(Exception e){
			System.out.println("访问数据方法实现类findList方法出错");
			e.printStackTrace();
		}finally{
			dao.closeAll(rs,ps,conn);  
		}
		return (List<T>)info;  
	}
	/**
	 * 组装set方法
	 * @param columnName 字段名
	 * @return
	 */
	private static String getSetMethodName(String columnName) {
		return "set" + columnName.substring(0, 1).toUpperCase()
		+ columnName.toLowerCase().substring(1);
	}
}

获取所有字段的方法:

/**
 * 获取字段名称类
 * @author 胡汉三
 *
 */
public class Reflect003 {
	public static List<String> getKeys(Class<?> c){
		List<String> list = new ArrayList<String>();
		try{
			//根据Class的静态方法获取所以字段名称、不包括继承字段
			Field[] fs = c.getDeclaredFields();
			for (int i = 0; i < fs.length; i++) {
				list.add(fs[i].getName());
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		return list;
	}
}

Test:

public static void main(String[] args) throws Exception {
		DaoImpl dao = new DaoImpl();
		test_user u = new test_user();
		String sqlPage = "SELECT * FROM test_user WHERE id <= ";
		sqlPage += " (SELECT id FROM test_user ORDER BY id LIMIT "+(2-1)*20+", 1) ";
		sqlPage += " ORDER BY id LIMIT 20 " ;  //
		
		List<test_user> listT = (List<test_user>)dao.findList(u, sqlPage, new ArrayList());
		for (int i = 0; i < listT.size(); i++) {
			test_user user = listT.get(i);
			System.out.println("名称:"+user.getName());
		}
	}

结果:




下一篇继续学习反射的实际应用、利用反射构建JSON格式数据!

欢迎QQ群交流:138986722






posted @ 2013-03-05 17:11  java程序员填空  阅读(315)  评论(0编辑  收藏  举报