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;
}