反射模拟DbUtils实现ResultSet转成Bean实例
前几天接触到了apache的一个小框架DbUtils,真的被其优雅的设计所震撼到了,尤其是其中的
MyBean mybean = QueryRunner.query(sqlConnection,sqlStatement,new BeanHandler<MyBean.class>(),params);
当时真的是感觉到很是神奇,仅仅是指定了一下那个Bean类的全名,就能从数据库结果集中自动的生成我们需要的Bean对象,真的是太优雅了。然后我就翻了翻源码,然后尴尬的发现自己能力有限,并不能真正做出那样强大而且优雅的东西。
![]()
反射技术
虽然写不了那样强大的框架,但是模拟一下还是可行的嘛,我在源码中看到了反射技术的影子,然后就恶补了一下相关的知识点。细节方面主要是使用到了PropertyDescriptor这个类,以及相关的getReadMethod和getWriteMethod。说白了就是实现setter和getter方法。
下面是一个简单的入门级的小例子
// 这个小例子就包含了getter方法和setter的使用了
public static <T> void test1(String proName, Class<T> beanCLass) throws Exception {
PropertyDescriptor pd = new PropertyDescriptor(proName, beanCLass);
String type = pd.getPropertyType().toString();
Method setMethod = pd.getWriteMethod();
// Person p = new Person();
T p = (T) beanCLass.newInstance();
// 这里也仅仅是做个示例,只允许String类型的Property来赋值,否则会报错的
setMethod.invoke(p, "郭璞");
System.out.println(pd.getReadMethod().invoke(p, null));
}
获取所有的Properties
经过了上面的小例子,那我们就具备了给单个的Property赋值的实现了,至于怎么给一个Bean的所有的Property赋值,请接着往下看。
beanClass.getDeclaredFields().有了这行代码,我们就可以接着下一步了。
// 使用下面的这个方法,我们就可以轻松的获取一个Bean的所有的
Properties了
public static <T> Field[] getFields(Class<T> clazz) throws Exception {
String qualifyName = new String(clazz.toString().substring(6, clazz.toString().length()));
qualifyName.concat(".class");
System.out.println("Qualify Name:" + qualifyName);
Class cls = Class.forName(qualifyName);
Field[] fields = cls.getDeclaredFields();
return fields;
}
我的小框架
为了接下来的测试成功,我们先new出来几个Bean吧。分别如下:
/**
* @Date 2016年7月18日
*
* @author Administrator
*/
package com.grb.one;
/**
* @author 郭璞
*
*/
public class Person {
private String name;
private int age;
public Person() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Person(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
/**
* @Date 2016年7月18日
*
* @author Administrator
*/
package com.grb.one;
/**
* @author 郭璞
*
*/
public class Dog {
public String volun;
private String name;
public String getVolun() {
return volun;
}
public void setVolun(String volun) {
this.volun = volun;
}
public Dog() {
}
@Override
public String toString() {
return "Dog [volun=" + volun + ", name=" + name + "]";
}
/**
* @param name
* the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the name
*/
public String getName() {
return name;
}
public void run(Integer mails) {
System.out.println("This dog runned:" + mails + " mails.!");
}
}
接下来就是重头戏了。
/**
* @Date 2016年7月18日
*
* @author Administrator
*/
package neixing;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import com.grb.one.Dog;
import com.grb.one.Person;
/**
* @author 郭璞
*
*/
public class Demo {
public static void main(String[] args) throws Exception {
test1("name", com.grb.one.Person.class);
System.out.println("----------------------------------------");
test2();
System.out.println("----------------------------------------");
test3();
}
public static void test2() throws Exception {
Map<String, Object> resultset = new HashMap<String, Object>();
resultset.put("name", "person-name-property");
resultset.put("age", 20);
Person p = (Person) createBean(resultset, com.grb.one.Person.class);
System.out.println(p.toString());
}
public static void test3() throws Exception {
Map<String, Object> resultset = new HashMap<String, Object>();
resultset.put("volun", "dog-volun-property");
resultset.put("name", "dog-name-property");
Dog dog = (Dog) createBean(resultset, com.grb.one.Dog.class);
System.out.println(dog.toString());
}
public static <T> Field[] getFields(Class<T> clazz) throws Exception {
String qualifyName = new String(clazz.toString().substring(6, clazz.toString().length()));
qualifyName.concat(".class");
System.out.println("Qualify Name:" + qualifyName);
Class cls = Class.forName(qualifyName);
Field[] fields = cls.getDeclaredFields();
return fields;
}
public static <T> T createBean(Map<String, Object> resultset, Class<T> bean) throws Exception {
T mybean = bean.newInstance();
Field[] fields = getFields(bean);
for (Field field : fields) {
PropertyDescriptor pd = new PropertyDescriptor(field.getName(), bean);
Method setter = pd.getWriteMethod();
setter.invoke(mybean, resultset.get(field.getName()));
}
return mybean;
}
}
测试结果
下面就来一起看看振奋人心的结果吧。
郭璞
----------------------------------------
Qualify Name:com.grb.one.Person
Person [name=person-name-property, age=20]
----------------------------------------
Qualify Name:com.grb.one.Dog
Dog [volun=dog-volun-property, name=dog-name-property]
总结
反射技术对于泛型的使用可谓是登峰造极了。这样做的好处不言而喻。
今天代码中的闪光点在于:
String.subString();// 分割字符串,实现bean的全名转化成可反射的字符串类型Map<String,Object>的使用,好处在于模拟了ResultSet,提供了素材Class<T> bean的使用,神奇的一种方式啊。泛型的优点可不仅仅在这里能看到啊。:-)
好了,今天的分享就先到这里吧。希望这个思路能给看到这篇文章的童鞋一丝启发,开发出专属于自己的一套小工具。
反射模拟DbUtils实现ResultSet转成Bean实例的更多相关文章
- 采用dom4j和反射模拟Spring框架的依赖注入功能
Spring的依赖注入是指将对象的创建权交给Spring框架,将对象所依赖的属性注入进来的行为.在学习了dom4j后,其实也可以利用dom4j和反射做一个小Demo模拟Spring框架的这种功能.下面 ...
- 利用反射将Datatable、SqlDataReader转换成List模型
1. DataTable转IList public class DataTableToList<T>whereT :new() { ///<summary> ///利用反射将D ...
- SpringMVC中出现" 400 Bad Request "错误(用@ResponseBody处理ajax传过来的json数据转成bean)的解决方法
最近angularjs post到后台 400一头雾水 没有任何错误. 最后发现好文,感谢作者 SpringMVC中出现" 400 Bad Request "错误(用@Respon ...
- 3.Spring-用反射模拟IoC
1.BeanFactory.java package com.jike.spring.chapter03.reflect; import java.io.InputStream; import jav ...
- 简单的map转换成Bean的工具
简单的map转换成Bean的工具 package com.sd.microMsg.util; import java.lang.reflect.Field; import java.lang.refl ...
- 模拟DbUtils实现接口回调机制
想必大家都用过apache 的DbUtils吧,这个简单的对JDBC的封装小框架真的是非常非常的适合新手的学习呢.逻辑上也不是很复杂,难度刚刚好. 下面我就模仿它来实现一个字符串的处理小框架. 思路 ...
- 利用泛型和反射,管理配置文件,把Model转换成数据行,并把数据行转换成Model
利用泛型和反射,管理配置文件,把Model转换成数据行,并把数据行转换成Model 使用场景:网站配置项目,为了便于管理,网站有几个Model类来管理配置文件, 比如ConfigWebsiteMo ...
- 使用反射创建Bean、Spring中是如何根据类名配置创建Bean实例、Java提供了Class类获取类别的字段和方法,包括构造方法
Java提供了Class类,可以通过编程方式获取类别的字段和方法,包括构造方法 获取Class类实例的方法: 类名.class 实例名.getClass() Class.forNam ...
- 在Spring Bean实例过程中,如何使用反射和递归处理的Bean属性填充?
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! <Spring 手撸专栏>目录 [x] 第 1 章:开篇介绍,我要带你撸 Spri ...
随机推荐
- 从零开始搭建口袋妖怪管理系统(1)-从Angular1.x开始
开坑,一直喜欢口袋妖怪,想着能写点有关的程序. 最近项目要改写管理系统,所以用Angular1.x搭建一个口袋妖怪管理系统试试. 巩固Ng1.x的知识+学习库的用法,然后算是记录一个系统从零开始到成型 ...
- codevs 1069 关押罪犯
提交地址:http://codevs.cn/problem/1069/ 1069 关押罪犯 2010年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻 ...
- ●CodeForces 429D Trick_Function
题链: http://codeforces.com/problemset/problem/429/D题解: 分治,最近点对 不难发现g(i,j)=sum[j]-sum[i], 那么f(i,j)=(i- ...
- ●2301 [HAOI2011] Problem b
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2301 题解: 莫比乌斯反演,入门题. 类似●HDU 1695 GCD 只是多了一个下界,(另 ...
- 【网络流】【BZOJ1006】【SCOI2007】蜥蜴
学弟@lher在周末训练赛中出的题目的原题(这个人拿省选题来当作提高组模拟,太丧了...) 题意简析:看题目:) 解题思路:题目显然是最大流. 首先拆点将点权变为边权,然后按照题意对于所有有跳板的点向 ...
- 【NOIP2011TG】solution
老师最近叫我把NOIPTG的题目给刷掉,于是就开始刷吧= = 链接:https://www.luogu.org/problem/lists?name=&orderitem=pid&ta ...
- APIO 2013
这套好丧--跟别的画风好不一样(中国风?).提答没做也没测,假装只有两题吧.140/200 T1.ROBOTS 题目大意:h*w的网格上有n个机器人编号1~n,网格上有空地.墙.顺/逆时针转向器,每次 ...
- C语言程序第三次作业
(一)改错题 计算f(x)的值:输入实数x,计算并输出下列分段函数f(x)的值,输出时保留1位小数. 输入输出样例1: Enterr x: 10.0 f(10.0) = 0.1 输入输出样例2: En ...
- Java的数组排序
对数组进行排序 使用到的排序算法有: 1 选择排序 2 冒泡排序 3 插入排序 4 JavaAPI提高排序算法 选择排序的原理: 1 将数组中每个元素与第一个元素比较,如果这个元素小于第 ...
- Safari 3D transform变换z-index层级渲染异常
(猛戳来源:http://www.zhangxinxu.com/wordpress/?p=5569)