我用反射写的数据处理小框架
自己造轮子还是有意思啊
工厂模式
package top.yibobo.util.handler;
import java.sql.ResultSet;
public class TypeHandlerFactory {
/**
* 工厂模式,通过传入的class判断实例化哪个TypeHandler的实现类
* 实现对TypeHandler实现类和调用者之间的解耦
* @param cls 判定对象
* @return TypeHandler
*/
public static TypeHandler creatTypeHandler(Class cls) {
if(cls.isPrimitive() || cls == String.class ||Number.class.isAssignableFrom(cls)) {
return new PrimitiveHandler();//基本数据类型及其包装类以及String类处理器
}else if(cls.getSimpleName().equals("Date")) {
return new DateHandler();//java.sql.Date与java.util.Date处理器,字符串转Date
}else if(ResultSet.class.isAssignableFrom(cls)) {
return new ResultSetHandler();//ResultSet结果集处理器,一行结果封装成相应对象
}
return null;
}
}
根接口
package top.yibobo.util.handler;
/**
* 类型处理器
* 通过指定的class实现类型的转换
* @author pyb
*
*/
public interface TypeHandler {
public Object typeHandler(Class type, Object value);
}
具体实现类之结果集一行转换为对应对象
package top.yibobo.util.handler;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
public class ResultSetHandler implements TypeHandler{
protected ResultSetHandler(){}
/**
* 一个工具
* 将一个对象和ResultSet结果集传入进来
* 可以实现将当前结果集所查询的一行映射到传入的对象中
*
* @param t
* @param rs
* @return 将映射完毕的对象返回
*/
private <T> T getQueryObject(T t,ResultSet rs){
Class<ResultSet> rsclass = ResultSet.class;
Field[] fields = t.getClass().getDeclaredFields();
for(Field f:fields){
//获取set方法名
String fieldName = "set"+f.getName().substring(0,1).toUpperCase()
+f.getName().substring(1);
//获取ResultSet要使用的get方法名
String rsFieldName = "get"+f.getType().getSimpleName().substring(0,1).toUpperCase()
+f.getType().getSimpleName().substring(1);
try {
//给对象赋值的set方法
Method m = t.getClass().getMethod(fieldName, f.getType());
//rs要用的get方法
Method m2 = rsclass.getMethod(rsFieldName, String.class);
Object obj = m2.invoke(rs, f.getName());
m.invoke(t, obj);
} catch (NoSuchMethodException | SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
return t;
}
/**
* 类型处理器的实现类,将传入的value结果集进行处理,以class的类型对象返回
* @param type class类型对象
* @param value 结果集
* @return
*/
@Override
public Object typeHandler(Class type, Object value) {
Object obj = null;
try {
obj = getQueryObject(type.getConstructor(null).newInstance(null), (ResultSet)value);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
return obj;
}
}
具体实现类之基本数据类型及String及包装类的转换
package top.yibobo.util.handler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class PrimitiveHandler implements TypeHandler {
protected PrimitiveHandler() {}
/**
* 此方法实现将指定的value值对应class的基本数据+String类型转换
*/
@Override
public Object typeHandler(Class type, Object value) {
//判断是否赋值兼容,直接兼容的话就没必要往下了
if(type.isInstance(value)) {
return value;
}
//要转的类型是String的话,直接返回value的toString就行了
if(type == String.class) {
return value.toString();
}
//如果要转的类型是布尔值
if(type.getName().equals("boolean")) {
if(value.toString().equals("true")
|| value.toString().equals("false")) {
if(value.toString().equals("true")) {
return true;
}
}
return false;
}
//如果要转的是char就提取value的String值第一个字
if(type.getName().equals("char")) {
String val = value.toString();
return val.toCharArray()[0];
}
//判断value能不能赋值给String,能的话就证明他是一个String,进入String转基本数据类型的操作
if(String.class.isInstance(value)) {
String val = value.toString();
String typeName = type.getName();
switch (typeName) {
case "int":
return NumHandler(Integer.class, val, typeName);
case "double":
return NumHandler(Double.class, val, typeName);
case "long":
return NumHandler(Long.class, val, typeName);
case "float":
return NumHandler(Float.class, val, typeName);
case "short":
return NumHandler(Short.class, val, typeName);
case "byte":
return NumHandler(Byte.class, val, typeName);
default:
break;
}
}
return null;
}
/**
* String类型和六种基本数字类型的转换
* @param cls parse方法调用者的class
* @param num 要转换成对应数字类的String参数
* @param typeName 传入的当前类型的字符串
* @return
*/
private Object NumHandler(Class<? extends Number> cls,String num,String typeName) {
Object obj = null;
try {
String parse = "parse"+typeName.substring(0, 1).toUpperCase()+typeName.substring(1);
Method m = cls.getMethod(parse, String.class);
obj = m.invoke(null, num);
} catch (NoSuchMethodException | SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return obj;
}
}
具体实现类之Deta类的转换
package top.yibobo.util.handler;
import java.text.SimpleDateFormat;
public class DateHandler implements TypeHandler {
protected DateHandler() {}
/**
* 此方法实现将传入的value转换成指定的Date值
*/
@Override
public Object typeHandler(Class type, Object value) {
//判断是否赋值兼容,直接兼容的话就没必要往下了
if(type.isInstance(value)) {
return value;
}
//如果value是个String类型的,就进行到字符串转日期的操作
if(String.class.isInstance(value)) {
String date = value.toString();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
//得到java.util.Date类型和java.sql.Date类型的时间
java.util.Date date1 = null;
try {
date1 = format.parse(date);
} catch (Exception e) {
e.printStackTrace();
}
java.sql.Date date2 = new java.sql.Date(date1.getTime());
if(type.getName().equals("java.sql.Date")) {
return date2;
}
if(type.getName().equals("java.util.Date")) {
return date1;
}
}
return null;
}
}
