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