java 反射机制构建JDBC查询方法实例代码教程



java 反射机制构建JDBC查询方法实例代码教程。经过前面的一篇文章的学习、学会了利用Class.formName(“”)去获取Class对象、在通过Class对象提供的静态方法、获取类或接口的字段、方法、构造这些成员。

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

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

数据库连接类:

 

  1. /**
  2.  * 数据连接类
  3.  * @author 胡汉三
  4.  *
  5.  */
  6. public class UtilDao {
  7.     static Properties properties = null;
  8.     public UtilDao(){
  9.         //读取属性文件
  10.         properties = new Properties();
  11.         java.io.InputStream in = (java.io.InputStream) this.getClass()
  12.                 .getResourceAsStream(“/mysqlDB.properties”);
  13.         try {
  14.             properties.load(in);
  15.         } catch (IOException ex) {
  16.             System.out.println(ex.getMessage());
  17.             ex.printStackTrace();
  18.         }
  19.     }
  20.     public Connection getConn(){
  21.         Connection connection = null;
  22.         try{
  23.             Class.forName(properties.getProperty(“DBDriver”));
  24.             connection = DriverManager.getConnection(properties.getProperty(“url”),properties.getProperty(“name”),properties.getProperty(“pass”));
  25.         }catch (Exception err) {
  26.             System.out.println(“连接ConDB–>getCon()____JDBC错误!”);
  27.             err.printStackTrace();
  28.             return null;
  29.         }
  30.         return connection;
  31.     }
  32.     /**
  33.      * 以下是关闭重载方法
  34.      * @param rs
  35.      * @param st
  36.      * @param cs
  37.      * @param conn
  38.      * @throws SQLException
  39.      */
  40.     public void closeAll(ResultSet rs,Statement st ,CallableStatement cs ,Connection conn) throws SQLException{
  41.         if(rs!=null){
  42.             rs.close();
  43.         }
  44.         if(st!=null){
  45.             st.close();
  46.         }
  47.         if(cs!=null){
  48.             cs.close();
  49.         }
  50.         if(conn!=null){
  51.             conn.close();
  52.         }
  53.     }
  54.     public void closeAll(ResultSet rs,Statement st,Connection conn) throws SQLException{
  55.         if(rs!=null){
  56.             rs.close();
  57.         }
  58.         if(st!=null){
  59.             st.close();
  60.         }
  61.         if(conn!=null){
  62.             conn.close();
  63.         }
  64.     }
  65.     public void closeAll(ResultSet rs,PreparedStatement ps,Connection conn) throws SQLException{
  66.         if(rs!=null){
  67.             rs.close();
  68.         }
  69.         if(ps!=null){
  70.             ps.close();
  71.         }
  72.         if(conn!=null){
  73.             conn.close();
  74.         }
  75.     }
  76.     public void closeAll(PreparedStatement ps,Connection conn) throws SQLException{
  77.         if(ps!=null){
  78.             ps.close();
  79.         }
  80.         if(conn!=null){
  81.             conn.close();
  82.         }
  83.     }
  84.     public void closeAll(Statement st,Connection conn) throws SQLException{
  85.         if(st!=null){
  86.             st.close();
  87.         }
  88.         if(conn!=null){
  89.             conn.close();
  90.         }
  91.     }
  92.     public void closeAll(Connection conn) throws SQLException{
  93.         if(conn!=null){
  94.             conn.close();
  95.         }
  96.     }
  97. }

属性文件:

 

 

  1. DBDriver=com.mysql.jdbc.Driver
  2. url=jdbc\:mysql\://localhost\:3306/hzw
  3. name=root
  4. pass=root
  5. characterEncoding=utf8

数据层接口:

 

 

  1. /**
  2.  * 访问数据方法接口
  3.  * @author 胡汉三
  4.  * @param <T>
  5.  *
  6.  */
  7. @SuppressWarnings(“unchecked”)
  8. public interface IDao<T> {
  9.     /**
  10.      * 分页查询方法
  11.      * @param objClass 类对象
  12.      * @param sql 查询语句
  13.      * @param params 参数
  14.      * @return 分页数据
  15.      * @throws Exception
  16.      */
  17.     public List<T> findList(Object objClass,String sql, List params)throws Exception;
  18.     /**
  19.      * 查询一条数据
  20.      * @param objClass 类对象
  21.      * @param sql 查询语句
  22.      * @param params 参数
  23.      * @return 一条数据信息
  24.      * @throws Exception
  25.      */
  26.     public T findInfo(Object objClass,String sql ,List params)throws Exception;
  27. }

 

数据层接口实现:

 

  1. /**
  2.  * 访问数据方法实现类
  3.  * @author 胡汉三
  4.  *
  5.  * @param <T>
  6.  */
  7. @SuppressWarnings({“unchecked”,”unused”})
  8. public class DaoImpl<T> implements IDao<T> {
  9.     private UtilDao dao = new UtilDao();
  10.     private Connection conn = null;
  11.     private ResultSet rs = null;
  12.     private PreparedStatement ps = null;
  13.     /*
  14.      * 查询一条数据
  15.      */
  16.     public T findInfo(Object objClass,String sql, List params) throws Exception {
  17.         Class c = objClass.getClass();
  18.         try{
  19.             conn = dao.getConn();
  20.             ps = conn.prepareStatement(sql);
  21.             for (int i = 0; i < params.size(); i++) {
  22.                 if(params.get(i)!=null){
  23.                     Object obj = params.get(i);
  24.                     if(obj.getClass().getName().equals(“java.lang.String”)){
  25.                         ps.setString(i+1, obj.toString());
  26.                     }else if(obj.getClass().getName().equals(“java.lang.Integer”)){
  27.                         ps.setInt(i+1, Integer.valueOf(obj.toString()));
  28.                     }else{
  29.                         ps.setObject(i+1, obj);
  30.                     }
  31.                 }
  32.             }
  33.             rs = ps.executeQuery();
  34.             Class type = null ; //属性类型
  35.             if(rs.next()){
  36.                 objClass = c.newInstance();
  37.                 List<String> list = Reflect003.getKeys(c);
  38.                 Method method = null;
  39.                 for (int i = 0; i < list.size(); i++) {
  40.                     String key = list.get(i);
  41.                     String mName = ”set”+key.substring(0,1).toUpperCase()+key.substring(1);
  42.                     String typeName = c.getDeclaredField(key).getType().getName();
  43.                     if(typeName.equals(“int”)){
  44.                         type = int.class;
  45.                         method = c.getMethod(mName, type);
  46.                         method.invoke(objClass, rs.getInt(key));
  47.                     }else if(typeName.equals(“java.lang.String”)){
  48.                         type = java.lang.String.class;
  49.                         method = c.getMethod(mName, type);
  50.                         method.invoke(objClass, rs.getString(key));
  51.                     }
  52.                 }
  53.             }
  54.         }catch(Exception e){
  55.             System.out.println(“访问数据方法实现类findInfo方法出错”);
  56.             e.printStackTrace();
  57.         }finally{
  58.             dao.closeAll(rs,ps,conn);
  59.         }
  60.         return (T)objClass;
  61.     }
  62.     /*
  63.      * 分页查询方法
  64.      */
  65.     public List<T> findList(Object objClass,String sql, List params)
  66.     throws Exception {
  67.         /*
  68.          * 创建返回值对象
  69.          */
  70.         List<Object> info = new ArrayList<Object>();
  71.         //获得Class对象
  72.         Class c = objClass.getClass();
  73.         try{
  74.             conn = dao.getConn();
  75.             ps = conn.prepareStatement(sql);
  76.             for (int i = 0; i < params.size(); i++) {
  77.                 if(params.get(i)!=null){
  78.                     Object obj = params.get(i);
  79.                     /*
  80.                      * 判断参数的原始类型
  81.                      * 暂时判断Integer跟String类型
  82.                      */
  83.                     if(obj.getClass().getName().equals(“java.lang.String”)){
  84.                         ps.setString(i+1, obj.toString());
  85.                     }else if(obj.getClass().getName().equals(“java.lang.Integer”)){
  86.                         ps.setInt(i+1, Integer.valueOf(obj.toString()));
  87.                     }else{
  88.                         ps.setObject(i+1, obj);
  89.                     }
  90.                 }
  91.             }
  92.             rs = ps.executeQuery();
  93.             Class type = null ; //属性类型
  94.             while(rs.next()){
  95.                 //创建一个实例
  96.                 objClass = c.newInstance();
  97.                 //获取所有的字段名称
  98.                 List<String> list = Reflect003.getKeys(c);
  99.                 Method method = null;//声明Method对象
  100.                 for (int i = 0; i < list.size(); i++) {
  101.                     String key = list.get(i);
  102.                     String mName = getSetMethodName(key); //组装set方法名称
  103.                     String typeName = c.getDeclaredField(key).getType().getName();  //获取字段类型名称
  104.                     /*
  105.                      * 判断字段类型
  106.                      */
  107.                     if(typeName.equals(“int”)){
  108.                         type = int.class; //赋值属性类型
  109.                         method = c.getMethod(mName, type); //获得Method实例
  110.                         method.invoke(objClass, rs.getInt(key));  //调用该set方法
  111.                     }else if(typeName.equals(“java.lang.String”)){
  112.                         type = java.lang.String.class;
  113.                         method = c.getMethod(mName, type);
  114.                         method.invoke(objClass, rs.getString(key));
  115.                     }
  116.                 }
  117.                 info.add(objClass);
  118.             }
  119.         }catch(Exception e){
  120.             System.out.println(“访问数据方法实现类findList方法出错”);
  121.             e.printStackTrace();
  122.         }finally{
  123.             dao.closeAll(rs,ps,conn);
  124.         }
  125.         return (List<T>)info;
  126.     }
  127.     /**
  128.      * 组装set方法
  129.      * @param columnName 字段名
  130.      * @return
  131.      */
  132.     private static String getSetMethodName(String columnName) {
  133.         return ”set” + columnName.substring(0, 1).toUpperCase()
  134.         + columnName.toLowerCase().substring(1);
  135.     }
  136. }


 

获取所有字段的方法:

 

  1. /**
  2.  * 获取字段名称类
  3.  * @author 胡汉三
  4.  *
  5.  */
  6. public class Reflect003 {
  7.     public static List<String> getKeys(Class<?> c){
  8.         List<String> list = new ArrayList<String>();
  9.         try{
  10.             //根据Class的静态方法获取所以字段名称、不包括继承字段
  11.             Field[] fs = c.getDeclaredFields();
  12.             for (int i = 0; i < fs.length; i++) {
  13.                 list.add(fs[i].getName());
  14.             }
  15.         }catch(Exception e){
  16.             e.printStackTrace();
  17.         }
  18.         return list;
  19.     }
  20. }

 

Test:

 

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

 

结果:

 

 

 

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