欢迎来到Doc100.Net免费学习资源知识分享平台!
您的位置:首页 > 程序异常 >

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

更新时间: 2014-01-05 02:07:53 责任编辑: Author_N1

 

通俗易懂解释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;
  
 }


 

 


 

上一篇:上一篇
下一篇:下一篇

 

随机推荐程序问答结果

 

 

如对文章有任何疑问请提交到问题反馈,或者您对内容不满意,请您反馈给我们DOC100.NET论坛发贴求解。
DOC100.NET资源网,机器学习分类整理更新日期::2014-01-05 02:07:53
如需转载,请注明文章出处和来源网址:http://www.doc100.net/bugs/t/5984/
本文WWW.DOC100.NET DOC100.NET版权所有。