反射写的BaseDAO
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; public final class BaseDAO{ /** * ------------- Oracle --------------- * DB_DRIVER ="oracle.jdbc.driver.OracleDriver"; * DB_URL ="jdbc:oracle:thin:@localhost:1521:admin"; * DB_USERNAME ="root"; * DB_PASSWORD ="root"; * ------------------------------------ */ /** * ------------- Sql Server --------------- * DB_DRIVER ="com.microsoft.sqlserver.jdbc.SQLServerDriver"; * DB_URL ="jdbc:sqlserver://localhost:1433;DatabaseName=bookinfo"; * DB_USERNAME ="root"; * DB_PASSWORD ="root"; * ---------------------------------------- */ private static final String DB_DRIVER ="com.mysql.jdbc.Driver"; private static final String DB_URL ="jdbc:mysql://localhost:3306/student"; private static final String DB_USERNAME ="root"; private static final String DB_PASSWORD ="root"; private static Connection getConnection() throws SQLException{ try { Class.forName(DB_DRIVER); return DriverManager.getConnection(DB_URL, DB_USERNAME, DB_PASSWORD); } catch (ClassNotFoundException e) { e.printStackTrace(); throw new RuntimeException("无法找到对应的数据库驱动类"); } } //增删改 public static void executeUpdate(String sql,Object[] args){ Connection con=null; PreparedStatement ps=null; System.out.println("准备执行:"+sql); try { con=getConnection(); ps= con.prepareStatement(sql); if(args!=null&&args.length>0){ for(int i=0;i<args.length;i++){ ps.setObject(i+1,args[i]); } } ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException("SQL语句执行失败:"+sql); }finally{ closeAll(con,ps,null); } } //查询 public static <T> List<T> executeQuery(Class<T> entityClass,String sql,Object[] args){ Connection con=null; PreparedStatement ps=null; ResultSet rs=null; System.out.println("准备执行:"+sql); try { con=getConnection(); ps= con.prepareStatement(sql); if(args!=null&&args.length>0){ for(int i=0;i<args.length;i++){ ps.setObject(i+1,args[i]); } } rs=ps.executeQuery(); List<T> list=new ArrayList<T>(); while(rs.next()){ T obj=fillDataFromResultSetToEntity(entityClass,rs); list.add(obj); } return list; } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException("SQL语句执行失败:"+sql); }finally{ closeAll(con,ps,rs); } } private static<T> T fillDataFromResultSetToEntity(Class<T> entityClass, ResultSet rs)throws SQLException { try { //实例化对应实体类 T entity = entityClass.newInstance(); //获得该实体类的所有set方法 Method[] methods=getAllSetMethods(entityClass); for(Method m:methods){ try{ //通过set方法名推算出属性名 String fieldName=m.getName().substring(3,4).toLowerCase()+m.getName().substring(4); //获得要调用的ResultSet对象的方法名 String rsMethodName = getResultSetMethod(m.getParameterTypes()[0]); //获得要调用的ResultSet对象的方法对象 Method rsMethod=rs.getClass().getMethod(rsMethodName,String.class); //调用rs.getXXX方法获得对应列的数据 Object fieldValue=rsMethod.invoke(rs,fieldName); //调用实体对象的set方法设值 m.invoke(entity,fieldValue); }catch (SecurityException e) { System.out.println("[警告]:"+entityClass.getName()+"."+m.getName()+"无法访问,跳过.."); continue; } catch (IllegalArgumentException e) { System.out.println("[警告]:"+entityClass.getName()+"."+m.getName()+"("+m.getParameterTypes()[0].getName()+")参数错误"); continue; } catch (NoSuchMethodException e) { System.out.println("[警告]:找不到方法"+entityClass.getName()+"."+m.getName()+"("+m.getParameterTypes()[0].getName()+")"); continue; } catch (InvocationTargetException e) { System.out.println("[警告]:调用"+entityClass.getName()+"."+m.getName()+"("+m.getParameterTypes()[0].getName()+")方法产生内部异常"); continue; } } return entity; } catch (InstantiationException e) { e.printStackTrace(); throw new RuntimeException("无法实例化" + entityClass.getName()); } catch (IllegalAccessException e) { e.printStackTrace(); throw new RuntimeException("没有或无法访问["+entityClass.getName()+"]的无参构造函数"); } } private static Method[] getAllSetMethods(Class<?> entityClass){ Method[] methods=entityClass.getMethods(); List<Method> list=new ArrayList<Method>(); for(Method m:methods){ if(m.getName().indexOf("set")==0){ list.add(m); } } return list.toArray(new Method[list.size()]); } private static String getResultSetMethod(Class<?> fieldType) { String rsMethodName = null; if (String.class.equals(fieldType)) { rsMethodName = "getString"; } if (Long.class.equals(fieldType) || "long".equals(fieldType.getName())) { rsMethodName = "getLong"; } if (Date.class.equals(fieldType)) { rsMethodName = "getDate"; } if (Integer.class.equals(fieldType) || "int".equals(fieldType.getName())) { rsMethodName = "getInt"; } if (Double.class.equals(fieldType) || "double".equals(fieldType.getName())) { rsMethodName = "getDouble"; } if (Float.class.equals(fieldType) || "float".equals(fieldType.getName())) { rsMethodName = "getFloat"; } if (rsMethodName == null) { throw new RuntimeException("无法识别的属性类型:" + fieldType.getName() + "目前支持的属性类型有[String,Integer,Long,Double,Float,Date]"); } return rsMethodName; } private static void closeAll(Connection con, PreparedStatement ps,ResultSet rs) { if(rs!=null){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException("关闭数据集错误"); } } if(ps!=null){ try { ps.close(); } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException("关闭数据访问对象错误"); } } if(con!=null){ try { con.close(); } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException("关闭数据库连接错误"); } } } }