当前位置: 代码迷 >> SQL >> 老妪能解解释java反射机制(二) (模拟 ibatis 的 selectBySql 查询)
  详细解决方案

老妪能解解释java反射机制(二) (模拟 ibatis 的 selectBySql 查询)

热度:624   发布时间:2016-05-05 12:03:45.0
通俗易懂解释java反射机制(二) (模拟 ibatis 的 selectBySql 查询)

JAVA有着一个非常突出的动态相关机制:Reflection,
用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。

换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),
并生成其对象实体、或对其fields设值、或唤起其methods。

JAVA反射机制是在运行状态中,对于任意一个类,
都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

我自己的理解反射其中一个应用:提供这样一个方法: 把类名 当作形参 传入 经过一系列处理后(获得属性 获取方法 等等) 可以返回给你这个类的对象。
关键在与这个类 是你随便写的 是在运行时候动态new出来的
而不是在编译前 程序员自己写的。
作用是  更加灵活 可以复用。

 

一下是jdbc 的查询方法:(虽然是jdbc 但是也是可以多次复用的公共查询方法)


 

/**  * query data  *   * @param sql  *            query data's sql  * @return return a list  */ @SuppressWarnings("unchecked") public List<Map> selectQuery(String sql) {  openConnection();  List<Map> result = new ArrayList<Map>();  try {   stmt = conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_SENSITIVE,     ResultSet.CONCUR_UPDATABLE);   //System.out.println(sql);      rs = stmt.executeQuery();   ResultSetMetaData rsm = rs.getMetaData();   int cols = rsm.getColumnCount();   while (rs.next()) {    Map<String, String> map = new HashMap<String, String>();    for (int i = 1; i <= cols; i++) {     String colName = rsm.getColumnLabel(i);     String colValue = rs.getString(i);     //System.out.println("colName:\t"+colName+";colValue:\t"+colValue);     map.put(colName, colValue);    }    result.add(map);   }  } catch (SQLException e) {   System.out.println(e.toString());  }finally{   closeConnection();  }  return result; }


 
返回查询到对象的集合 map 的key是字段名 ,value 是字段的值。

接下来用beanFactory 生产出来你想要的任何 bean 的list集合

package com.woyi.util.factory;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;public class BeanFactory { /**  * @param beanName 对应javaBean包加类名  * @param map  * @return  */ @SuppressWarnings("unchecked")//beanName是所要封装的目的对象的名字,maplist是从数据库查出来的list public static List ListToBean(String beanName,List<Map> mapList){  List list = new ArrayList();  for (Map<String, String> map : mapList) {//对maplist进行遍历,map里面的key 是数据库表的字段或者其别名,   //value就是其对应的值了   try{       Class c = Class.forName(beanName);   //加载获得bean的Class对象    Constructor con = c.getConstructor(new Class[]{}); //获得bean的构造器    Object myclass = con.newInstance(new Object[]{});  //用构造器new一个bean的对象    Field[] fields = myclass.getClass().getDeclaredFields();//bean的属性数组    Set  set = map.keySet();//获取map里面所有的key值 放到set里面    Iterator<String> iter = set.iterator();//获取set的迭代器    while (iter.hasNext()) {//遍历     String key = iter.next();     for (Field field : fields) {      String fieldName = field.getName();      if(key.toLowerCase().equals(field.getName().toLowerCase())){//比较数据库字段名和bean的属性名是否一致//       不区分大小写 若一致 则调用bean的set方法 将字段值set进bean的属性值       String methodName = "set"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);       //判断bean 属性的类型       if (field.getType().getSimpleName().equals("Integer")) {        Method method = c.getDeclaredMethod(methodName,Integer.class);//获取set方法        int value = 0;        try {         value = Integer.parseInt(map.get(key));        } catch (Exception e) {         value = 0;        }        method.invoke(myclass,value);//调用set方法       }else if(field.getType().getSimpleName().equals("int") ){        Method method = c.getDeclaredMethod(methodName,int.class);        int value = 0;        try {         value = Integer.parseInt(map.get(key));        } catch (Exception e) {         value = 0;        }        method.invoke(myclass,value);       }else if(field.getType().getSimpleName().equals("String")){        Method method = c.getDeclaredMethod(methodName,String.class);        method.invoke(myclass, map.get(key));       }else if(field.getType().getSimpleName().equals("double")){        Method method = c.getDeclaredMethod(methodName,double.class);                double value = 0.0;        try {         value = Double.parseDouble(map.get(key));        } catch (Exception e) {         value = 0.0;        }        method.invoke(myclass, value);       }else if(field.getType().getSimpleName().equals("Double")){        Method method = c.getDeclaredMethod(methodName,Double.class);        double value = 0.0;        try {         value = Double.parseDouble(map.get(key));        } catch (Exception e) {         value = 0.0;        }                method.invoke(myclass, value);       }else{        System.out.println("目前只支持int ,double与 String 类型数据属性");        continue;       }       //以后扩展其他属性类型的解析      }     }    }    list.add(myclass);   }catch(Exception e){       e.printStackTrace();      }     }  return list; }}



最后 强转成 你想要的List<beanName> 接收 就可以了

for example:

public List<HelpInfoConfig> queryHelp1(){  String sql = "select * from help  order by id ";  DBBase dBBase = new DBBase();//DBBase 是操作数据库的工具类 里面有获取connection select等等方法  List<Map> list= dBBase.selectQuery(sql);  List<HelpInfoConfig> help = BeanFactory.ListToBean("com.woyi.bean.HelpInfoConfig", list);  return help;   }


 

 


 

  相关解决方案