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.ResultSetMetaData; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import com.bjsxt.wuye.util.DBUtil; import com.bjsxt.wuye.util.GetNameUtil; import com.bjsxt.wuye.util.PageUtil; @SuppressWarnings("unchecked") public class BaseDao{ /** * 拼接oracle 分頁sql語句 * @param sql * @return */ public String getOraclePageSql(String sql){ StringBuffer sqlBuffer = new StringBuffer("select * from (select a_tab_01.*,rownum a_row_num_r from ("); sqlBuffer.append(sql); sqlBuffer.append(" ) a_tab_01 where rownum<=?) b_tab_02 where a_row_num_r>=?"); return sqlBuffer.toString(); } /** * 單表 等值查詢 分頁 * @param objVo * @param pageNumStr * @param pageSize * @return */ public PageUtil queryListByPage(Object objVo,String pageNumStr,String pageSize) throws ClassNotFoundException, SQLException, SecurityException, IllegalArgumentException, InstantiationException, IllegalAccessException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException{ List sqlAndParamList = getSqlAndParam(objVo, ""); if(sqlAndParamList != null&&sqlAndParamList.size()>0){ StringBuffer sql = (StringBuffer) sqlAndParamList.get(0); List paramList = (List) sqlAndParamList.get(1); return queryListByPage(sql.toString(),objVo.getClass(),pageNumStr,pageSize,paramList.toArray()); } return null; } /**分頁查詢 * @param sql * @param c * @param pageNumStr * @param pageSize * @param param * @return */ public PageUtil queryListByPage(String sql,Class c,String pageNumStr,String pageSize,Object...param) throws ClassNotFoundException, SQLException, SecurityException, IllegalArgumentException, InstantiationException, IllegalAccessException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException{ if(c!=null){ String totalSql = "select count(*) from "+sql.split("from")[1];//獲取統計記錄總數的sql語句 int totalCount = getTotalCount(totalSql,param); //建立 PageUtil對象 PageUtil pageUtil = new PageUtil(pageSize,pageNumStr,totalCount); //獲取鏈接 Connection conn = DBUtil.getConn(); //獲取Oracle 分頁的查詢語句 sql = getOraclePageSql(sql); //預處理sql語句 PreparedStatement ps = conn.prepareStatement(sql); //填坑 setPsValue(ps, param); //把分頁條件 從第幾條記錄到第幾條記錄數據補充到PreparedStatement對象 ps.setObject(param==null?1:param.length+1, pageUtil.getRowEnd()); ps.setObject(param==null?2:param.length+2, pageUtil.getRowStart()); //獲取結果集 ResultSet rs = ps.executeQuery(); //將結果集放入vo,再放入list容器 List resultList = addList(rs, c); //關閉對象 DBUtil.close(conn, ps, rs); pageUtil.setList(resultList); return pageUtil; }else{ System.out.println("反射對象不能爲null"); return null; } } /** * 查詢並返回對象結果集 * @param sql 輸入的sql語句 * @param c 相對應的類 * @param param 準備填坑的參數 * @return 返回查詢到的對象結果集List */ public List queryList(String sql,Class c,Object...param) throws ClassNotFoundException, SQLException, InstantiationException, IllegalAccessException, SecurityException, NoSuchFieldException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { if(c != null){ //第一步: 獲取鏈接 Connection conn = DBUtil.getConn(); //第二步: sql 語句 挖坑 預處理sql語句 PreparedStatement ps = conn.prepareStatement(sql); //第三步: 給sql語句填坑 setPsValue(ps,param); //第四步: 執行查詢 ResultSet rs = ps.executeQuery(); //根據輸入的sql語句和對應的填坑參數返回查詢到的對象List List resultList = addList(rs, c); DBUtil.close(conn, ps, rs); //關閉與數據庫的連接 return resultList; }else{ System.out.println("反射對象不能爲null"); return null; } } /** * 填坑 * @param ps 預處理對象 * @param param 準備填坑的參數 */ private void setPsValue(PreparedStatement ps,Object...param) throws SQLException{ if(param !=null&¶m.length>0){ for(int i = 0;i<param.length;i++){ ps.setObject(i+1,param[i]); } } } /** * 查詢並返回對象結果集 * @param rs 查詢到的結果集 * @param c 結果集要賦值給的相關類 * @return 返回查詢到的對象List */ public List addList(ResultSet rs,Class c) throws SQLException, InstantiationException, IllegalAccessException, SecurityException, NoSuchFieldException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException{ List resultList = new ArrayList(); //遍歷rs中的結果集 while(rs.next()){ //把rs結果集賦給對應的類對象,而後獲取相對應的類對象 Object obj = setObjectFieldValue(rs,c); resultList.add(obj); } return resultList; } /** * 給vo對象屬性賦值 * @param rs 查詢到的結果集 * @param c 結果集要插入的對應類 * @return 獲取對應的類對象 */ private Object setObjectFieldValue(ResultSet rs,Class c) throws SQLException, SecurityException, NoSuchFieldException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException{ ResultSetMetaData rsmd = rs.getMetaData(); //獲取rs中的元數據 int colCount = rsmd.getColumnCount(); //獲取rs中有多少列 Object obj = c.newInstance(); //建立vo對象 for(int i = 1;i<=colCount;i++){ String colName = rsmd.getColumnName(i); //獲取sql語句中字段名 if(!colName.toLowerCase().equals("a_row_num_r")){ String fieldName = GetNameUtil.getFieldNameByColName(colName); //根據sql語句中字段名獲取屬性名 String setter = GetNameUtil.getSetter(fieldName); //經過屬性名獲取設定器名 Field field = c.getDeclaredField(fieldName); //獲取VO類中的屬性名 //獲取設定器對應的映射方法 Method m = c.getDeclaredMethod(setter, field.getType()); Object value = rs.getObject(i); //獲取rs中查詢到和屬性名對應的值 //調用設定器 invokeSetter(value,field,m,obj); } } return obj; } /** * 不一樣類型下調用設定器 * @param value 屬性名對應的值 * @param field 屬性名 * @param m 和屬性嗎對應的方法 * @param obj 和屬性名對應的類對象 */ private void invokeSetter(Object value,Field field,Method m,Object obj) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException{ if(value !=null){ if(value.getClass()==BigDecimal.class){//判斷 字段結果類型是不是BigDecimal BigDecimal bd = (BigDecimal)value; //強制類型轉換 if(field.getType()==Integer.class||field.getType()==int.class){//屬性類型是Integer m.invoke(obj, bd.intValue()); }else if(field.getType()==Double.class||field.getType()==double.class){ m.invoke(obj, bd.doubleValue()); }else if(field.getType()==Float.class||field.getType()==float.class){ m.invoke(obj, bd.floatValue()); }else if(field.getType()==Byte.class||field.getType()==byte.class){ m.invoke(obj, bd.byteValue()); }else if(field.getType()==long.class||field.getType()==Long.class){ m.invoke(obj, bd.longValue()); }else if(field.getType()==Short.class||field.getType()==short.class){ m.invoke(obj, bd.shortValue()); } }else{ m.invoke(obj,value); } } } /** * 根據條件進行單表查詢 * @param objVo 類對象 * @return 獲得查詢到的對象結果集 */ public List queryList(Object objVo) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, ClassNotFoundException, SQLException, InstantiationException, NoSuchFieldException{ //獲取sql語句和參數聚合集 List sqlAndParamList = getSqlAndParam(objVo,""); if(sqlAndParamList != null&&sqlAndParamList.size()>0){ String sql = sqlAndParamList.get(0).toString(); List paramList = (List) sqlAndParamList.get(1); //調用 查詢結果集的方法 return queryList(sql,objVo.getClass(),paramList.toArray()); } return null; } /** * 獲取屬性值 * @param field 屬性名 * @param objVo 屬性名對應類對象 * @return 獲得獲取的屬性值 */ private Object getFieldValue(Field field,Object objVo) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{ String getter = GetNameUtil.getGetter(field); //獲取取值器名 Method m = objVo.getClass().getDeclaredMethod(getter); //獲取取值器 Object value = m.invoke(objVo); return value; } /** * 獲取sql語句和參數聚合集 * @param objVo sql語句對應的類對象 * @return 獲得sql語句和參數聚合集 */ private List getSqlAndParam(Object objVo,String remark) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{ List resultList = new ArrayList(); List paramList = new ArrayList(); Class c = objVo.getClass(); //根據對象名獲取類名 String tabName = GetNameUtil.getTabOrColName(c.getSimpleName()); //根據類名獲取代表 String sqlPre = remark.equals("totalCount")?"select count(*) from ":"select * from "; StringBuffer sql = new StringBuffer(sqlPre+" "+tabName+" t where 1=1"); //獲取 參數對象屬性名數組 Field[] fieldArray = c.getDeclaredFields(); //遍歷屬性名數組獲取每一個屬性值 for(int i = 0;i<fieldArray.length;i++){ Object value = getFieldValue(fieldArray[i],objVo); //獲取屬性值 if(value!=null){ if(value.getClass()!=String.class){ sql.append(" and t."+GetNameUtil.getTabOrColName(fieldArray[i].getName())+"=?"); //獲取列明 paramList.add(value); }else{ if(!((String)value).trim().equals("")){ sql.append(" and t."+GetNameUtil.getTabOrColName(fieldArray[i].getName())+"=?"); //獲取列明 paramList.add(value); //把參數置入參數聚合集 } } } } resultList.add(sql); //獲得sql語句 resultList.add(paramList); //將參數聚合集放入結果聚合集中 return resultList; } /** * 獲取記錄總數 * @param sql 輸入的sql語句 * @param param 參數集 * @return 獲得記錄總數 */ private int getTotalCount(String sql,Object...param) throws ClassNotFoundException, SQLException{ //獲取鏈接 Connection conn = DBUtil.getConn(); //預處理sql語句 PreparedStatement ps = conn.prepareStatement(sql); //填坑 setPsValue(ps, param); //獲取rs結果集 ResultSet rs = ps.executeQuery(); //獲取記錄總數 int count = rs.next()?rs.getInt(1):0; DBUtil.close(conn, ps, rs); return count; } /** * 獲取記錄總數 * @param objVo 類對象 * @return 獲得查詢記錄數 */ public int getTotalCount(Object objVo) throws SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, ClassNotFoundException, SQLException{ List sqlAndParamList = getSqlAndParam(objVo,"totalCount"); //獲取sql語句和參數聚合集 if(sqlAndParamList != null&&sqlAndParamList.size()>0){ String sql = sqlAndParamList.get(0).toString(); List paramList = (List) sqlAndParamList.get(1); //調用 查詢結果集的方法 return getTotalCount(sql,paramList.toArray()); } return 0; } /** * 根據Id獲取單條記錄 * @param objVo 對象 * @return 獲得查詢到的對象 */ public Object queryObjectById(Object objVo) throws SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, ClassNotFoundException, SQLException, InstantiationException, NoSuchFieldException{ List list = queryList(objVo); //查詢到對應的對象結果集 if(list!=null&&list.size()>0){ return list.get(0); } return null; } /** * 向數據庫中插入數據 * @param objVo 對應 插入數據的類對象 * @param preKeyField sql語句中的對應相關表的主鍵 */ public void addVo(Object objVo,String preKeyField) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, ClassNotFoundException, SQLException{ //建立裝參數的集合 List paramList = new ArrayList(); //獲取反射對象 Class c = objVo.getClass(); String tabName = GetNameUtil.getTabOrColName(c.getSimpleName()); //獲取表名 StringBuffer sql = new StringBuffer("insert into "+tabName+" values("); //獲取類對象中的屬性名數組 Field[] fieldArray = c.getDeclaredFields(); //遍歷屬性名 for(int i = 0;i<fieldArray.length;i++){ String fieldName = fieldArray[i].getName(); if(!fieldName.equals(preKeyField)){ sql.append("?,"); Object value = getFieldValue(fieldArray[i], objVo); //獲取屬性值 paramList.add(value); //把屬性值裝入參數聚合集 } else{ sql.append("seq_"+tabName+".nextval,"); //獲取sql語句中的遞增值 } } sql.deleteCharAt(sql.length()-1); //去掉sql語句中最後一個逗號 sql.append(")"); //添加數據 modifyVo(sql.toString(),paramList.toArray()); } /** * 更新數據庫相關記錄 * @param objVo 要修改的vo對象 * @param preKeyField 必寫 主鍵對應的屬性名 */ public void updateVo(Object objVo,String... preKeyFields) throws SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, NoSuchFieldException, ClassNotFoundException, SQLException{ List paramList = new ArrayList(); //建立裝參數的集合 Class c = objVo.getClass(); //獲取反射對象 String tabName = GetNameUtil.getTabOrColName(c.getSimpleName()); //獲取表名 //拼接sql StringBuffer sql = new StringBuffer("update "+tabName+" t set "); Field[] fieldArray = c.getDeclaredFields(); //獲取屬性名 //遍歷屬性名數組 for(int i = 0;i<fieldArray.length;i++){ String fieldName = fieldArray[i].getName(); int j =0 ; for (j = 0; j < preKeyFields.length; j++) { if(fieldName.equals(preKeyFields[j])){ break; } } Object value = getFieldValue(fieldArray[i], objVo); //獲取屬性值 if(j>=preKeyFields.length && null != value && !"".equals(value)){ sql.append("t."+GetNameUtil.getTabOrColName(fieldName)+"=? ,"); paramList.add(value); //將獲得的屬性值裝入參數聚合集 } } sql.deleteCharAt(sql.length()-1); sql.append(" where t."+GetNameUtil.getTabOrColName(preKeyFields[0])+"=? "); for(int i=1; i<preKeyFields.length;i++){ sql.append(" and "+GetNameUtil.getTabOrColName(preKeyFields[i])+"=? "); } System.out.println(sql); //根據傳進來的主鍵名字 獲取主鍵對應的屬性名 for(String preKeyField:preKeyFields){ Field preKeyFieldObj = c.getDeclaredField(preKeyField); //獲取主鍵對應的屬性值 Object keyValue = getFieldValue(preKeyFieldObj, objVo); //將主鍵的值裝入參數聚合 paramList.add(keyValue); //修改信息 } modifyVo(sql.toString(),paramList.toArray()); } /** * 刪除數據庫單條記錄 * @param objVo 裝有主鍵參數值的對象 * @param preKeyField 主鍵對應的名字 */ public void deleteVo(Object objVo,String preKeyField) throws SecurityException, NoSuchFieldException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, ClassNotFoundException, SQLException{ //獲取反射對象 Class c = objVo.getClass(); String tabName = GetNameUtil.getTabOrColName(c.getSimpleName());//獲取表名 //拼接sql StringBuffer sql = new StringBuffer("delete from "+tabName+" t where t. "+GetNameUtil.getTabOrColName(preKeyField)+"=?"); //根據傳進來的主鍵名字 獲取主鍵對應的對像中的屬性名 Field preKeyFieldObj = c.getDeclaredField(preKeyField); //獲取主鍵對應的屬性值 Object keyValue = getFieldValue(preKeyFieldObj, objVo); //刪除單條記錄 modifyVo(sql.toString(),keyValue); } /** * 增刪改公用的方法 * @param sql 輸入的sql語句 * @param param 參數聚合集 */ private void modifyVo(String sql,Object...param) throws ClassNotFoundException, SQLException{ //獲取鏈接 Connection conn = DBUtil.getConn(); //預處理sql語句 PreparedStatement ps = conn.prepareStatement(sql); //填坑 setPsValue(ps, param); //執行 ps.executeUpdate(); //關閉 DBUtil.close(conn, ps, null); } }