用反射写出与apache的增删改查框架差不多的框架,优化了上次写的代码
package top.yibobo.util; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.ResultSet; public class ResultSetHandler { private ResultSetHandler(){} /** * 一个工具 * 将一个对象和ResultSet结果集传入进来 * 可以实现将当前结果集所查询的一行映射到传入的对象中 * * @param t * @param rs * @return 将映射完毕的对象返回 */ public static <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); System.out.println(rsFieldName); 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; } }
这回增删改都有啦,除了上次写的那个返回一个集合的以外,还加了个查询单条数据只返回一个对象的重载方法
增删改倒是挺简单的
package top.yibobo.util; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.math.BigDecimal; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; public class QueryUtil { private static QueryUtil INSTANCE = null; private QueryUtil(){} public static QueryUtil getInstance(){ if(INSTANCE == null){ synchronized (QueryUtil.class) { if(INSTANCE == null){ INSTANCE = new QueryUtil(); } } } return INSTANCE; } /** * 此方法使用反射将type中的成员变量与方法进行动态获取 * 并且通过反射将成员变量的类型动态提取出来从而实现ResultSet中getXXX的动态获取 * 方法运行结果为将所查询数据表中的每一行保存为对象,并在查询完毕后将包含所有对象的集合返回 * @author pyb * @param connection * @param sql * @param type * @return sql语句查询出来的对象结果集合 */ public <T> List<T> query(Connection connection,String sql,Class<T> type){ List<T> list = new ArrayList<T>(); Field[] field = type.getDeclaredFields();//获得class中所有的成员属性 try { PreparedStatement ps = connection.prepareStatement(sql); ResultSet rs = ps.executeQuery(); while(rs.next()){//遍历结果集 //通过传入的class获取此class所代表的类的实例 Constructor c = type.getConstructor(null); //c.newInstance等同于new出来的实例 T t = (T) ResultSetHandler.getQueryObject(c.newInstance(null), rs); list.add(t); } } catch (NoSuchMethodException e1) { e1.printStackTrace(); } catch (SecurityException e1) { e1.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } return list; } /** * 此方法实现将sql语句查询的一行数据保存为相应的对象并返回 * @param connection * @param sql * @param type * @param objs * @return 与数据表中的一行数据映射的对象 */ public <T> T query(Connection connection,String sql,Class<T> type,Object[] objs){ Field[] fields = type.getDeclaredFields(); T t = null; PreparedStatement pr; try { //创建完整的PrepareStatement,给?赋值 pr = connection.prepareStatement(sql); for(int i = 0;i<objs.length;i++){ pr.setObject(i+1, objs[i]); } ResultSet rs = pr.executeQuery(); if(rs.next()){//调用ResultSetHandler方法获得一个对象 Constructor<T> c = type.getConstructor(null); t = ResultSetHandler.getQueryObject(c.newInstance(null), rs); } } catch (SQLException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return t; } /** * 此方法实现增删改的功能 * @param connection * @param sql * @param objs * @return */ public int update(Connection connection,String sql,Object[] objs){ int row = 0; try { PreparedStatement ps = connection.prepareStatement(sql); for(int i = 0 ; i < objs.length ; i++){ ps.setObject(i+1, objs[i]); } row = ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } return row; } }