我用反射写的数据处理小框架
自己造轮子还是有意思啊
工厂模式
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; } }